Fix SHIP_FLYING attribute applied too generously; close #96

This commit is contained in:
Dominic Szablewski 2024-05-13 10:54:18 +02:00
parent 0dae020303
commit a342af737e
5 changed files with 18 additions and 8 deletions

View file

@ -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) { 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)); vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 1024));
pos.y -= 200; 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; section_t *next = camera->section->next;
vec3_t target = vec3_project_to_ray(pos, next->center, camera->section->center); 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; camera->has_initial_section = true;
} }
else { 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; camera->position = pos;

View file

@ -467,8 +467,15 @@ void ship_update(ship_t *self) {
self->dir_up.z = (sy * sz) + (cy * sx * cz); self->dir_up.z = (sy * sz) + (cy * sx * cz);
self->prev_section = self->section; 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; 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) { if (distance > 3700) {
flags_add(self->flags, SHIP_FLYING); flags_add(self->flags, SHIP_FLYING);
} }

View file

@ -323,7 +323,7 @@ track_face_t *track_section_get_base_face(section_t *section) {
return face; 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 // Start search several sections before current section
for (int i = 0; i < TRACK_SEARCH_LOOK_BACK; i++) { 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; 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) { if (d < shortest_distance) {
shortest_distance = d; shortest_distance = d;
nearest_section = section; nearest_section = section;
@ -352,7 +355,7 @@ section_t *track_nearest_section(vec3_t pos, section_t *section, float *distance
if (junction) { if (junction) {
section = junction; section = junction;
for (int i = 0; i < TRACK_SEARCH_LOOK_AHEAD; i++) { 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) { if (d < shortest_distance) {
shortest_distance = d; shortest_distance = d;
nearest_section = section; nearest_section = section;

View file

@ -86,7 +86,7 @@ void track_load_sections(char *file);
bool track_collect_pickups(track_face_t *face); bool track_collect_pickups(track_face_t *face);
void track_face_set_color(track_face_t *face, rgba_t color); void track_face_set_color(track_face_t *face, rgba_t color);
track_face_t *track_section_get_base_face(section_t *section); 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; struct camera_t;
void track_draw(struct camera_t *camera); void track_draw(struct camera_t *camera);

View file

@ -195,7 +195,7 @@ void weapons_update(void) {
} }
// Track collision // 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)) { if (weapon_collides_with_track(weapon)) {
for (int p = 0; p < 32; p++) { for (int p = 0; p < 32; p++) {
vec3_t velocity = vec3(rand_float(-512, 512), rand_float(-512, 512), rand_float(-512, 512)); vec3_t velocity = vec3(rand_float(-512, 512), rand_float(-512, 512), rand_float(-512, 512));