weston/tests/vertex-clip-test.c
Loïc Molinari e82ce8032c gl-renderer: Fix quad clipper non-zero area check
The non-zero area check of clipper_quad_clip() is incorrect for quads
initialized with a polygon starting with a vertical edge. In order to
handle polygons starting with an horizontal edge and polygons starting
with a vertical one, it must check opposite vertices for equality.

The test previously described as "Box intersects entire smaller
aligned quad" is now described as "Clockwise winding and top/left
initial vertex". This test keeps the same values as before but all
combinations of winding order and first edge orientations are
also tested. The QUAD() macro isn't used anymore to do so.

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
2024-02-06 09:21:11 +00:00

737 lines
22 KiB
C

/*
* Copyright © 2013 Sam Spilsbury <smspillaz@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Each vertex clipping test begins with a brief textual introduction using a
* coordinate system with X growing right and Y growing down as a convention.
*/
#include "config.h"
#include "weston-test-runner.h"
#include "vertex-clipping.h"
#define BOX(x1,y1,x2,y2) { { x1, y1 }, { x2, y2 } }
#define QUAD(x1,y1,x2,y2) { { x1, y1 }, { x2, y1 }, { x2, y2 }, { x1, y2 } }
struct vertex_clip_test_data {
struct clipper_vertex box[2];
struct clipper_vertex polygon[8];
struct clipper_vertex clipped[8];
int polygon_n;
int clipped_n;
bool aligned;
};
/* Compare clipped vertices to expected vertices. While the clipper guarantees
* correct winding order, it doesn't specify which vertex is emitted first. This
* function takes care of finding the first expected vertex in the clipped array
* before comparing the entire series. */
static void
assert_vertices(const struct clipper_vertex *clipped, int clipped_n,
const struct clipper_vertex *expected, int expected_n)
{
int first, i, j;
/* Is the number of clipped vertices correct? */
assert(clipped_n == expected_n);
for (first = 0; first < clipped_n; first++)
if (clipper_float_difference(clipped[first].x, expected[0].x) == 0.0f &&
clipper_float_difference(clipped[first].y, expected[0].y) == 0.0f)
break;
/* Have we found the first expected vertex? */
assert(!clipped_n || first != clipped_n);
/* Do the remaining vertices match? */
for (i = 1; i < clipped_n; i++) {
j = (i + first) % clipped_n;
assert(clipper_float_difference(clipped[j].x, expected[i].x) == 0.0f &&
clipper_float_difference(clipped[j].y, expected[i].y) == 0.0f);
}
}
/* clipper_clip() tests: */
static const struct vertex_clip_test_data clip_expected_data[] = {
/* Quad inside box. */
{
.box = BOX (50.0f, 50.0f, 100.0f, 100.0f),
.polygon = QUAD(51.0f, 51.0f, 99.0f, 99.0f),
.clipped = QUAD(51.0f, 51.0f, 99.0f, 99.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Quad bottom edge outside of box. */
{
.box = BOX (50.0f, 50.0f, 100.0f, 100.0f),
.polygon = QUAD(51.0f, 51.0f, 99.0f, 101.0f),
.clipped = QUAD(51.0f, 51.0f, 99.0f, 100.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Quad top edge outside of box. */
{
.box = BOX (50.0f, 50.0f, 100.0f, 100.0f),
.polygon = QUAD(51.0f, 49.0f, 99.0f, 99.0f),
.clipped = QUAD(51.0f, 50.0f, 99.0f, 99.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Quad left edge outside of box. */
{
.box = BOX (50.0f, 50.0f, 100.0f, 100.0f),
.polygon = QUAD(49.0f, 51.0f, 99.0f, 99.0f),
.clipped = QUAD(50.0f, 51.0f, 99.0f, 99.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Quad right edge outside of box. */
{
.box = BOX (50.0f, 50.0f, 100.0f, 100.0f),
.polygon = QUAD(51.0f, 51.0f, 101.0f, 99.0f),
.clipped = QUAD(51.0f, 51.0f, 100.0f, 99.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Rotated quad with edges adjacent to box corners. */
{
.box = BOX(50.0f, 50.0f, 100.0f, 100.0f),
.polygon = {{ 25.0f, 75.0f}, {75.0f, 25.0f},
{125.0f, 75.0f}, {75.0f, 125.0f}},
.clipped = QUAD(50.0f, 50.0f, 100.0f, 100.0f),
.polygon_n = 4,
.clipped_n = 4,
},
/* Rotated quad with edges cutting out box corners. */
{
.box = BOX(50.0f, 50.0f, 100.0f, 100.0f),
.polygon = {{ 37.5f, 75.0f}, { 75.0f, 37.5f},
{112.5f, 75.0f}, { 75.0f, 112.5f}},
.clipped = {{ 62.5f, 50.0f}, { 87.5f, 50.0f},
{100.0f, 62.5f}, {100.0f, 87.5f},
{ 87.5f, 100.0f}, { 62.5f, 100.0f},
{ 50.0f, 87.5f}, { 50.0f, 62.5f}},
.polygon_n = 4,
.clipped_n = 8,
},
/* Same as above using counter-clockwise winding. */
{
.box = BOX(50.0f, 50.0f, 100.0f, 100.0f),
.polygon = {{ 37.5f, 75.0f}, { 75.0f, 112.5f},
{112.5f, 75.0f}, { 75.0f, 37.5f}},
.clipped = {{ 62.5f, 50.0f}, { 50.0f, 62.5f},
{ 50.0f, 87.5f}, { 62.5f, 100.0f},
{ 87.5f, 100.0f}, {100.0f, 87.5f},
{100.0f, 62.5f}, { 87.5f, 50.0f}},
.polygon_n = 4,
.clipped_n = 8,
},
};
TEST_P(clip_expected, clip_expected_data)
{
struct vertex_clip_test_data *tdata = data;
struct clipper_vertex clipped[8];
int clipped_n;
clipped_n = clipper_clip(tdata->polygon, tdata->polygon_n, tdata->box,
clipped);
assert_vertices(clipped, clipped_n, tdata->clipped, tdata->clipped_n);
}
TEST(clip_size_too_high)
{
struct clipper_vertex polygon[8] = {}, box[2] = {};
assert(clipper_clip(polygon, 9, box, NULL) == -1);
}
/* clipper_quad_clip() tests: */
static const struct vertex_clip_test_data quad_clip_expected_data[] = {
/* Aligned quad clipping with adjacent edges: */
/* Box top/left corner adjacent to polygon bottom/right corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-1.00f, -1.00f, -0.50f, -0.50f),
.clipped_n = 0,
},
/* Box top edge adjacent to polygon bottom edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.25f, -1.00f, 0.25f, -0.50f),
.clipped_n = 0,
},
/* Box top/right corner adjacent to polygon bottom/left corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.50f, -1.00f, 1.00f, -0.50f),
.clipped_n = 0,
},
/* Box left edge adjacent to polygon right edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-1.00f, -0.25f, -0.50f, 0.25f),
.clipped_n = 0,
},
/* Box right edge adjacent to polygon left edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.50f, -0.25f, 1.00f, 0.25f),
.clipped_n = 0,
},
/* Box bottom/left corner adjacent to polygon top/right corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-1.00f, 0.50f, -0.50f, 1.00f),
.clipped_n = 0,
},
/* Box bottom edge adjacent to polygon top edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.25f, 0.50f, 0.25f, 1.00f),
.clipped_n = 0,
},
/* Box bottom/right corner adjacent to polygon top/left corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.50f, 0.50f, 1.00f, 1.00f),
.clipped_n = 0,
},
/* Aligned quad clipping with intersecting edges: */
/* Box top/left corner intersects polygon bottom/right corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.75f, -0.75f, -0.25f, -0.25f),
.clipped = QUAD(-0.50f, -0.50f, -0.25f, -0.25f),
.clipped_n = 4,
},
/* Box top edge intersects polygon bottom edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.25f, -0.75f, 0.25f, -0.25f),
.clipped = QUAD(-0.25f, -0.50f, 0.25f, -0.25f),
.clipped_n = 4,
},
/* Box top/right corner intersects polygon bottom/left corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.25f, -0.75f, 0.75f, -0.25f),
.clipped = QUAD( 0.25f, -0.50f, 0.50f, -0.25f),
.clipped_n = 4,
},
/* Box left edge intersects polygon right edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.75f, -0.25f, -0.25f, 0.25f),
.clipped = QUAD(-0.50f, -0.25f, -0.25f, 0.25f),
.clipped_n = 4,
},
/* Box right edge intersects polygon left edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.25f, -0.25f, 0.75f, 0.25f),
.clipped = QUAD( 0.25f, -0.25f, 0.50f, 0.25f),
.clipped_n = 4,
},
/* Box bottom/left corner intersects polygon top/right corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.75f, 0.25f, -0.25f, 0.75f),
.clipped = QUAD(-0.50f, 0.25f, -0.25f, 0.50f),
.clipped_n = 4,
},
/* Box bottom edge intersects polygon top edge. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD(-0.25f, 0.25f, 0.25f, 0.75f),
.clipped = QUAD(-0.25f, 0.25f, 0.25f, 0.50f),
.clipped_n = 4,
},
/* Box bottom/right corner intersects polygon top/left corner. */
{
.aligned = true,
.box = BOX (-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = QUAD( 0.25f, 0.25f, 0.75f, 0.75f),
.clipped = QUAD( 0.25f, 0.25f, 0.50f, 0.50f),
.clipped_n = 4,
},
/* Rotated quad clipping with adjacent edges: */
/* Box top/left corner adjacent to polygon bottom corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, -0.75f}, {-0.50f, -1.00f},
{-0.25f, -0.75f}, {-0.50f, -0.50f}},
.clipped_n = 0,
},
/* Box top edge adjacent to polygon bottom corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.25f, -0.75f}, { 0.00f, -1.00f},
{ 0.25f, -0.75f}, { 0.00f, -0.50f}},
.clipped_n = 0,
},
/* Box top/right corner adjacent to polygon bottom corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.25f, -0.75f}, { 0.50f, -1.00f},
{ 0.75f, -0.75f}, { 0.50f, -0.50f}},
.clipped_n = 0,
},
/* Box left edge adjacent to polygon right corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-1.00f, 0.00f}, {-0.75f, -0.25f},
{-0.50f, 0.00f}, {-0.75f, 0.25f}},
.clipped_n = 0,
},
/* Box right edge adjacent to polygon left corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.50f, 0.00f}, { 0.75f, -0.25f},
{ 1.00f, 0.00f}, { 0.75f, 0.25f}},
.clipped_n = 0,
},
/* Box bottom/left corner adjacent to polygon top corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, 0.75f}, {-0.50f, 0.50f},
{-0.25f, 0.75f}, {-0.50f, 1.00f}},
.clipped_n = 0,
},
/* Box bottom edge adjacent to polygon top corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.25f, 0.75f}, { 0.00f, 0.50f},
{ 0.25f, 0.75f}, { 0.00f, 1.00f}},
.clipped_n = 0,
},
/* Box bottom/right corner adjacent to polygon top corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.25f, 0.75f}, { 0.50f, 0.50f},
{ 0.75f, 0.75f}, { 0.50f, 1.00f}},
.clipped_n = 0,
},
/* Rotated quad clipping with slightly intersecting edges: */
/* Box top/left corner slightly intersects polygon bottom/right edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, -0.50f}, {-0.50f, -0.75f},
{-0.25f, -0.50f}, {-0.50f, -0.25f}},
.clipped = {{-0.50f, -0.25f}, {-0.50f, -0.50f},
{-0.25f, -0.50f}},
.clipped_n = 3,
},
/* Box top edge slightly intersects polygon bottom corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.25f, -0.50f}, { 0.00f, -0.75f},
{ 0.25f, -0.50f}, { 0.00f, -0.25f}},
.clipped = {{-0.25f, -0.50f}, { 0.25f, -0.50f},
{ 0.00f, -0.25f}},
.clipped_n = 3,
},
/* Box top/right corner slightly intersects polygon bottom/left edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.25f, -0.50f}, { 0.50f, -0.75f},
{ 0.75f, -0.50f}, { 0.50f, -0.25f}},
.clipped = {{ 0.25f, -0.50f}, { 0.50f, -0.50f},
{ 0.50f, -0.25f}},
.clipped_n = 3,
},
/* Box left edge slightly intersects polygon right corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, 0.00f}, {-0.50f, -0.25f},
{-0.25f, 0.00f}, {-0.50f, 0.25f}},
.clipped = {{-0.50f, -0.25f}, {-0.25f, 0.00f},
{-0.50f, 0.25f}},
.clipped_n = 3,
},
/* Box right edge slightly intersects polygon left corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.25f, 0.00f}, { 0.50f, -0.25f},
{ 0.75f, 0.00f}, { 0.50f, 0.25f}},
.clipped = {{ 0.25f, 0.00f}, { 0.50f, -0.25f},
{ 0.50f, 0.25f}},
.clipped_n = 3,
},
/* Box bottom/left corner slightly intersects polygon top/right edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, 0.50f}, {-0.50f, 0.25f},
{-0.25f, 0.50f}, {-0.50f, 0.75f}},
.clipped = {{-0.50f, 0.25f}, {-0.25f, 0.50f},
{-0.50f, 0.50f}},
.clipped_n = 3,
},
/* Box bottom edge slightly intersects polygon top corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.25f, 0.50f}, { 0.00f, 0.25f},
{ 0.25f, 0.50f}, { 0.00f, 0.75f}},
.clipped = {{-0.25f, 0.50f}, { 0.00f, 0.25f},
{ 0.25f, 0.50f}},
.clipped_n = 3,
},
/* Box bottom/right corner slightly intersects polygon top/left edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.25f, 0.50f}, { 0.50f, 0.25f},
{ 0.75f, 0.50f}, { 0.50f, 0.75f}},
.clipped = {{ 0.25f, 0.50f}, { 0.50f, 0.25f},
{ 0.50f, 0.50f}},
.clipped_n = 3,
},
/* Rotated quad clipping with largely intersecting edges: */
/* Box top/left corner largely intersects polygon bottom/right edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.625f, -0.375f}, {-0.375f, -0.625f},
{-0.125f, -0.375f}, {-0.375f, -0.125f}},
.clipped = {{-0.500f, -0.500f}, {-0.250f, -0.500f},
{-0.125f, -0.375f}, {-0.375f, -0.125f},
{-0.500f, -0.250f}},
.clipped_n = 5,
},
/* Box top edge largely intersects polygon bottom corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.250f, -0.375f}, { 0.000f, -0.625f},
{ 0.250f, -0.375f}, { 0.000f, -0.125f}},
.clipped = {{-0.125f, -0.500f}, { 0.125f, -0.500f},
{ 0.250f, -0.375f}, { 0.000f, -0.125f},
{-0.250f, -0.375f}},
.clipped_n = 5,
},
/* Box top/right corner largely intersects polygon bottom/left edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.125f, -0.375f}, { 0.375f, -0.625f},
{ 0.625f, -0.375f}, { 0.375f, -0.125f}},
.clipped = {{ 0.125f, -0.375f}, { 0.250f, -0.500f},
{ 0.500f, -0.500f}, { 0.500f, -0.250f},
{ 0.375f, -0.125f}},
.clipped_n = 5,
},
/* Box left edge largely intersects polygon right corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.625f, 0.000f}, {-0.375f, -0.250f},
{-0.125f, 0.000f}, {-0.375f, 0.250f}},
.clipped = {{-0.500f, 0.125f}, {-0.500f, -0.125f},
{-0.375f, -0.250f}, {-0.125f, 0.000f},
{-0.375f, 0.250f}},
.clipped_n = 5,
},
/* Box right edge largely intersects polygon left corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.125f, 0.000f}, { 0.375f, -0.250f},
{ 0.625f, 0.000f}, { 0.375f, 0.250f}},
.clipped = {{ 0.125f, 0.000f}, { 0.375f, -0.250f},
{ 0.500f, -0.125f}, { 0.500f, 0.125f},
{ 0.375f, 0.250f}},
.clipped_n = 5,
},
/* Box bottom/left corner largely intersects polygon top/right edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.625f, 0.375f}, {-0.375f, 0.125f},
{-0.125f, 0.375f}, {-0.375f, 0.625f}},
.clipped = {{-0.500f, 0.500f}, {-0.500f, 0.250f},
{-0.375f, 0.125f}, {-0.125f, 0.375f},
{-0.250f, 0.500f}},
.clipped_n = 5,
},
/* Box bottom edge largely intersects polygon top corner. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.250f, 0.375f}, { 0.000f, 0.125f},
{ 0.250f, 0.375f}, { 0.000f, 0.625f}},
.clipped = {{-0.125f, 0.500f}, {-0.250f, 0.375f},
{ 0.000f, 0.125f}, { 0.250f, 0.375f},
{ 0.125f, 0.500f}},
.clipped_n = 5,
},
/* Box bottom/right corner largely intersects polygon top/left edge. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{ 0.125f, 0.375f}, { 0.375f, 0.125f},
{ 0.625f, 0.375f}, { 0.375f, 0.625f}},
.clipped = {{ 0.125f, 0.375f}, { 0.375f, 0.125f},
{ 0.500f, 0.250f}, { 0.500f, 0.500f},
{ 0.250f, 0.500f}},
.clipped_n = 5,
},
/* Box intersects entire smaller aligned quad of different winding
* orders and first edge orientations: */
/* Clockwise winding and top/left initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{-0.25f, -0.25f}, { 0.25f, -0.25f},
{ 0.25f, 0.25f}, {-0.25f, 0.25f}},
.clipped = {{-0.25f, -0.25f}, { 0.25f, -0.25f},
{ 0.25f, 0.25f}, {-0.25f, 0.25f}},
.clipped_n = 4,
},
/* Clockwise winding and top/right initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{ 0.25f, -0.25f}, { 0.25f, 0.25f},
{-0.25f, 0.25f}, {-0.25f, -0.25f}},
.clipped = {{ 0.25f, -0.25f}, { 0.25f, 0.25f},
{-0.25f, 0.25f}, {-0.25f, -0.25f}},
.clipped_n = 4,
},
/* Clockwise winding and bottom/right initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{ 0.25f, 0.25f}, {-0.25f, 0.25f},
{-0.25f, -0.25f}, { 0.25f, -0.25f}},
.clipped = {{ 0.25f, 0.25f}, {-0.25f, 0.25f},
{-0.25f, -0.25f}, { 0.25f, -0.25f}},
.clipped_n = 4,
},
/* Clockwise winding and bottom/left initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{-0.25f, 0.25f}, {-0.25f, -0.25f},
{ 0.25f, -0.25f}, { 0.25f, 0.25f}},
.clipped = {{-0.25f, 0.25f}, {-0.25f, -0.25f},
{ 0.25f, -0.25f}, { 0.25f, 0.25f}},
.clipped_n = 4,
},
/* Counter-clockwise winding and top/left initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{-0.25f, -0.25f}, {-0.25f, 0.25f},
{ 0.25f, 0.25f}, { 0.25f, -0.25f}},
.clipped = {{-0.25f, -0.25f}, {-0.25f, 0.25f},
{ 0.25f, 0.25f}, { 0.25f, -0.25f}},
.clipped_n = 4,
},
/* Counter-clockwise winding and top/right initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{ 0.25f, -0.25f}, {-0.25f, -0.25f},
{-0.25f, 0.25f}, { 0.25f, 0.25f}},
.clipped = {{ 0.25f, -0.25f}, {-0.25f, -0.25f},
{-0.25f, 0.25f}, { 0.25f, 0.25f}},
.clipped_n = 4,
},
/* Counter-clockwise winding and bottom/right initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{ 0.25f, 0.25f}, { 0.25f, -0.25f},
{-0.25f, -0.25f}, {-0.25f, 0.25f}},
.clipped = {{ 0.25f, 0.25f}, { 0.25f, -0.25f},
{-0.25f, -0.25f}, {-0.25f, 0.25f}},
.clipped_n = 4,
},
/* Counter-clockwise winding and bottom/left initial vertex. */
{
.aligned = true,
.box = BOX(-0.50f, -0.50f, 0.50f, 0.50f),
.polygon = {{-0.25f, 0.25f}, { 0.25f, 0.25f},
{ 0.25f, -0.25f}, {-0.25f, -0.25f}},
.clipped = {{-0.25f, 0.25f}, { 0.25f, 0.25f},
{ 0.25f, -0.25f}, {-0.25f, -0.25f}},
.clipped_n = 4,
},
/* Miscellaneous cases: */
/* Box intersects entire same size aligned quad. */
{
.aligned = true,
.box = BOX (-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = QUAD(-0.5f, -0.5f, 0.5f, 0.5f),
.clipped = QUAD(-0.5f, -0.5f, 0.5f, 0.5f),
.clipped_n = 4,
},
/* Box intersects entire rotated quad. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.5f, 0.0f}, { 0.0f, -0.5f},
{ 0.5f, 0.0f}, { 0.0f, 0.5f}},
.clipped = {{-0.5f, 0.0f}, { 0.0f, -0.5f},
{ 0.5f, 0.0f}, { 0.0f, 0.5f}},
.clipped_n = 4,
},
/* Box intersects rotated quad cutting out the 4 corners. */
{
.aligned = false,
.box = BOX(-0.5f, -0.5f, 0.5f, 0.5f),
.polygon = {{-0.75f, 0.00f}, { 0.00f, -0.75f},
{ 0.75f, 0.00f}, { 0.00f, 0.75f}},
.clipped = {{-0.50f, 0.25f}, {-0.50f, -0.25f},
{-0.25f, -0.50f}, { 0.25f, -0.50f},
{ 0.50f, -0.25f}, { 0.50f, 0.25f},
{ 0.25f, 0.50f}, {-0.25f, 0.50f}},
.clipped_n = 8,
},
};
TEST_P(quad_clip_expected, quad_clip_expected_data)
{
struct vertex_clip_test_data *tdata = data;
struct clipper_vertex clipped[8];
struct clipper_quad quad;
int clipped_n;
clipper_quad_init(&quad, tdata->polygon, tdata->aligned);
clipped_n = clipper_quad_clip(&quad, tdata->box, clipped);
assert_vertices(clipped, clipped_n, tdata->clipped, tdata->clipped_n);
}
/* clipper_float_difference() tests: */
TEST(float_difference_different)
{
assert(clipper_float_difference(1.0f, 0.0f) == 1.0f);
}
TEST(float_difference_same)
{
assert(clipper_float_difference(1.0f, 1.0f) == 0.0f);
}