Fixed bug with frustum culling not working sometimes

dev
Shariq Shah 9 years ago
parent e95074a904
commit 6c2ec5a688
  1. 3
      orgfile.org
  2. 33
      src/bounding_volumes.c
  3. 3
      src/bounding_volumes.h
  4. 24
      src/camera.c
  5. 7
      src/entity.c

@ -146,7 +146,8 @@ x Font atlas proper cleanup
** TODO Textual/Binary format for data serialization and persistance ** TODO Textual/Binary format for data serialization and persistance
** TODO Better logging ** TODO Better logging
** TODO Hatching/Ink rendering style ** TODO Hatching/Ink rendering style
** TODO Fix frustum culling sometimes not working ** DONE Fix frustum culling sometimes not working
- State "DONE" from "TODO" [2017-03-25 Sat 19:10]
** DONE Compile and test on windows ** DONE Compile and test on windows
- State "DONE" from "TODO" [2017-03-14 Tue 00:32] - State "DONE" from "TODO" [2017-03-14 Tue 00:32]
** TODO Array based string type comptible with cstring(char*) ** TODO Array based string type comptible with cstring(char*)

@ -6,6 +6,13 @@
int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Transform* transform) int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Transform* transform)
{ {
vec3 min, max, size, center, half_ext, half_size; vec3 min, max, size, center, half_ext, half_size;
vec3_fill(&min, 0.f, 0.f, 0.f);
vec3_fill(&max, 0.f, 0.f, 0.f);
vec3_fill(&size, 0.f, 0.f, 0.f);
vec3_fill(&center, 0.f, 0.f, 0.f);
vec3_fill(&half_ext, 0.f, 0.f, 0.f);
vec3_fill(&half_size, 0.f, 0.f, 0.f);
vec3_add(&min, &box->min, &transform->position); vec3_add(&min, &box->min, &transform->position);
vec3_mul(&min, &min, &transform->scale); vec3_mul(&min, &min, &transform->scale);
vec3_add(&max, &box->max, &transform->position); vec3_add(&max, &box->max, &transform->position);
@ -17,15 +24,13 @@ int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Tra
vec3_scale(&half_size, &size, 0.5f); vec3_scale(&half_size, &size, 0.5f);
for(int i = 0; i < 6; i++) for(int i = 0; i < 6; i++)
{ {
vec3 normal = {frustum[i].x, frustum[i].y, frustum[i].z}; vec3 normal = {frustum[i].x, frustum[i].y, frustum[i].z};
float distance = frustum[i].w; float distance = frustum[i].w;
float d = vec3_dot(&normal, &center); float d = vec3_dot(&normal, &center);
vec3 abs_normal = {fabsf(normal.x), fabsf(normal.y), fabsf(normal.z)}; vec3 abs_normal = {fabsf(normal.x), fabsf(normal.y), fabsf(normal.z)};
float r = vec3_dot(&half_ext, &abs_normal); float r = vec3_dot(&half_ext, &abs_normal);
if(d + r < -distance) if(d + r < -distance)
{
return IT_OUTSIDE; return IT_OUTSIDE;
}
} }
return IT_INSIDE; return IT_INSIDE;
} }
@ -33,24 +38,26 @@ int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Tra
int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, struct Transform* transform) int bv_intersect_frustum_sphere(vec4* frustum, struct Bounding_Sphere* sphere, struct Transform* transform)
{ {
int intersect_type = IT_INSIDE; int intersect_type = IT_INSIDE;
vec3 center; vec3 center, abs_pos, abs_scale;
float radius = sphere->radius; float radius = sphere->radius;
vec3 abs_pos, abs_scale; vec3_fill(&center, 0.f, 0.f, 0.f);
vec3_fill(&abs_pos, 0.f, 0.f, 0.f);
vec3_fill(&abs_scale, 0.f, 0.f, 0.f);
transform_get_absolute_pos(transform, &abs_pos); transform_get_absolute_pos(transform, &abs_pos);
transform_get_absolute_scale(transform, &abs_scale); transform_get_absolute_scale(transform, &abs_scale);
float max_scale_dimension = fabsf(abs_scale.x); float max_scale_dimension = fabsf(abs_scale.x);
if(fabsf(abs_scale.y) > max_scale_dimension) max_scale_dimension = fabsf(abs_scale.y); if(fabsf(abs_scale.y) > max_scale_dimension) max_scale_dimension = fabsf(abs_scale.y);
if(fabsf(abs_scale.z) > max_scale_dimension) max_scale_dimension = fabsf(abs_scale.z); if(fabsf(abs_scale.z) > max_scale_dimension) max_scale_dimension = fabsf(abs_scale.z);
radius *= max_scale_dimension; radius *= max_scale_dimension;
vec3_fill(&center, 0.f, 0.f, 0.f);
vec3_add(&center, &sphere->center, &abs_pos); vec3_add(&center, &sphere->center, &abs_pos);
//vec3_mul(&center, &center, &transform->scale); //vec3_mul(&center, &center, &transform->scale);
for(int i = 0; i < 6; i++) for(int i = 0; i < 6; i++)
{ {
vec3 plane_normal = {frustum[i].x, frustum[i].y, frustum[i].z}; vec3 plane_normal = {frustum[i].x, frustum[i].y, frustum[i].z};
float distance = frustum[i].w; float distance = frustum[i].w;
float dot = vec3_dot(&plane_normal, &center) + distance; float dot = vec3_dot(&plane_normal, &center) + distance;
if(dot < -radius) if(dot < -radius)
{ {
intersect_type = IT_OUTSIDE; intersect_type = IT_OUTSIDE;

@ -31,7 +31,8 @@ enum Frustum_Planes
FP_BOTTOM, FP_BOTTOM,
FP_TOP, FP_TOP,
FP_NEAR, FP_NEAR,
FP_FAR FP_FAR,
FP_NUM_PLANES
}; };
int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Transform* transform); int bv_intersect_frustum_box(vec4* frustum, struct Bounding_Box* box, struct Transform* transform);

@ -16,8 +16,9 @@
#include <math.h> #include <math.h>
static struct Camera* camera_list; static struct Camera* camera_list;
static int* empty_indices; static int* empty_indices;
static int primary_camera_index; static int primary_camera_index;
static void update_frustum(struct Camera* camera); static void update_frustum(struct Camera* camera);
struct Camera* camera_get(int index) struct Camera* camera_get(int index)
@ -31,8 +32,8 @@ struct Camera* camera_get(int index)
void camera_init(void) void camera_init(void)
{ {
camera_list = array_new(struct Camera); camera_list = array_new(struct Camera);
empty_indices = array_new(int); empty_indices = array_new(int);
primary_camera_index = -1; primary_camera_index = -1;
} }
@ -44,8 +45,15 @@ void camera_remove(int index)
if(camera->fbo != -1) framebuffer_remove(camera->fbo); if(camera->fbo != -1) framebuffer_remove(camera->fbo);
if(camera->render_tex != -1) texture_remove(camera->render_tex); if(camera->render_tex != -1) texture_remove(camera->render_tex);
if(camera->depth_tex != -1) texture_remove(camera->depth_tex); if(camera->depth_tex != -1) texture_remove(camera->depth_tex);
camera->resizeable = 0;
camera->fbo = camera->render_tex = camera->depth_tex = camera->node = -1; camera->fbo = camera->render_tex = camera->depth_tex = camera->node = -1;
camera->ortho = camera->resizeable = 0;
camera->fov = camera->aspect_ratio = camera->nearz = camera->farz = 0.f;
mat4_identity(&camera->view_mat);
mat4_identity(&camera->proj_mat);
mat4_identity(&camera->view_proj_mat);
for(int i = 0; i < FP_NUM_PLANES; i++)
vec4_fill(&camera->frustum[i], 0.f, 0.f, 0.f, 0.f);
vec4_fill(&camera->clear_color, 0.f, 1.f, 0.f, 1.0);
array_push(empty_indices, index, int); array_push(empty_indices, index, int);
} }
} }
@ -87,6 +95,8 @@ int camera_create(int node, int width, int height)
mat4_identity(&new_camera->view_mat); mat4_identity(&new_camera->view_mat);
mat4_identity(&new_camera->proj_mat); mat4_identity(&new_camera->proj_mat);
mat4_identity(&new_camera->view_proj_mat); mat4_identity(&new_camera->view_proj_mat);
for(int i = 0; i < FP_NUM_PLANES; i++)
vec4_fill(&new_camera->frustum[i], 0.f, 0.f, 0.f, 0.f);
camera_update_view(new_camera); camera_update_view(new_camera);
camera_update_proj(new_camera); camera_update_proj(new_camera);
vec4_fill(&new_camera->clear_color, 1.f, 1.f, 1.f, 1.f); vec4_fill(&new_camera->clear_color, 1.f, 1.f, 1.f, 1.f);
@ -262,10 +272,10 @@ static void update_frustum(struct Camera* camera)
camera->frustum[FP_FAR].z = mvp[11] - mvp[10]; camera->frustum[FP_FAR].z = mvp[11] - mvp[10];
camera->frustum[FP_FAR].w = mvp[15] - mvp[14]; camera->frustum[FP_FAR].w = mvp[15] - mvp[14];
for(int i = 0; i < 6; i++) for(int i = 0; i < FP_NUM_PLANES; i++)
{ {
vec3 plane_xyz = {camera->frustum[i].x, camera->frustum[i].y, camera->frustum[i].z}; vec3 plane_xyz = {camera->frustum[i].x, camera->frustum[i].y, camera->frustum[i].z};
float length = fabsf(vec3_len(&plane_xyz)); float length = fabsf(vec3_len(&plane_xyz));
vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length)); vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length));
} }
} }

