Skip to content
Closed
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
50 changes: 46 additions & 4 deletions src/vehicle.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <stdlib.h>

#define EARTH_RADIUS 6371000.0
#define TRAIL_MAX 3600
#define TRAIL_MAX 1800
#define TRAIL_INTERVAL 0.016f
#define TRAIL_DIST_INTERVAL 0.01f // meters between ribbon samples

Expand Down Expand Up @@ -208,6 +208,27 @@ static Color heat_to_color(float heat, unsigned char alpha, view_mode_t mode) {
float s = (heat - 0.83f) / 0.17f;
cr = 255; cg = 250 + 5 * s; cb = 60 + 195 * s;
}
} else if (mode == VIEW_SNOW) {
// Snow: deep navy → royal blue → teal → green → yellow → red
if (heat < 0.16f) {
float s = heat / 0.16f;
cr = 10 + 10 * s; cg = 20 + 20 * s; cb = 100 + 40 * s;
} else if (heat < 0.33f) {
float s = (heat - 0.16f) / 0.17f;
cr = 20 - 10 * s; cg = 40 + 80 * s; cb = 140 + 40 * s;
} else if (heat < 0.5f) {
float s = (heat - 0.33f) / 0.17f;
cr = 10 - 10 * s; cg = 120 + 40 * s; cb = 180 - 100 * s;
} else if (heat < 0.66f) {
float s = (heat - 0.5f) / 0.16f;
cr = 0 + 60 * s; cg = 160 + 40 * s; cb = 80 - 80 * s;
} else if (heat < 0.83f) {
float s = (heat - 0.66f) / 0.17f;
cr = 60 + 180 * s; cg = 200 + 20 * s; cb = 0;
} else {
float s = (heat - 0.83f) / 0.17f;
cr = 240; cg = 220 - 180 * s; cb = 0;
}
} else {
// Grid (default): purple → magenta → red → orange → yellow → white
if (heat < 0.16f) {
Expand Down Expand Up @@ -351,18 +372,39 @@ void vehicle_update(vehicle_t *v, const hil_state_t *state, const home_position_
v->airspeed = state->ind_airspeed * 0.01f;
v->altitude_rel = (float)(alt - v->alt0);

// Sample trail by time OR distance (whichever triggers first)
// Adaptive trail sampling: record a point when direction changes (tight turns
// get dense coverage) or after a max distance on straight runs (so they don't
// go bare). Minimum distance gate prevents duplicate points when hovering.
float dist_since = 0.0f;
Vector3 cur_dir = {0};
if (v->trail_count > 0) {
int last = (v->trail_head - 1 + v->trail_capacity) % v->trail_capacity;
float ddx = v->position.x - v->trail[last].x;
float ddy = v->position.y - v->trail[last].y;
float ddz = v->position.z - v->trail[last].z;
dist_since = sqrtf(ddx*ddx + ddy*ddy + ddz*ddz);
if (dist_since > 0.001f) {
cur_dir = (Vector3){ ddx/dist_since, ddy/dist_since, ddz/dist_since };
}
}

// Direction change: dot product < threshold means significant turn
float dir_dot = 1.0f;
if (v->trail_count > 1 && dist_since > 0.001f) {
dir_dot = cur_dir.x * v->trail_last_dir.x +
cur_dir.y * v->trail_last_dir.y +
cur_dir.z * v->trail_last_dir.z;
}

// Sample triggers: dense on turns, sparse on straights
v->trail_timer += GetFrameTime();
if (v->trail_timer >= TRAIL_INTERVAL || dist_since >= TRAIL_DIST_INTERVAL) {
bool dir_trigger = (dir_dot < 0.995f) && (dist_since >= TRAIL_DIST_INTERVAL);
bool dist_trigger = (dist_since >= 0.5f);
bool time_trigger = (v->trail_timer >= TRAIL_INTERVAL * 4.0f);

if (dir_trigger || dist_trigger || time_trigger) {
v->trail_timer = 0.0f;
if (dist_since > 0.001f) v->trail_last_dir = cur_dir;
v->trail[v->trail_head] = v->position;
v->trail_roll[v->trail_head] = v->roll_deg;
v->trail_pitch[v->trail_head] = v->pitch_deg;
Expand Down Expand Up @@ -616,7 +658,7 @@ void vehicle_draw(vehicle_t *v, view_mode_t view_mode, bool selected,
rlEnd();
} else {
// ── Speed ribbon trail (mode 2) ──
// Batched triangle ribbon: single rlBegin/rlEnd instead of per-quad DrawTriangle3D.
// Batched triangle ribbon with adaptive sampling (dense on turns, sparse on straights).
// Perpendicular blending (70% previous + 30% current) prevents twisting on tight turns.
float max_speed = v->trail_speed_max > 1.0f ? v->trail_speed_max : 1.0f;
float max_half_w = v->model_scale * 0.25f;
Expand Down
1 change: 1 addition & 0 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ typedef struct {
int trail_head;
int trail_capacity;
float trail_timer;
Vector3 trail_last_dir; // direction of last recorded segment (for adaptive sampling)
Shader lighting_shader; // shared lighting shader (id=0 if none)
int loc_matNormal; // shader uniform for normal matrix
} vehicle_t;
Expand Down