Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,14 @@ int main(int argc, char *argv[]) {
bool show_ground_track = false; // ground projection off by default
bool classic_colors = false; // K key: toggle classic (red/blue) vs modern (yellow/purple)
bool show_edge_indicators = true; // Ctrl+L: screen edge drone indicators
int corr_mode = 0; // Shift+T: 0=off, 1=ribbon, 2=line
int corr_mode = 0; // Shift+T: 0=off, 1=line, 2=curtain
// Per-vehicle trail_count snapshot at the moment Shift+T entered
// curtain mode (corr_mode == 2). vehicle_draw_correlation_curtain
// clips to samples added since this baseline, so toggling Curtain
// mid-flight always starts the ruled surface from "now" instead of
// dragging the whole accumulated trail into it. Trails / ribbons
// are unaffected — they keep using the full trail buffer.
int curtain_baseline[MAX_VEHICLES] = {0};
bool show_corr_labels = true; // Ctrl+L: distance labels in ortho correlation
bool show_axes = false; // Z: axis orientation gizmo
bool insufficient_data[MAX_VEHICLES]; // drones with no position data
Expand Down Expand Up @@ -818,10 +825,20 @@ int main(int argc, char *argv[]) {
}
}

// Shift+T: cycle correlation overlay (off → ribbonline → off)
// Shift+T: cycle correlation overlay (off → linecurtain → off)
if (IsKeyPressed(KEY_T) && (IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT))
&& is_replay && num_replay_files > 1) {
corr_mode = (corr_mode + 1) % 3;
// On transition INTO curtain mode, snapshot every active
// vehicle's current trail_count. The curtain draw clips to
// samples added past this baseline so the surface starts
// empty and grows from this moment forward instead of
// dragging in pre-toggle trail data.
if (corr_mode == 2) {
for (int i = 0; i < vehicle_count; i++) {
curtain_baseline[i] = vehicles[i].trail_count;
}
}
const char *names[] = { "Correlation Off", "Correlation Line", "Correlation Curtain" };
hud_toast(&hud, names[corr_mode], 2.0f);
}
Expand Down Expand Up @@ -1187,7 +1204,8 @@ int main(int argc, char *argv[]) {
ortho_panel_update(&ortho, vehicles[selected].position);
ortho_panel_render(&ortho, vehicles, vehicle_count,
selected, scene.theme,
corr_mode, hud.pinned, hud.pinned_count);
corr_mode, hud.pinned, hud.pinned_count,
curtain_baseline);
}