@ -18,7 +18,7 @@ static int* empty_indices;
void entity_init(void) void entity_init(void)
{ {
entity_list = array_new(struct Entity); entity_list = array_new(struct Entity);
empty_indices = array_new(int); empty_indices = array_new(int);
} }
@ -52,6 +52,7 @@ void entity_remove(int index)
entity->parent = -1; entity->parent = -1;
entity->is_listener = 0; entity->is_listener = 0;
array_free(entity->children); array_free(entity->children);
entity->children = NULL;
free(entity->name); free(entity->name);
free(entity->tag); free(entity->tag);
entity->name = entity->tag = NULL; entity->name = entity->tag = NULL;
@ -80,7 +81,7 @@ struct Entity* entity_create(const char* name, const char* tag)
if(new_entity->tag) free(new_entity->tag); if(new_entity->tag) free(new_entity->tag);
new_entity->name = name ? str_new(name) : str_new("DEFAULT_NAME"); new_entity->name = name ? str_new(name) : str_new("DEFAULT_NAME");
new_entity->tag = tag ? str_new(tag) : str_new("DEFAULT_TAG"); new_entity->tag = tag ? str_new(tag) : str_new("DEFAULT_TAG");
new_entity->node = index; new_entity->node = index;
new_entity->parent = -1; new_entity->parent = -1;
new_entity->is_listener = 0; new_entity->is_listener = 0;
@ -172,8 +173,8 @@ void* entity_component_get(struct Entity* entity, enum Component component)
void* entity_component_add(struct Entity* entity, enum Component component, ...) void* entity_component_add(struct Entity* entity, enum Component component, ...)
{ {
void* new_comp = NULL;
assert(entity); assert(entity);
void* new_comp = NULL;
va_list args; va_list args;
va_start(args, component); va_start(args, component);
int new_comp_index = -1; int new_comp_index = -1;

Loading…
Cancel
Save