paint-volume: Fix culling bug to handle partial culls
This updates the inner loops of the cull function so now the vertices of the polygon being culled are iterated in the inner loop instead of the clip planes and we count how many vertices are outside the current plane so we can bail out immediately if all the vertices are outside of any plane and so we can correctly track partial intersections with the clip region. The previous approach could catch some partial intersections but for example a rectangle that was larger than the clip region centred over the clip region with all corners outside would be reported as outside, not as a partial intersection.
This commit is contained in:
parent
151b80a837
commit
114133c98c
@ -922,8 +922,7 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv,
|
|||||||
{
|
{
|
||||||
int vertex_count;
|
int vertex_count;
|
||||||
ClutterVertex *vertices = pv->vertices;
|
ClutterVertex *vertices = pv->vertices;
|
||||||
gboolean in = TRUE;
|
gboolean partial = FALSE;
|
||||||
gboolean out = TRUE;
|
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -942,10 +941,10 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv,
|
|||||||
else
|
else
|
||||||
vertex_count = 8;
|
vertex_count = 8;
|
||||||
|
|
||||||
for (i = 0; i < vertex_count; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
gboolean point_in = TRUE;
|
int out = 0;
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < vertex_count; j++)
|
||||||
{
|
{
|
||||||
ClutterVertex p;
|
ClutterVertex p;
|
||||||
float distance;
|
float distance;
|
||||||
@ -953,32 +952,27 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv,
|
|||||||
/* XXX: for perspective projections this can be optimized
|
/* XXX: for perspective projections this can be optimized
|
||||||
* out because all the planes should pass through the origin
|
* out because all the planes should pass through the origin
|
||||||
* so (0,0,0) is a valid v0. */
|
* so (0,0,0) is a valid v0. */
|
||||||
p.x = vertices[i].x - planes[j].v0.x;
|
p.x = vertices[j].x - planes[i].v0.x;
|
||||||
p.y = vertices[i].y - planes[j].v0.y;
|
p.y = vertices[j].y - planes[i].v0.y;
|
||||||
p.z = vertices[i].z - planes[j].v0.z;
|
p.z = vertices[j].z - planes[i].v0.z;
|
||||||
|
|
||||||
distance =
|
distance =
|
||||||
planes[j].n.x * p.x + planes[j].n.y * p.y + planes[j].n.z * p.z;
|
planes[i].n.x * p.x + planes[i].n.y * p.y + planes[i].n.z * p.z;
|
||||||
|
|
||||||
if (distance < 0)
|
if (distance < 0)
|
||||||
{
|
out++;
|
||||||
point_in = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!point_in)
|
if (out == 4)
|
||||||
in = FALSE;
|
return CLUTTER_CULL_RESULT_OUT;
|
||||||
else
|
else if (out != 0)
|
||||||
out = FALSE;
|
partial = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in)
|
if (partial)
|
||||||
return CLUTTER_CULL_RESULT_IN;
|
|
||||||
else if (out)
|
|
||||||
return CLUTTER_CULL_RESULT_OUT;
|
|
||||||
else
|
|
||||||
return CLUTTER_CULL_RESULT_PARTIAL;
|
return CLUTTER_CULL_RESULT_PARTIAL;
|
||||||
|
else
|
||||||
|
return CLUTTER_CULL_RESULT_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user