Lusito / box2d.ts

Full blown Box2D Ecosystem for the web, written in TypeScript
https://lusito.github.io/box2d.ts
60 stars 6 forks source link

[Solved] `DrawSolidPolygon` gets wrong collider position #35

Closed 8Observer8 closed 1 year ago

8Observer8 commented 1 year ago

box2d-core 0.10.0 JavaScript

DrawSolidPolygon gets wrong collider position: https://plnkr.co/edit/GU2srU06SAzySUg6

image

I try to set collider position in main.js here:

    const groundBody = world.CreateBody({ type: b2BodyType.b2_staticBody,
        position: { x: groundPosition[0] / pixelsPerMeter,
        y: groundPosition[1] / pixelsPerMeter}});

But I have wrong line positions in debug-drawer.js:

    DrawSolidPolygon(vertices, vertexCount, color) {
        // console.log(vertices);
        // console.log(color);
        mat4.mul(this.projViewMatrix, this.projMatrix, this.viewMatrix);
        gl.uniform3f(this.uColorLocation, color.r, color.g, color.b);
        this.drawLine(vertices[0], vertices[1]);
        this.drawLine(vertices[1], vertices[2]);
        this.drawLine(vertices[2], vertices[3]);
        this.drawLine(vertices[3], vertices[0]);
    }

I ported this example to box2d-wasm v7.0.0 and it works fine: https://plnkr.co/edit/exqhktfXnvxwtBRq

debug-drawer-box2dwasm-js

Lusito commented 1 year ago

Are you aware of PushTransform/PopTransform within the b2Draw interface? PushTransform(xf:

The vertices might not be in their final position. You need to take the transforms into account

8Observer8 commented 1 year ago

I added console.log(xf) here:

    PushTransform(xf) {
        console.log(xf);
    }

I see the offset: image

I create a new vector in the constructor:

    constructor(program, pixelsPerMeter) {
        /* ... */
        this.xf = vec3.create();
    }

I load an offset vector before drawing:

    PushTransform(xf) {
        this.xf[0] = xf.p.x * this.pixelsPerMeter;
        this.xf[1] = xf.p.y * this.pixelsPerMeter;
    }

I apply the offset before drawing:

vec3.add(this.position, this.position, this.xf);

And it works: https://plnkr.co/edit/GU2srU06SAzySUg6

image

Thank you very much!

P.S. As you can see, I'm drawing the colliders behind the object:

function draw() {
    gl.clear(gl.COLOR_BUFFER_BIT);

    DrawShapes(debugDrawer, world);

    mat4.fromTranslation(modelMatrix, groundPosition);
    mat4.rotateZ(modelMatrix, modelMatrix, 0);
    mat4.scale(modelMatrix, modelMatrix, groundSize);
    mat4.mul(mvpMatrix, projViewMatrix, modelMatrix);
    gl.uniformMatrix4fv(uMvpMatrixLocation, false, mvpMatrix);
    gl.uniform3fv(uColorLocation, groundColor);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

because in this case I can see the boundaries of the object. If the colliders are drawn on top of the object, it looks bad in this example:

function draw() {
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Ground
    mat4.fromTranslation(modelMatrix, groundPosition);
    mat4.rotateZ(modelMatrix, modelMatrix, 0);
    mat4.scale(modelMatrix, modelMatrix, groundSize);
    mat4.mul(mvpMatrix, projViewMatrix, modelMatrix);
    gl.uniformMatrix4fv(uMvpMatrixLocation, false, mvpMatrix);
    gl.uniform3fv(uColorLocation, groundColor);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

    DrawShapes(debugDrawer, world);
}

image

Lusito commented 1 year ago

Just so you know, the transformation is not just a positional offset, but also a rotation. If that doesn't matter for your example, fine. Otherwise you will end up with drawing issues when your bodies start rotating.

8Observer8 commented 1 year ago

the transformation is not just a positional offset, but also a rotation

I see the problem. I'll try to fix it by myself. If I can't, I'll create an issue.

debug-drawer-box2dcore-webgl-js-collider-rotation-problem

8Observer8 commented 1 year ago

I tried to use quat.rotateZ(this.rotation, this.rotation, this.radianOffset); from glMatrix: https://glmatrix.net/docs/mat4.js.html#line827 and got this cool effect:

debug-drawer-box2dcore-webgl-js-first-trying-to-fix-a-rotation-problem

8Observer8 commented 1 year ago

Rotation problem with box2d-core and WebGL: https://github.com/Lusito/box2d.ts/issues/36