Do some culling based on camera direction

This commit is contained in:
Dominic Szablewski 2023-09-01 19:04:27 +02:00
parent 9e90c4768f
commit ecf1e63508
6 changed files with 55 additions and 22 deletions

View file

@ -21,10 +21,17 @@ void camera_init(camera_t *camera, section_t *section) {
camera->velocity = vec3(0, 0, 0); camera->velocity = vec3(0, 0, 0);
camera->angle = vec3(0, 0, 0); camera->angle = vec3(0, 0, 0);
camera->angular_velocity = vec3(0, 0, 0); camera->angular_velocity = vec3(0, 0, 0);
camera->mat = mat4_identity();
camera->has_initial_section = false; 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) { void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->last_position = camera->position; camera->last_position = camera->position;
(camera->update_func)(camera, ship, droid); (camera->update_func)(camera, ship, droid);

View file

@ -11,7 +11,6 @@ typedef struct camera_t {
vec3_t angular_velocity; vec3_t angular_velocity;
vec3_t last_position; vec3_t last_position;
vec3_t real_velocity; vec3_t real_velocity;
mat4_t mat;
section_t *section; section_t *section;
bool has_initial_section; bool has_initial_section;
float update_timer; float update_timer;
@ -19,6 +18,7 @@ typedef struct camera_t {
} camera_t; } camera_t;
void camera_init(camera_t *camera, section_t *section); 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(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_external(camera_t *, ship_t *camShip, droid_t *);
void camera_update_race_internal(camera_t *, ship_t *camShip, droid_t *); void camera_update_race_internal(camera_t *, ship_t *camShip, droid_t *);

View file

@ -68,14 +68,27 @@ Object *objects_load(char *name, texture_list_t tl) {
p += 4; // skeleton sub p += 4; // skeleton sub
p += 4; // skeleton next p += 4; // skeleton next
object->radius = 0;
object->vertices = mem_bump(object->vertices_len * sizeof(vec3_t)); object->vertices = mem_bump(object->vertices_len * sizeof(vec3_t));
for (int i = 0; i < object->vertices_len; i++) { for (int i = 0; i < object->vertices_len; i++) {
object->vertices[i].x = get_i16(bytes, &p); object->vertices[i].x = get_i16(bytes, &p);
object->vertices[i].y = get_i16(bytes, &p); object->vertices[i].y = get_i16(bytes, &p);
object->vertices[i].z = get_i16(bytes, &p); object->vertices[i].z = get_i16(bytes, &p);
p += 2; // padding 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)); object->normals = mem_bump(object->normals_len * sizeof(vec3_t));
for (int i = 0; i < object->normals_len; i++) { for (int i = 0; i < object->normals_len; i++) {
object->normals[i].x = get_i16(bytes, &p); object->normals[i].x = get_i16(bytes, &p);

View file

@ -343,6 +343,7 @@ typedef struct Object {
vec3_t origin; vec3_t origin;
int32_t extent; // Flags for object characteristics int32_t extent; // Flags for object characteristics
int16_t flags; // Next object in list int16_t flags; // Next object in list
float radius;
struct Object *next; // Next object in list struct Object *next; // Next object in list
} Object; } Object;

View file

@ -123,21 +123,26 @@ void scene_draw(camera_t *camera) {
object_draw(sky_object, &sky_object->mat); object_draw(sky_object, &sky_object->mat);
render_set_depth_write(true); render_set_depth_write(true);
// Nearby objects // 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;
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_draw(object, &object->mat);
} }
object = object->next; object = object->next;
} }
} }
void scene_set_start_booms(int light_index) { void scene_set_start_booms(int light_index) {

View file

@ -259,17 +259,24 @@ void track_draw_section(section_t *section) {
} }
void track_draw(camera_t *camera) { void track_draw(camera_t *camera) {
render_set_model_mat(&mat4_identity()); render_set_model_mat(&mat4_identity());
float max_dist_sq = RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR;
vec3_t cam_pos = camera->position;
section_t *s = g.track.sections; // Calculate the camera forward vector, so we can cull everything that's
for(int32_t i = 0; i < g.track.section_count; ++i, ++s) // behind. Ideally we'd want to do a full frustum culling here. FIXME.
{ vec3_t cam_pos = camera->position;
vec3_t d = vec3_sub(cam_pos, s->center); vec3_t cam_dir = camera_forward(camera);
float dist_sq = d.x * d.x + d.y * d.y + d.z * d.z;
if (dist_sq < max_dist_sq) { 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); track_draw_section(s);
} }
} }