RandyGaul / cute_headers

Collection of cross-platform one-file C/C++ libraries with no dependencies, primarily used for games
4.21k stars 264 forks source link

cute_2d c2PolytoPolyManifold issue #366

Closed Xfennec closed 9 months ago

Xfennec commented 9 months ago

Hi,

First, thank for this great library, it's really helpful!

My game features cars (polys) and world "hazards" (circles and polys), and I need collision normals (cute 2D "manifolds" , if my understanding is correct) to "bounce" the car back on collision.

My issue is that I'm unable to get c2PolytoPolyManifold() to report contacts. Everything is OK with c2CircletoPoly, c2CircletoPolyManifold and c2PolytoPoly, but c2PolytoPolyManifold always report 0 contacts.

I'm probably missing something. Any idea?

    c2Poly poly_world;
    poly_world.count = 4;
    poly_world.verts[0] = c2V(-1.0, -1.0);
    poly_world.verts[1] = c2V(1.0, -1.0);
    poly_world.verts[2] = c2V(1.0, 1.0);
    poly_world.verts[3] = c2V(-1.0, 1.0);

    c2Poly poly_car;
    poly_car.count = 4;
    poly_car.verts[0] = c2V(-0.05, -1.04);
    poly_car.verts[1] = c2V(0.05, -1.04);
    poly_car.verts[2] = c2V(0.05, -0.94);
    poly_car.verts[3] = c2V(-0.05, -0.94);

    int res = c2PolytoPoly(&poly_car, NULL, &poly_world, NULL);
    printf("res: %d\n", res);

    c2Manifold m;
    c2PolytoPolyManifold(&poly_car, NULL, &poly_world, NULL, &m);
    printf("m.count: %d\n", m.count);

Result:

gcc main.c -lm && ./a.out 
res: 1
m.count: 0
RandyGaul commented 9 months ago

You'll need to get the vertices in CCW order and also set the normals for each polygon. The easiest way is to call c2MakePoly after assigning vertices in any order. So, try this:

c2Poly poly_world;
poly_world.count = 4;
poly_world.verts[0] = c2V(-1.0, -1.0);
poly_world.verts[1] = c2V(1.0, -1.0);
poly_world.verts[2] = c2V(1.0, 1.0);
poly_world.verts[3] = c2V(-1.0, 1.0);
c2MakePoly(&poly_world);

c2Poly poly_car;
poly_car.count = 4;
poly_car.verts[0] = c2V(-0.05, -1.04);
poly_car.verts[1] = c2V(0.05, -1.04);
poly_car.verts[2] = c2V(0.05, -0.94);
poly_car.verts[3] = c2V(-0.05, -0.94);
c2MakePoly(&poly_car);

int res = c2PolytoPoly(&poly_car, NULL, &poly_world, NULL);
printf("res: %d\n", res);

c2Manifold m;
c2PolytoPolyManifold(&poly_car, NULL, &poly_world, NULL, &m);
printf("m.count: %d\n", m.count);
Xfennec commented 9 months ago

Thanks, it does the trick!

May I suggest a short note about this in the doc of c2PolytoPolyManifold?

Subsidiary question: when I fix the winding "by hand", the resulting manifolds are less consistent than when I call c2MakePoly. Does this function does some other "magic" on the poly? (I would like to avoid calling it every frame for every car)