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

Active Actors API bug #30

Open
ghost opened this issue Feb 28, 2024 · 3 comments
Open

Active Actors API bug #30

ghost opened this issue Feb 28, 2024 · 3 comments

Comments

@ghost
Copy link

ghost commented Feb 28, 2024

Hey, i hope you are doing well

introduction

I was looking the physx official documentation and stumbled upon the active actors API, it creates a list of rigid bodies that moved in the last iteration, it is pretty handy and provides a slight performance improvement.

https://nvidia-omniverse.github.io/PhysX/physx/5.3.1/docs/RigidBodyDynamics.html?highlight=active%20actor#active-actors

problem

When consuming the api like this.

let activeActors = PhysX.SupportFunctions.prototype.PxScene_getActiveActors(scene);

And checking if there are any active actors like this.

console.log(activeActors.size())

It always returns 0 no matter what.

reproducible example

Here is the modified example scene to reflect this bug.
I added some comments indicating changes and added a console.log for logging activeActors.size()

<!DOCTYPE html>

<head>
    <title>PhysX Test</title>
    <style>
        html,
        body,
        canvas {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
        }

        canvas {
            display: block;
        }
    </style>
</head>

<body>
    <canvas></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/3.4.2/gl-matrix-min.js"
        integrity="sha512-eV9ExyTa3b+YHr99IBTYpwk4wbgDMDlfW8uTxhywO8dWb810fGUSKDgHhEv1fAqmJT4jyYnt1iWWMW4FRxeQOQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="physx-js-webidl.js"></script>
    <script>
        PhysX().then(function (PhysX) {
            var version = PhysX.PHYSICS_VERSION;

            var allocator = new PhysX.PxDefaultAllocator();
            var errorCb = new PhysX.PxDefaultErrorCallback();
            var foundation = PhysX.CreateFoundation(version, allocator, errorCb);

            var tolerances = new PhysX.PxTolerancesScale();
            var physics = PhysX.CreatePhysics(version, foundation, tolerances);

            var tmpVec = new PhysX.PxVec3(0, -9.81, 0);
            var sceneDesc = new PhysX.PxSceneDesc(tolerances);
            sceneDesc.set_gravity(tmpVec);
            sceneDesc.set_cpuDispatcher(PhysX.DefaultCpuDispatcherCreate(0));
            sceneDesc.set_filterShader(PhysX.DefaultFilterShader());
            var scene = physics.createScene(sceneDesc);

            ///////////////////////// set flag ///////////////////////////////
            scene.setFlag(PhysX.PxSceneFlagEnum.ENABLE_ACTIVE_ACTORS, true)
            ///////////////////////// set flag ///////////////////////////////

            var material = physics.createMaterial(0.5, 0.5, 0.5);
            var shapeFlags = new PhysX.PxShapeFlags(PhysX.PxShapeFlagEnum.eSCENE_QUERY_SHAPE | PhysX.PxShapeFlagEnum.eSIMULATION_SHAPE | PhysX.PxShapeFlagEnum.eVISUALIZATION);

            var tmpPose = new PhysX.PxTransform(PhysX.PxIDENTITYEnum.PxIdentity);
            var tmpFilterData = new PhysX.PxFilterData(1, 1, 0, 0);

            var groundGeometry = new PhysX.PxBoxGeometry(10, 0.5, 10);
            var groundShape = physics.createShape(groundGeometry, material, true, shapeFlags);
            var ground = physics.createRigidStatic(tmpPose);
            groundShape.setSimulationFilterData(tmpFilterData);
            ground.attachShape(groundShape);
            scene.addActor(ground);

            var boxGeometry = new PhysX.PxBoxGeometry(0.5, 0.5, 0.5);
            var lastBox = null;
            for (var y = 0; y < 10; y++) {
                tmpVec.set_x(0); tmpVec.set_y(y * 2 + 5); tmpVec.set_z(0);
                tmpPose.set_p(tmpVec);
                var boxShape = physics.createShape(boxGeometry, material, true, shapeFlags);
                var box = physics.createRigidDynamic(tmpPose);
                boxShape.setSimulationFilterData(tmpFilterData);
                box.attachShape(boxShape);
                scene.addActor(box);
                lastBox = box;
            }

            PhysX.destroy(groundGeometry);
            PhysX.destroy(boxGeometry);
            PhysX.destroy(tmpFilterData);
            PhysX.destroy(tmpPose);
            PhysX.destroy(tmpVec);
            PhysX.destroy(shapeFlags);
            PhysX.destroy(sceneDesc);
            PhysX.destroy(tolerances);

            const {mat4, vec4, vec3} = glMatrix;
            const viewMatrix = mat4.create();
            const projectionMatrix = mat4.create();
            const viewProjectionMatrix = mat4.create();
            const tmpVec4 = vec4.create();

            const canvas = document.querySelector('canvas');
            const context = canvas.getContext('2d');
            setupDebugDrawer(PhysX, scene);

            simulationLoop();

            function setupDebugDrawer() {
                canvas.width = canvas.clientWidth;
                canvas.height = canvas.clientHeight;

                mat4.lookAt(viewMatrix, [12, 15, 20], [0, 0, 0], [0, 1, 0])
                mat4.perspective(projectionMatrix, 45 * (Math.PI / 180), canvas.width / canvas.height, 0.01, 75);
                mat4.multiply(viewProjectionMatrix, projectionMatrix, viewMatrix);

                const context = canvas.getContext('2d');
                scene.setVisualizationParameter(PhysX.eSCALE, 1);
                scene.setVisualizationParameter(PhysX.eWORLD_AXES, 1);
                scene.setVisualizationParameter(PhysX.eACTOR_AXES, 1);
                scene.setVisualizationParameter(PhysX.eCOLLISION_SHAPES, 1);
            }

            ///////////// check if there are active actors ///////////////
            function logActiveActors() {
                let activeActors = PhysX.SupportFunctions.prototype.PxScene_getActiveActors(scene);
                console.log(activeActors.size())
            }
            ///////////// check if there are active actors ///////////////

            function simulationLoop() {
                let lastFrame = 0;
                requestAnimationFrame(function loop(hrTime) {
                    var timeStep = Math.min(0.03, (hrTime - lastFrame) / 1000);
                    scene.simulate(timeStep);
                    scene.fetchResults(true);

                    /////////// log active actors /////////////
                    logActiveActors()
                    /////////// log active actors /////////////

                    debugDraw(scene);

                    var lastBoxPos = lastBox.getGlobalPose().get_p();

                    lastFrame = hrTime;
                    requestAnimationFrame(loop);
                });
            }

            function project(x, y, z) {
                const result = vec4.transformMat4(tmpVec4, [x, y, z, 1], viewProjectionMatrix);
                const clipX = (result[0] / result[3]);
                const clipY = (result[1] / result[3]);
                return [(canvas.width / 2) * (1 + clipX), (canvas.height / 2) * (1 - clipY)];
            }

            function drawLine(from, to, color) {
                const [r, g, b] = color;

                context.beginPath();
                context.strokeStyle = `rgb(${255 * r}, ${255 * g}, ${255 * b})`;
                context.moveTo(...from);
                context.lineTo(...to);
                context.stroke();
            }

            function debugDraw() {
                canvas.width = canvas.width;
                const rb = scene.getRenderBuffer();
                for (let i = 0; i < rb.getNbLines(); i++) {
                    const line = PhysX.NativeArrayHelpers.prototype.getDebugLineAt(rb.getLines(), i);
                    const from = project(line.pos0.get_x(), line.pos0.get_y(), line.pos0.get_z());
                    const to = project(line.pos1.get_x(), line.pos1.get_y(), line.pos1.get_z());
                    drawLine(from, to, colors[line.get_color0()]);
                }
            }

            const colors = {
                [PhysX.PxDebugColorEnum.eARGB_BLACK]: [0, 0, 0],
                [PhysX.PxDebugColorEnum.eARGB_RED]: [1, 0, 0],
                [PhysX.PxDebugColorEnum.eARGB_GREEN]: [0, 1, 0],
                [PhysX.PxDebugColorEnum.eARGB_BLUE]: [0, 0, 1],
                [PhysX.PxDebugColorEnum.eARGB_YELLOW]: [1, 1, 0],
                [PhysX.PxDebugColorEnum.eARGB_MAGENTA]: [1, 0, 1],
                [PhysX.PxDebugColorEnum.eARGB_CYAN]: [0, 1, 1],
                [PhysX.PxDebugColorEnum.eARGB_WHITE]: [1, 1, 1],
                [PhysX.PxDebugColorEnum.eARGB_GREY]: [0.5, 0.5, 0.5],
                [PhysX.PxDebugColorEnum.eARGB_DARKRED]: [0.5, 0, 0],
                [PhysX.PxDebugColorEnum.eARGB_DARKGREEN]: [0, 0.5, 0],
                [PhysX.PxDebugColorEnum.eARGB_DARKBLUE]: [0, 0, 0.5],
            };
        });
    </script>
</body>

</html>

@fabmax
Copy link
Owner

fabmax commented Feb 29, 2024

You made a typo 😄

PhysX enum values are prefixed with a lower case 'e'. It has to be eENABLE_ACTIVE_ACTORS instead of ENABLE_ACTIVE_ACTORS:

scene.setFlag(PhysX.PxSceneFlagEnum.eENABLE_ACTIVE_ACTORS, true)

It's a bit odd that this is not an error. I assume the wasm runtime simply treats the undefined as a 0 and sets some other flag instead.

@ghost
Copy link
Author

ghost commented Feb 29, 2024

we have some faulty typescript types, here is the declaration in the physx-js-webidl.wasm.d.ts file.

enum PxSceneFlagEnum {
        'ENABLE_ACTIVE_ACTORS',
        [...]
}

and faulty me, should have researched a little bit more.

Thanks again for responding to my question, have a great day!

@fabmax
Copy link
Owner

fabmax commented Mar 1, 2024

Did you generate the typescript bindings with the method given in the README.md?

The script isn't mine and I don't have any typescript experience at all, so unfortunately I won't be able to fix this 😃

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

1 participant