// Render
Expand Down Expand Up @@ -1282,6 +1300,7 @@ int main(int argc, char *argv[]) {
} else if (corr_mode == 2) {
vehicle_draw_correlation_curtain(
&vehicles[selected], &vehicles[pidx],
curtain_baseline[selected], curtain_baseline[pidx],
scene.theme, scene.camera.position);
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/ortho_panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ void ortho_panel_update(ortho_panel_t *op, Vector3 pos) {

void ortho_panel_render(ortho_panel_t *op, const vehicle_t *vehicles,
int vehicle_count, int selected, const theme_t *theme,
int corr_mode, const int *pinned, int pinned_count)
int corr_mode, const int *pinned, int pinned_count,
const int *curtain_baseline)
{
Color bg_col = theme->sky;

Expand All @@ -273,6 +274,8 @@ void ortho_panel_render(ortho_panel_t *op, const vehicle_t *vehicles,
&& pidx != selected) {
vehicle_draw_correlation_curtain(
&vehicles[selected], &vehicles[pidx],
curtain_baseline ? curtain_baseline[selected] : 0,
curtain_baseline ? curtain_baseline[pidx] : 0,
theme, op->cameras[v].position);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/ortho_panel.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ void ortho_panel_init(ortho_panel_t *op);
void ortho_panel_update(ortho_panel_t *op, Vector3 vehicle_pos);
void ortho_panel_render(ortho_panel_t *op, const vehicle_t *vehicles,
int vehicle_count, int selected, const theme_t *theme,
int corr_mode, const int *pinned, int pinned_count);
int corr_mode, const int *pinned, int pinned_count,
const int *curtain_baseline);
void ortho_panel_draw(const ortho_panel_t *op, int screen_h, int hud_bar_h,
const theme_t *theme, Font font,
const vehicle_t *vehicles, int vehicle_count,
Expand Down
37 changes: 29 additions & 8 deletions src/vehicle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1267,15 +1267,36 @@ void vehicle_set_ghost_alpha(vehicle_t *v, float alpha) {

void vehicle_draw_correlation_curtain(
const vehicle_t *va, const vehicle_t *vb,
int baseline_a, int baseline_b,
const theme_t *theme, Vector3 cam_pos) {
(void)theme; // colors come from vehicle->color, theme kept for API consistency
if (va->trail_count < 2 || vb->trail_count < 2) return;

int n = va->trail_count < vb->trail_count ? va->trail_count : vb->trail_count;
// Effective post-baseline sample counts, capped at the ring capacity.
// Once the live trail has rolled past the baseline by more than the
// ring length, the baseline is lost and we fall back to drawing the
// whole ring (still bounded, still doesn't drag in pre-toggle data
// that was never there).
int new_a = va->trail_count - baseline_a;
int new_b = vb->trail_count - baseline_b;
if (new_a < 2 || new_b < 2) return;
if (new_a > va->trail_capacity) new_a = va->trail_capacity;
if (new_b > vb->trail_capacity) new_b = vb->trail_capacity;

int n = new_a < new_b ? new_a : new_b;
if (n < 2) return;

int start_a = (va->trail_count < va->trail_capacity) ? 0 : va->trail_head;
int start_b = (vb->trail_count < vb->trail_capacity) ? 0 : vb->trail_head;
// Starting index of the post-baseline window in each ring.
// Pre-wrap (trail_count <= capacity): samples live at indices
// [0, trail_count); the window starts at trail_count - new_*.
// Post-wrap: newest sample is at (head + capacity - 1) % capacity;
// window of the last new_* samples starts new_* positions back from
// there, i.e. (head + capacity - new_*) % capacity.
int start_a = (va->trail_count <= va->trail_capacity)
? (va->trail_count - new_a)
: (va->trail_head + va->trail_capacity - new_a) % va->trail_capacity;
int start_b = (vb->trail_count <= vb->trail_capacity)
? (vb->trail_count - new_b)
: (vb->trail_head + vb->trail_capacity - new_b) % vb->trail_capacity;

Color ca = va->color;
Color cb = vb->color;
Expand All @@ -1284,10 +1305,10 @@ void vehicle_draw_correlation_curtain(
rlBegin(RL_TRIANGLES);
for (int i = 1; i < n; i++) {
// Map index through fractional position for trail length alignment
int idx_a0 = (start_a + (int)((float)(i - 1) / n * va->trail_count)) % va->trail_capacity;
int idx_a1 = (start_a + (int)((float)i / n * va->trail_count)) % va->trail_capacity;
int idx_b0 = (start_b + (int)((float)(i - 1) / n * vb->trail_count)) % vb->trail_capacity;
int idx_b1 = (start_b + (int)((float)i / n * vb->trail_count)) % vb->trail_capacity;
int idx_a0 = (start_a + (int)((float)(i - 1) / n * new_a)) % va->trail_capacity;
int idx_a1 = (start_a + (int)((float)i / n * new_a)) % va->trail_capacity;
int idx_b0 = (start_b + (int)((float)(i - 1) / n * new_b)) % vb->trail_capacity;
int idx_b1 = (start_b + (int)((float)i / n * new_b)) % vb->trail_capacity;

Vector3 pa0 = va->trail[idx_a0];
Vector3 pa1 = va->trail[idx_a1];
Expand Down
6 changes: 6 additions & 0 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,14 @@ Color vehicle_marker_color(float roll, float pitch, float vert, float speed,
Color drone_color);

// Draw correlation curtain between two vehicles (cross-vehicle overlay).
// baseline_a/baseline_b: trail_count snapshots taken when curtain mode
// was entered. Only samples added since then participate in the
// curtain, so toggling Shift+T to Curtain mid-flight starts the ruled
// surface from "now" instead of dragging the entire accumulated trail
// through it. Pass 0/0 to draw the full trails (legacy behavior).
void vehicle_draw_correlation_curtain(
const vehicle_t *va, const vehicle_t *vb,
int baseline_a, int baseline_b,
const theme_t *theme, Vector3 cam_pos);

// Draw thick correlation line between two vehicles at current positions.
Expand Down
Loading