[mutter/gbsneto/graphene-frustrum: 8/17] clutter/stage: Use graphene_frustum_t for clipping




commit ce9cc0a90cb246bc215c71f889aaa376406c89bb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Oct 9 19:08:47 2020 -0300

    clutter/stage: Use graphene_frustum_t for clipping
    
    Instead of 4 planes, use a graphene_frustum_t to store the clipping
    planes.
    
    The cautious reviewer might noticed that we are now setting up 6
    planes: the 4 planes we were doing before, plus 2 extra planes in
    the Z axis. These extra planes simulate an "infinite" Z far, and
    an "on-camera" Z near.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489

 clutter/clutter/clutter-actor.c                |  6 ++--
 clutter/clutter/clutter-paint-volume-private.h |  4 +--
 clutter/clutter/clutter-paint-volume.c         | 38 ++++++++------------------
 clutter/clutter/clutter-stage-private.h        |  2 +-
 clutter/clutter/clutter-stage.c                | 38 ++++++++++++++++++--------
 5 files changed, 45 insertions(+), 43 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 5103fc7dc2..ef128e9788 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -3441,7 +3441,7 @@ cull_actor (ClutterActor        *self,
 {
   ClutterActorPrivate *priv = self->priv;
   ClutterStage *stage;
-  const graphene_plane_t *stage_clip;
+  const graphene_frustum_t *clip_frustum;
 
   if (!priv->last_paint_volume_valid)
     {
@@ -3463,10 +3463,10 @@ cull_actor (ClutterActor        *self,
     }
 
   stage = (ClutterStage *) _clutter_actor_get_stage_internal (self);
-  stage_clip = _clutter_stage_get_clip (stage);
+  clip_frustum = _clutter_stage_get_clip (stage);
 
   *result_out =
-    _clutter_paint_volume_cull (&priv->last_paint_volume, stage_clip);
+    _clutter_paint_volume_cull (&priv->last_paint_volume, clip_frustum);
 
   if (*result_out != CLUTTER_CULL_RESULT_OUT)
     {
diff --git a/clutter/clutter/clutter-paint-volume-private.h b/clutter/clutter/clutter-paint-volume-private.h
index 5d160c3806..5d51e5bf31 100644
--- a/clutter/clutter/clutter-paint-volume-private.h
+++ b/clutter/clutter/clutter-paint-volume-private.h
@@ -123,8 +123,8 @@ void                _clutter_paint_volume_axis_align           (ClutterPaintVolu
 void                _clutter_paint_volume_set_reference_actor  (ClutterPaintVolume *pv,
                                                                 ClutterActor *actor);
 
-ClutterCullResult   _clutter_paint_volume_cull                 (ClutterPaintVolume     *pv,
-                                                                const graphene_plane_t *planes);
+ClutterCullResult   _clutter_paint_volume_cull                 (ClutterPaintVolume       *pv,
+                                                                const graphene_frustum_t *frustum);
 
 void                _clutter_paint_volume_get_stage_paint_box  (ClutterPaintVolume *pv,
                                                                 ClutterStage *stage,
diff --git a/clutter/clutter/clutter-paint-volume.c b/clutter/clutter/clutter-paint-volume.c
index 705b276349..2047bf46e4 100644
--- a/clutter/clutter/clutter-paint-volume.c
+++ b/clutter/clutter/clutter-paint-volume.c
@@ -1071,14 +1071,12 @@ _clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv,
 }
 
 ClutterCullResult
-_clutter_paint_volume_cull (ClutterPaintVolume     *pv,
-                            const graphene_plane_t *planes)
+_clutter_paint_volume_cull (ClutterPaintVolume       *pv,
+                            const graphene_frustum_t *frustum)
 {
-  int vertex_count;
   graphene_point3d_t *vertices = pv->vertices;
-  gboolean partial = FALSE;
-  int i;
-  int j;
+  graphene_point3d_t *min, *max;
+  graphene_box_t box;
 
   if (pv->is_empty)
     return CLUTTER_CULL_RESULT_OUT;
@@ -1088,33 +1086,21 @@ _clutter_paint_volume_cull (ClutterPaintVolume     *pv,
   g_return_val_if_fail (pv->is_complete == TRUE, CLUTTER_CULL_RESULT_IN);
   g_return_val_if_fail (pv->actor == NULL, CLUTTER_CULL_RESULT_IN);
 
+  min = &vertices[0];
+
   /* Most actors are 2D so we only have to transform the front 4
    * vertices of the paint volume... */
   if (G_LIKELY (pv->is_2d))
-    vertex_count = 4;
+    max = &vertices[2];
   else
-    vertex_count = 8;
+    max = &vertices[6];
 
-  for (i = 0; i < 4; i++)
-    {
-      const graphene_plane_t *plane = &planes[i];
-      int out = 0;
-      for (j = 0; j < vertex_count; j++)
-        {
-          if (graphene_plane_distance (plane, &vertices[j]) < 0)
-            out++;
-        }
-
-      if (out == vertex_count)
-        return CLUTTER_CULL_RESULT_OUT;
-      else if (out != 0)
-        partial = TRUE;
-    }
+  graphene_box_init (&box, min, max);
 
-  if (partial)
-    return CLUTTER_CULL_RESULT_PARTIAL;
-  else
+  if (graphene_frustum_intersects_box (frustum, &box))
     return CLUTTER_CULL_RESULT_IN;
+  else
+    return CLUTTER_CULL_RESULT_OUT;
 }
 
 void
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index 8c3d1317a7..68fec2a840 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -98,7 +98,7 @@ ClutterActor *_clutter_stage_do_pick (ClutterStage    *stage,
 ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage);
 void                _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage);
 
-const graphene_plane_t *_clutter_stage_get_clip (ClutterStage *stage);
+const graphene_frustum_t *_clutter_stage_get_clip (ClutterStage *stage);
 
 ClutterStageQueueRedrawEntry *_clutter_stage_queue_actor_redraw            (ClutterStage                 
*stage,
                                                                             ClutterStageQueueRedrawEntry 
*entry,
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index e3c5a8aefe..f001db557c 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -115,7 +115,7 @@ struct _ClutterStagePrivate
 
   GArray *paint_volume_stack;
 
-  graphene_plane_t current_clip_planes[4];
+  graphene_frustum_t clip_frustum;
 
   GSList *pending_relayouts;
   GList *pending_queue_redraws;
@@ -659,13 +659,16 @@ typedef struct _Vector4
 } Vector4;
 
 static void
-_cogl_util_get_eye_planes_for_screen_poly (float                   *polygon,
-                                           int                      n_vertices,
-                                           float                   *viewport,
-                                           const graphene_matrix_t *projection,
-                                           const graphene_matrix_t *inverse_project,
-                                           graphene_plane_t        *planes)
-{
+_cogl_util_get_eye_planes_for_screen_poly (float                    *polygon,
+                                           int                       n_vertices,
+                                           float                    *viewport,
+                                           const graphene_matrix_t  *projection,
+                                           const graphene_matrix_t  *inverse_project,
+                                           const ClutterPerspective *perspective,
+                                           graphene_frustum_t       *frustum)
+{
+  graphene_plane_t planes[6];
+  graphene_vec4_t v;
   float Wc;
   Vector4 *tmp_poly;
   int i;
@@ -749,6 +752,18 @@ _cogl_util_get_eye_planes_for_screen_poly (float                   *polygon,
 
       graphene_plane_init_from_points (&planes[i], &p[0], &p[1], &p[2]);
     }
+
+  graphene_plane_init_from_vec4 (&planes[4],
+                                 graphene_vec4_init (&v, 0.f, 0.f, -1.f,
+                                                     perspective->z_near));
+  graphene_plane_init_from_vec4 (&planes[5],
+                                 graphene_vec4_init (&v, 0.f, 0.f, 1.f,
+                                                     perspective->z_far));
+
+  graphene_frustum_init (frustum,
+                         &planes[0], &planes[1],
+                         &planes[2], &planes[3],
+                         &planes[4], &planes[5]);
 }
 
 /* XXX: Instead of having a toplevel 2D clip region, it might be
@@ -809,7 +824,8 @@ setup_view_for_pick_or_paint (ClutterStage                *stage,
                                              viewport,
                                              &priv->projection,
                                              &priv->inverse_projection,
-                                             priv->current_clip_planes);
+                                             &priv->perspective,
+                                             &priv->clip_frustum);
 
   _clutter_stage_paint_volume_stack_free_all (stage);
 }
@@ -3075,10 +3091,10 @@ _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage)
 
 /* The is an out-of-band parameter available while painting that
  * can be used to cull actors. */
-const graphene_plane_t *
+const graphene_frustum_t *
 _clutter_stage_get_clip (ClutterStage *stage)
 {
-  return stage->priv->current_clip_planes;
+  return &stage->priv->clip_frustum;
 }
 
 /* When an actor queues a redraw we add it to a list on the stage that


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]