From 7c31edb385fce1ce3425c88994a333f4e6f6d5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 8 Mar 2018 17:54:14 +0100 Subject: DRW: Culling: Expose & Add culling functions to engines. This way engines can do preemptive culling by themselves. --- source/blender/draw/intern/DRW_render.h | 9 +++++++ source/blender/draw/intern/draw_manager.c | 4 +++ source/blender/draw/intern/draw_manager.h | 6 ----- source/blender/draw/intern/draw_manager_exec.c | 36 +++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 10 deletions(-) (limited to 'source/blender/draw') diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 4815c117a8c..9f0c06a2886 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -77,6 +77,11 @@ typedef struct DRWInterface DRWInterface; typedef struct DRWPass DRWPass; typedef struct DRWShadingGroup DRWShadingGroup; +/* TODO Put it somewhere else? */ +typedef struct BoundSphere { + float center[3], radius; +} BoundSphere; + /* declare members as empty (unused) */ typedef char DRWViewportEmptyList; @@ -478,6 +483,10 @@ void DRW_state_invert_facing(void); void DRW_state_clip_planes_add(float plane_eq[4]); void DRW_state_clip_planes_reset(void); +/* Culling, return true if object is inside view frustum. */ +bool DRW_culling_sphere_test(BoundSphere *bsphere); +bool DRW_culling_box_test(BoundBox *bbox); + /* Selection */ void DRW_select_load_id(unsigned int id); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 8ca5ee8f577..856e40da345 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -465,6 +465,7 @@ void DRW_viewport_matrix_override_set(float mat[4][4], DRWViewportMatrixType typ copy_m4_m4(DST.view_data.matstate.mat[type], mat); DST.override_mat |= (1 << type); DST.dirty_mat = true; + DST.clipping.updated = false; } void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type) @@ -473,6 +474,7 @@ void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type) copy_m4_m4(DST.view_data.matstate.mat[type], DST.original_mat.mat[type]); DST.override_mat &= ~(1 << type); DST.dirty_mat = true; + DST.clipping.updated = false; } void DRW_viewport_matrix_override_set_all(DRWMatrixState *state) @@ -480,6 +482,7 @@ void DRW_viewport_matrix_override_set_all(DRWMatrixState *state) memcpy(DST.view_data.matstate.mat, state, sizeof(DRWMatrixState)); DST.override_mat = 0xFFFFFF; DST.dirty_mat = true; + DST.clipping.updated = false; } void DRW_viewport_matrix_override_unset_all(void) @@ -487,6 +490,7 @@ void DRW_viewport_matrix_override_unset_all(void) memcpy(DST.view_data.matstate.mat, DST.original_mat.mat, sizeof(DRWMatrixState)); DST.override_mat = 0; DST.dirty_mat = true; + DST.clipping.updated = false; } bool DRW_viewport_is_persp_get(void) diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index f8989a0703a..1afa0ff2402 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -76,12 +76,6 @@ #endif /* USE_PROFILE */ -/* TODO Put it somewhere else? */ -typedef struct BoundSphere { - float center[3], radius; -} BoundSphere; - - /* ------------ Data Structure --------------- */ /** * Data structure containing all drawcalls organized by passes and materials. diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 1c149330005..27a94ae064b 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -530,11 +530,15 @@ static void draw_clipping_setup_from_view(void) /* Transform to world space. */ mul_m4_v3(viewinv, bsphere->center); } + + DST.clipping.updated = true; } /* Return True if the given BoundSphere intersect the current view frustum */ -static bool draw_culling_sphere_test(BoundSphere *bsphere) +bool DRW_culling_sphere_test(BoundSphere *bsphere) { + draw_clipping_setup_from_view(); + /* Bypass test if radius is negative. */ if (bsphere->radius < 0.0f) return true; @@ -556,6 +560,32 @@ static bool draw_culling_sphere_test(BoundSphere *bsphere) return true; } +/* Return True if the given BoundBox intersect the current view frustum. + * bbox must be in world space. */ +bool DRW_culling_box_test(BoundBox *bbox) +{ + draw_clipping_setup_from_view(); + + /* 6 view frustum planes */ + for (int p = 0; p < 6; p++) { + /* 8 box vertices. */ + for (int v = 0; v < 8 ; v++) { + float dist = plane_point_side_v3(DST.clipping.frustum_planes[p], bbox->vec[v]); + if (dist > 0.0f) { + /* At least one point in front of this plane. + * Go to next plane. */ + break; + } + else if (v == 7) { + /* 8 points behind this plane. */ + return false; + } + } + } + + return true; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -572,7 +602,7 @@ static void draw_matrices_model_prepare(DRWCallState *st) st->cache_id = DST.state_cache_id; } - if (draw_culling_sphere_test(&st->bsphere)) { + if (DRW_culling_sphere_test(&st->bsphere)) { st->flag &= ~DRW_CALL_CULLED; } else { @@ -934,8 +964,6 @@ static void drw_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha } } - DST.clipping.updated = false; - /* TODO dispatch threads to compute matrices/culling */ } -- cgit v1.2.3