From ecf1e635082188d3294e10abb255128204854127 Mon Sep 17 00:00:00 2001 From: Dominic Szablewski Date: Fri, 1 Sep 2023 19:04:27 +0200 Subject: [PATCH] Do some culling based on camera direction --- src/wipeout/camera.c | 9 ++++++++- src/wipeout/camera.h | 2 +- src/wipeout/object.c | 13 +++++++++++++ src/wipeout/object.h | 1 + src/wipeout/scene.c | 25 +++++++++++++++---------- src/wipeout/track.c | 27 +++++++++++++++++---------- 6 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/wipeout/camera.c b/src/wipeout/camera.c index eec80b7..8b4304b 100755 --- a/src/wipeout/camera.c +++ b/src/wipeout/camera.c @@ -21,10 +21,17 @@ void camera_init(camera_t *camera, section_t *section) { camera->velocity = vec3(0, 0, 0); camera->angle = vec3(0, 0, 0); camera->angular_velocity = vec3(0, 0, 0); - camera->mat = mat4_identity(); camera->has_initial_section = false; } +vec3_t camera_forward(camera_t *camera) { + float sx = sin(camera->angle.x); + float cx = cos(camera->angle.x); + float sy = sin(camera->angle.y); + float cy = cos(camera->angle.y); + return vec3(-(sy * cx), -sx, (cy * cx)); +} + void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) { camera->last_position = camera->position; (camera->update_func)(camera, ship, droid); diff --git a/src/wipeout/camera.h b/src/wipeout/camera.h index 9fad063..e846700 100755 --- a/src/wipeout/camera.h +++ b/src/wipeout/camera.h @@ -11,7 +11,6 @@ typedef struct camera_t { vec3_t angular_velocity; vec3_t last_position; vec3_t real_velocity; - mat4_t mat; section_t *section; bool has_initial_section; float update_timer; @@ -19,6 +18,7 @@ typedef struct camera_t { } camera_t; void camera_init(camera_t *camera, section_t *section); +vec3_t camera_forward(camera_t *camera); void camera_update(camera_t *camera, ship_t *ship, droid_t *droid); void camera_update_race_external(camera_t *, ship_t *camShip, droid_t *); void camera_update_race_internal(camera_t *, ship_t *camShip, droid_t *); diff --git a/src/wipeout/object.c b/src/wipeout/object.c index d89b985..4b004e2 100755 --- a/src/wipeout/object.c +++ b/src/wipeout/object.c @@ -68,14 +68,27 @@ Object *objects_load(char *name, texture_list_t tl) { p += 4; // skeleton sub p += 4; // skeleton next + object->radius = 0; object->vertices = mem_bump(object->vertices_len * sizeof(vec3_t)); for (int i = 0; i < object->vertices_len; i++) { object->vertices[i].x = get_i16(bytes, &p); object->vertices[i].y = get_i16(bytes, &p); object->vertices[i].z = get_i16(bytes, &p); p += 2; // padding + + if (abs(object->vertices[i].x) > object->radius) { + object->radius = abs(object->vertices[i].x); + } + if (abs(object->vertices[i].y) > object->radius) { + object->radius = abs(object->vertices[i].y); + } + if (abs(object->vertices[i].z) > object->radius) { + object->radius = abs(object->vertices[i].z); + } } + + object->normals = mem_bump(object->normals_len * sizeof(vec3_t)); for (int i = 0; i < object->normals_len; i++) { object->normals[i].x = get_i16(bytes, &p); diff --git a/src/wipeout/object.h b/src/wipeout/object.h index 1af9503..3e4912f 100755 --- a/src/wipeout/object.h +++ b/src/wipeout/object.h @@ -343,6 +343,7 @@ typedef struct Object { vec3_t origin; int32_t extent; // Flags for object characteristics int16_t flags; // Next object in list + float radius; struct Object *next; // Next object in list } Object; diff --git a/src/wipeout/scene.c b/src/wipeout/scene.c index f2e1c99..8ce5ced 100755 --- a/src/wipeout/scene.c +++ b/src/wipeout/scene.c @@ -123,21 +123,26 @@ void scene_draw(camera_t *camera) { object_draw(sky_object, &sky_object->mat); render_set_depth_write(true); - // Nearby objects - vec3_t cam_pos = camera->position; - Object *object = scene_objects; - float max_dist_sq = RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR; - while (object) { - vec3_t d = vec3_sub(cam_pos, object->origin); - float dist_sq = d.x * d.x + d.y * d.y + d.z * d.z; + // Objects - if (dist_sq < max_dist_sq) { + // Calculate the camera forward vector, so we can cull everything that's + // behind. Ideally we'd want to do a full frustum culling here. FIXME. + vec3_t cam_pos = camera->position; + vec3_t cam_dir = camera_forward(camera); + Object *object = scene_objects; + + while (object) { + vec3_t diff = vec3_sub(cam_pos, object->origin); + float cam_dot = vec3_dot(diff, cam_dir); + float dist_sq = vec3_dot(diff, diff); + if ( + cam_dot < object->radius && + dist_sq < (RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR) + ) { object_draw(object, &object->mat); } - object = object->next; } - } void scene_set_start_booms(int light_index) { diff --git a/src/wipeout/track.c b/src/wipeout/track.c index 9ea760d..21a235e 100755 --- a/src/wipeout/track.c +++ b/src/wipeout/track.c @@ -259,17 +259,24 @@ void track_draw_section(section_t *section) { } void track_draw(camera_t *camera) { - render_set_model_mat(&mat4_identity()); - - float max_dist_sq = RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR; - vec3_t cam_pos = camera->position; + render_set_model_mat(&mat4_identity()); - section_t *s = g.track.sections; - for(int32_t i = 0; i < g.track.section_count; ++i, ++s) - { - vec3_t d = vec3_sub(cam_pos, s->center); - float dist_sq = d.x * d.x + d.y * d.y + d.z * d.z; - if (dist_sq < max_dist_sq) { + // Calculate the camera forward vector, so we can cull everything that's + // behind. Ideally we'd want to do a full frustum culling here. FIXME. + vec3_t cam_pos = camera->position; + vec3_t cam_dir = camera_forward(camera); + + int drawn = 0; + int skipped = 0; + for(int32_t i = 0; i < g.track.section_count; i++) { + section_t *s = &g.track.sections[i]; + vec3_t diff = vec3_sub(cam_pos, s->center); + float cam_dot = vec3_dot(diff, cam_dir); + float dist_sq = vec3_dot(diff, diff); + if ( + cam_dot < 2048 && // FIXME: should use the bounding radius of the section + dist_sq < (RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR) + ) { track_draw_section(s); } }