From a342af737e3a68e8b493e9796b6c62ad18cec1ed Mon Sep 17 00:00:00 2001 From: Dominic Szablewski Date: Mon, 13 May 2024 10:54:18 +0200 Subject: [PATCH] Fix SHIP_FLYING attribute applied too generously; close #96 --- src/wipeout/camera.c | 4 ++-- src/wipeout/ship.c | 9 ++++++++- src/wipeout/track.c | 9 ++++++--- src/wipeout/track.h | 2 +- src/wipeout/weapon.c | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/wipeout/camera.c b/src/wipeout/camera.c index 8b15ad5..382f151 100755 --- a/src/wipeout/camera.c +++ b/src/wipeout/camera.c @@ -42,7 +42,7 @@ void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) { void camera_update_race_external(camera_t *camera, ship_t *ship, droid_t *droid) { vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 1024)); pos.y -= 200; - camera->section = track_nearest_section(pos, camera->section, NULL); + camera->section = track_nearest_section(pos, vec3(1,1,1), camera->section, NULL); section_t *next = camera->section->next; vec3_t target = vec3_project_to_ray(pos, next->center, camera->section->center); @@ -78,7 +78,7 @@ void camera_update_race_intro(camera_t *camera, ship_t *ship, droid_t *droid) { camera->has_initial_section = true; } else { - camera->section = track_nearest_section(pos, camera->section, NULL); + camera->section = track_nearest_section(pos, vec3(1,1,1), camera->section, NULL); } camera->position = pos; diff --git a/src/wipeout/ship.c b/src/wipeout/ship.c index f8448d0..8d6749a 100644 --- a/src/wipeout/ship.c +++ b/src/wipeout/ship.c @@ -467,8 +467,15 @@ void ship_update(ship_t *self) { self->dir_up.z = (sy * sz) + (cy * sx * cz); self->prev_section = self->section; + + // To find the nearest section to the ship, the original source de-emphasizes + // the .y component when calculating the distance to each section by a + // >> 2 shift. I.e. it tries to find the section that is more closely to the + // horizontal x,z plane (directly underneath the ship), instead of finding + // the section with the "real" closest distance. Hence the bias of + // vec3(1, 0.25, 1) here. float distance; - self->section = track_nearest_section(self->position, self->section, &distance); + self->section = track_nearest_section(self->position, vec3(1, 0.25, 1), self->section, &distance); if (distance > 3700) { flags_add(self->flags, SHIP_FLYING); } diff --git a/src/wipeout/track.c b/src/wipeout/track.c index d1c6798..4065721 100755 --- a/src/wipeout/track.c +++ b/src/wipeout/track.c @@ -323,7 +323,7 @@ track_face_t *track_section_get_base_face(section_t *section) { return face; } -section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance) { +section_t *track_nearest_section(vec3_t pos, vec3_t bias, section_t *section, float *distance) { // Start search several sections before current section for (int i = 0; i < TRACK_SEARCH_LOOK_BACK; i++) { @@ -340,7 +340,10 @@ section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance junction = section->junction; } - float d = vec3_len(vec3_sub(pos, section->center)); + // Some callers of this function want to de-emphazise the .y component + // of the difference, hence the multiplication with the bias vector. + // For the real, exact difference bias should be vec3(1,1,1) + float d = vec3_len(vec3_mul(vec3_sub(pos, section->center), bias)); if (d < shortest_distance) { shortest_distance = d; nearest_section = section; @@ -352,7 +355,7 @@ section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance if (junction) { section = junction; for (int i = 0; i < TRACK_SEARCH_LOOK_AHEAD; i++) { - float d = vec3_len(vec3_sub(pos, section->center)); + float d = vec3_len(vec3_mul(vec3_sub(pos, section->center), bias)); if (d < shortest_distance) { shortest_distance = d; nearest_section = section; diff --git a/src/wipeout/track.h b/src/wipeout/track.h index be9c8f4..69f2a12 100755 --- a/src/wipeout/track.h +++ b/src/wipeout/track.h @@ -86,7 +86,7 @@ void track_load_sections(char *file); bool track_collect_pickups(track_face_t *face); void track_face_set_color(track_face_t *face, rgba_t color); track_face_t *track_section_get_base_face(section_t *section); -section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance); +section_t *track_nearest_section(vec3_t pos, vec3_t bias, section_t *section, float *distance); struct camera_t; void track_draw(struct camera_t *camera); diff --git a/src/wipeout/weapon.c b/src/wipeout/weapon.c index 2095f43..63415fa 100755 --- a/src/wipeout/weapon.c +++ b/src/wipeout/weapon.c @@ -195,7 +195,7 @@ void weapons_update(void) { } // Track collision - weapon->section = track_nearest_section(weapon->position, weapon->section, NULL); + weapon->section = track_nearest_section(weapon->position, vec3(1,1,1), weapon->section, NULL); if (weapon_collides_with_track(weapon)) { for (int p = 0; p < 32; p++) { vec3_t velocity = vec3(rand_float(-512, 512), rand_float(-512, 512), rand_float(-512, 512));