memononen / libtess2

Game and tools oriented refactored version of GLU tesselator.
Other
465 stars 98 forks source link

strange behavior with TESS_WINDING_POSITIVE and TESS_BOUNDARY_CONTOURS #42

Closed udokrix closed 2 years ago

udokrix commented 2 years ago

Hello Mikko Mononen,

while working with the problem of offsetting polygons in 2d, I came across with your "libtess2" and its pascal-port "fpc-libtess2". When tesselating with winding rule "TESS_WINDING_POSITIVE" and the element type "TESS_BOUNDARY_CONTOURS" I found a strange behavior. Sometimes the correct result was delivered, sometimes not and I do not know why =(. I want to show in 2 examples what I mean. The two polygons

const TESSreal offsetSquare[26] = { 0, 0, 0, 80, 200,80, 200, 0, 120, 0, 120, 200, 200, 200, 200, 120, 0, 120, 0, 200, 80, 200, 80, 0, 0,0 } ;

and

const TESSreal offsetHouse[32]= { 0,0, 0,20, 100,20, 100,0, 80,0, 80,100, 100,100, 86,84, 36,136, 50,150, 64,136, 14,84, 0,100, 20,100, 20,0, 0,0 };

can be obtained by (raw) offsetting to the left 1.) a square in CCR orientation 0,0 200,0 200,200, 0,200, 0,0 with offsetting value=20 2.) a shape of a simple house in CCR orientation 0,0 100,0 100,100, 50,150 0,100 0,0 with offsetting value=20

When tesselating with

1.) tessAddContour(tess, 2, &offsetSquare[0], 2 * sizeof(TESSreal), 13); t=tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_BOUNDARY_CONTOURS, 0, 2, 0);

I got as result the 16 vertices of the 4 outer squares, which all have the negative winding number (-1). The correct result are 4 vertices of the inner square with winding number (+1), the downscaled square. So the delivered result is that of the winding rule TESS_WINDING_NEGATIVE.

This is the output-result (x-,y-component): 80, 0 0 , 0 0 , 80 80 , 80 200 , 0 120 , 0 120 , 80 200 , 80 200 , 120 120 , 120 120 , 200 200 , 200 80 , 120 0 , 120 0 , 200 80, 200

2.) tessAddContour(tess, 2, &offsetHouse[0], 2 * sizeof(TESSreal), 16); t=tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_BOUNDARY_CONTOURS, 0, 2, 0);

I got correct result of 5 vertices of the region with winding number (+1), the downscaled shape of a house. The 5 regions with winding number (-1) are correctly deleted.

This is the output-result (x-, y-component): 80, 90 50 , 121 20 , 90 20 , 20 80 , 20

The fpc-libtes2 delivers the same results as your libtess2.

These are only two examples of many cases I got the correct or false results and I don't know the reason. For me it looks as if in the course of tesselation the orientation of the input polygon is changed from CW -> CCW or vice versa.

I didn't try the GLU tesselator from SGI, that seems to me too complicated with all the callbacks. So I hope you can solve my dilemma.

Udo Krix

udokrix commented 2 years ago

issue #42 solved. I misunderstood the comment "of null the normal is calculated automatically" to last parameter "normal" of the function "tessTesselate()". With my own "normal"-parameter it works as it should. "visualdoj" who ported "libtess2" to pascal gave me the solution. Thanks again Udo Krix