Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to triangulate a square #36

Open
L1onKing opened this issue Sep 26, 2019 · 8 comments
Open

Trying to triangulate a square #36

L1onKing opened this issue Sep 26, 2019 · 8 comments

Comments

@L1onKing
Copy link

L1onKing commented Sep 26, 2019

Hello! First of all, big shoutout for your work from Ukraine! I like the way you organised the library, but I have couple of questions.

Now, as a test assignment in order to understand quirks & features of libtess2, I decided to triangulate a simple square:

let tl = TextureVertex(x: -1.0, y: 1.0, z: 0.0, s: 0.0, t: 0.0)
let tr = TextureVertex(x:  1.0, y: 1.0, z: 0.0, s: 1.0, t: 0.0)
let br = TextureVertex(x:  1.0, y:-1.0, z: 0.0, s: 1.0, t: 1.0)
let bl = TextureVertex(x: -1.0, y:-1.0, z: 0.0, s: 0.0, t: 1.0)

TextureVertex is a simple C-based struct which I'm using in my Swift layer.

Here's how my work with libtess2 looks like:

- (NSArray<NSNumber *> *)triangulate_TextureVertex:(TextureVertex *)vertices verticesCount:(int)count
{
    tessAddContour(tesselator, 2, vertices, sizeof(TextureVertex), count);
    
    if (tessTesselate(tesselator, TESS_WINDING_POSITIVE, TESS_POLYGONS, 6, 0, 0)) {
        
        const float *verts = tessGetVertices(tesselator);
        const int *vinds = tessGetVertexIndices(tesselator);
        
        
        for (int i = 0; i < 6; i++) {
            //NSLog(@"vert = %f", verts[i]);
            NSLog(@"index = %d", vinds[i]);
        }
        
        NSLog(@"Hold!");
    }
    
    return nil;
}

That's an Objective-C method in which I wrap the work with libtess2. This way I can use your library from my Swift code.

So as you can see I have a test for-loop where I can check out proposed indices set, and I'm kind of expecting to have 6 indices, because square is made of 2 triangles which means 2 set of 3 vertex indices.

But the weird part is that in the response I have only 4 indices [2, 3, 0, 1]. Obviously that's not enough to draw a square, at least 2 indices are missing. I decided to check tessGetVertices() just to see if x and y of Vertex are grabbed properly, but it looks legit.

Also - where can I get an info about indices count? Is there a function which can do that for me?

I understand that I might made some rookie mistake and would be happy if you could point me to it. If you need any additional info from me, just let me know.

With regards,
Yevhen

@memononen
Copy link
Owner

memononen commented Sep 26, 2019 via email

@L1onKing
Copy link
Author

Thank you for your response! I double-checked API and found 2 problems in my tessTesselate call. Now I'm calling like so:

tessTesselate(tesselator, TESS_WINDING_POSITIVE, TESS_POLYGONS, count, 2, 0)

Where count is 4, because square has 4 vertices, and I added 2 instead of 0 to vertexSize, because I'm passing x,y vertices.

But my output is still the same, nothing has changed. Could you maybe point me to my mistakes?

@L1onKing
Copy link
Author

Also I tried to pass 3 instead of count (which is 4) because I figured that maybe polygons in that case are triangles which makes the whole polygon. But result is still the same (a bit different order, but 4 indices in the response)

@memononen
Copy link
Owner

memononen commented Sep 26, 2019 via email

@L1onKing
Copy link
Author

Hello! I've noted my mistakes and it seems that I had some progress. But still there's a small problem with my triangulation.

Here's my test code. I used float[] array this time just to clear out the possibility that my custom struct is somewhat a problem:

float coords[] =
    {
        -1.0, -1.0,
        1.0, -1.0,
        1.0, 1.0,
        -1.0, 1.0
    };
    
    tessAddContour(tesselator, 2, coords, sizeof(float) * 2, 4);
    NSMutableArray<NSNumber *> *indicesList = [NSMutableArray new];
    if (tessTesselate(tesselator, TESS_WINDING_ODD, TESS_POLYGONS, 3, 2, NULL)) {
        
        const TESSindex *indices = tessGetElements(tesselator);
        int indicesCount = tessGetElementCount(tesselator) * 3;
        
        for (int i = 0; i < indicesCount; i++) {
            NSLog(@"aaa = %d", indices[i]);
            [indicesList addObject:@(indices[i])];
        }
        
        NSLog(@"Hold!");
    }

No I have 6 indices and I'm very happy about it, BUT those indices are 0, 1, 2, 1, 0, 3. Unfortunately, those indices are wrong and I can only draw a square with empty triangle in it. The result is supposed to be something like 0, 1, 2, 0, 2, 3, something like that.

Also, I tried the same input with two other tesselation libraries and in both cases I got the correct output. But libtess2 supports holes so I'm highly motivated to understand what mistakes I'm making here :)

@memononen
Copy link
Owner

memononen commented Sep 27, 2019 via email

@L1onKing
Copy link
Author

I got through winding rules and I understand that those influence on the way tesselator works with vertices (clockwise, counter-clockwise, etc). I think that in my case I can use TESS_WINDING_POSITIVE or TESS_WINDING_ODD, but in both scenarios I have the same result. Also I tried to use different winding options just to roll out the possibility that I'm mistaking, but either result was the same or nothing at all (like in case with TESS_WINDING_NEGATIVE).

Thank you for mentioning that tesselator might re-arrange vertices, I didn't know that (need to read documentation better)

Just out of curiosity I decided to print vertices as well, and that's what I get with this loop

for (int i = 0, j = 0; i < indicesCount; i++, j+=2) {
NSLog(@"id = %d, x = %f, y = %f", indices[i], coords[j], coords[j + 1]);
[indicesList addObject:@(indices[i])];
}

id = 0, x = -1.000000, y = -1.000000
id = 1, x = 1.000000, y = 1.000000
id = 2, x = -1.000000, y = 1.000000
id = 1, x = 1.000000, y = -1.000000
id = 0, x = 0.000000, y = 0.000000
id = 3, x = 0.000000, y = -1115111287065940802890891264.000000

I see that tesselator adds extra vertex (0, 0) and that vertex for id 3 seems to be out of memory bounds. Each time it has random values.

Maybe it's something in my input?

Thank you for putting time to help with this issue, I really appreciate that!

@memononen
Copy link
Owner

memononen commented Sep 27, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants