fabmax / physx-js-webidl

Javascript WASM bindings for Nvidia PhysX
MIT License
117 stars 27 forks source link

help on convex #9

Closed lo-th closed 2 years ago

lo-th commented 2 years ago

Hi i have problem's for convex mesh do you know how to set points in javascript ? i see you make convex in kool

and normally for set density is PhysX.PxRigidBodyExt.updateMassAndInertia( body, density, null, false ); but PxRigidBodyExt return nothing

thank's

lo-th commented 2 years ago

i have some result by forcing ConvexMeshDesc.points.data with _malloc but result is not good what difference between point.stride and points.count ?

fabmax commented 2 years ago

Convex meshes are a bit complicated to create. The PhysX documentation explains it quite well: https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/Geometry.html#convex-meshes

However in Javascript you cannot simply create an array of PxVec3 and pass that to PxConvexMeshDesc.points.data. Instead you have to create an Vector_PxVec3 with the number of points you need and then set the point coordinates somewhat like this:

var points = new PhysX.Vector_PxVec3(5);

var p = points.at(0); p.x = 0; p.y = 1; p.z = 0;
p = points.at(1); p.x = 1; p.y = 0; p.z = 0;
p = points.at(2); p.x = -1; p.y = 0; p.z = 0;
p = points.at(3); p.x = 0; p.y = 0; p.z = 1;
p = points.at(4); p.x = 0; p.y = 0; p.z = -1;

var desc = new PhysX.PxConvexMeshDesc();
desc.flags = PhysX._emscripten_enum_PxConvexFlagEnum_eCOMPUTE_CONVEX();
desc.points.count = points.size();
desc.points.stride = 12;     // sizeof(PxVec3);
desc.points.data = points.data();

var convexMesh = cooking.createConvexMesh(desc, physics.getPhysicsInsertionCallback());

edit: points.stride is the memory-size of a single point element (PxVec3) in bytes (3 floats at 4 bytes each).

lo-th commented 2 years ago

ok thank's fabmax !! now is work if my array or point is v:Float32Array stride is v.BYTES_PER_ELEMENT * 3 both methode work with Vector_PxVec3 or my _malloc convertion of v

ww1g11 commented 1 month ago

Hi @fabmax

Many thanks for creating physx-js-webidl

I am new to physx and javascript and found this example https://github.com/fabmax/physx-js-webidl/blob/main/dist/helloworld.html. I wanted to add a convex object, so I tried inserting the following code into helloworld.html:

            var points = new PhysX.Vector_PxVec3(5);
            var p = points.at(0); p.x = 0; p.y = 1; p.z = 0;
            p = points.at(1); p.x = 1; p.y = 0; p.z = 0;
            p = points.at(2); p.x = -1; p.y = 0; p.z = 0;
            p = points.at(3); p.x = 0; p.y = 0; p.z = 1;
            p = points.at(4); p.x = 0; p.y = 0; p.z = -1;

            var desc = new PhysX.PxConvexMeshDesc();
            desc.flags = PhysX._emscripten_enum_PxConvexFlagEnum_eCOMPUTE_CONVEX();
            desc.points.count = points.size();
            desc.points.stride = 12;     // sizeof(PxVec3);
            desc.points.data = points.data();

            console.log(desc);

            var cookingParams = new PhysX.PxCookingParams(PhysX.PxTolerancesScale());
            console.log('Created PxCookingParams:', cookingParams);

            var convexMesh = PhysX.CreateConvexMesh(cookingParams, desc);
            console.log(convexMesh);

            var convexShape = physics.createShape(convexMesh, material, true, shapeFlags);
            console.log(convexShape);

            tmpVec.set_y(0); tmpVec.set_z(10);
            tmpPose.set_p(tmpVec);
            var convex = physics.createRigidDynamic(tmpPose);
            convexShape.setSimulationFilterData(tmpFilterData);
            convex.attachShape(convexShape);
            scene.addActor(convex);

But I got two errors:

/src/PhysX/physx/source/geomutils/src/cooking/GuCookingQuickHullConvexHullLib.cpp (871) : internal error : QuickHullConvexHullLib::findSimplex: Simplex input points appers to be almost at the same place

/src/PhysX/physx/source/geomutils/src/GuBounds.cpp (479) : internal error : Gu::computeBounds: Unknown shape type.

I'm not sure how to resolve these issues. Do you have any suggestions? Thanks in advance.

fabmax commented 1 month ago

The points you create in the beginning appear to lie in a plane. Have you tried creating an actual volume (e.g. by adding another point with y = 1)?

ww1g11 commented 1 month ago

I have tried other points, such as a unit tetrahedron shown as follows

            var points = new PhysX.Vector_PxVec3(4);
            var p = points.at(0); p.x = 0; p.y = 0; p.z = 0;
            p = points.at(1); p.x = 1; p.y = 0; p.z = 0;
            p = points.at(2); p.x = 0; p.y = 1; p.z = 0;
            p = points.at(3); p.x = 0; p.y = 0; p.z = 1;

but got the same error, so do you have any example on creating a convex shape? I googled a lot but failed to find one.

fabmax commented 1 month ago

I'm using it in my engine here: https://github.com/fabmax/kool/blob/main/kool-physics/src/jsMain/kotlin/de/fabmax/kool/physics/geometry/ConvexMesh.js.kt

It's written in Kotlin but it translates to javascript. I'm using PxArray_PxVec3 instead of Vector_PxVec3 but that should not make a difference.

lo-th commented 1 month ago

Hi i use direct methode v = g.attributes.position.array;

let des = new PhysX.PxConvexMeshDesc();
tmpPoint = malloc( v );
des.points.stride = v.BYTES_PER_ELEMENT * 3;
des.points.count = v.length/3;
des.points.data = tmpPoint;
let flag = 0;
flag |= PhysX._emscripten_enum_PxConvexFlagEnum_eCOMPUTE_CONVEX()
flag |= PhysX._emscripten_enum_PxConvexFlagEnum_eQUANTIZE_INPUT()
flag |= PhysX._emscripten_enum_PxConvexFlagEnum_eDISABLE_MESH_VALIDATION()
let pxflags = new PhysX.PxConvexFlags( flag );
des.flags = pxflags
let tri = PhysX.PxTopLevelFunctions.prototype.CreateConvexMesh( root.cookingParams, des );
let ms = new PhysX.PxMeshScale();
let f = new PhysX.PxConvexMeshGeometryFlags();
g = new PhysX.PxConvexMeshGeometry( tri, ms, f );

const malloc = ( f, q ) => {

        const nDataBytes = f.length * f.BYTES_PER_ELEMENT;
        if( q === undefined ) q = PhysX._webidl_malloc( nDataBytes );
        let dataHeap = new Uint8Array( PhysX.HEAPU8.buffer, q, nDataBytes );
        dataHeap.set( new Uint8Array( f.buffer ) );
        return q;

    }
ww1g11 commented 1 month ago

Many thanks!

With the help of the malloc function, the unit tetrahedron also works:

let vertices = [0,0,0,1,0,0,0,1,0,0,0,1];
let v= new Float32Array(vertices);

By the way, the malloc function is similar to function getVertices at https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Physics/v2/Plugins/havokPlugin.ts