fabmax / physx-jni

Java JNI bindings for Nvidia PhysX
MIT License
89 stars 9 forks source link

Creating a heightfield #74

Open ItsFlare opened 2 weeks ago

ItsFlare commented 2 weeks ago

Hi, first of all thank you for creating & maintaining this project <3

I'm struggling to create a heightfield, would be great if an example was provided somewhere. Stumbled upon an old related issue (#41) with some Kotlin code, however that uses cooking and is since outdated (uses Vector_PxHeightFieldSample)

Current attempt below - see comments. Any help is appreciated!

try (MemoryStack mem = MemoryStack.stackPush()) {
    PxMaterial material = physics.createMaterial(0.5f, 0.5f, 0.5f);

    PxTransform identityPose = PxTransform.createAt(mem, MemoryStack::nmalloc, PxIDENTITYEnum.PxIdentity);
    this.actor = physics.createRigidStatic(identityPose);

    final int size = 1000;
    PxArray_PxHeightFieldSample samples = PxArray_PxHeightFieldSample.createAt(mem, MemoryStack::nmalloc, size * size);
    PxHeightFieldSample sample = new PxHeightFieldSample();
    for (int x = 0; x < size; x++) {
        for (int z = 0; z < size; z++) {
            sample.setHeight((short) ((Math.sin(x + z) + 1) * 20));
            samples.set(x * size + z, sample);
        }
    }
    sample.destroy();

    //How to properly instantiate PxStridedData?
    PxStridedData stridedData = PxStridedData.wrapPointer(samples.getAddress());
    stridedData.setData(samples);
    stridedData.setStride(2);

    PxHeightFieldDesc heightFieldDesc = PxHeightFieldDesc.createAt(mem, MemoryStack::nmalloc);
    heightFieldDesc.setFormat(PxHeightFieldFormatEnum.eS16_TM);
    heightFieldDesc.setNbColumns(size);
    heightFieldDesc.setNbRows(size);
    heightFieldDesc.setSamples(stridedData);
    heightFieldDesc.setFlags(PxHeightFieldFlags.createAt(mem, MemoryStack::nmalloc, (short) 0));

    //CreateHeightField returns null :(
    PxHeightField heightField = PxTopLevelFunctions.CreateHeightField(heightFieldDesc);
    PxHeightFieldGeometry heightFieldGeometry = PxHeightFieldGeometry.createAt(mem, MemoryStack::nmalloc);
    heightFieldGeometry.setColumnScale(1);
    heightFieldGeometry.setRowScale(1);
    heightFieldGeometry.setHeightScale(1);
    heightFieldGeometry.setHeightField(heightField);

    PxMeshGeometryFlags meshGeometryFlags = PxMeshGeometryFlags.createAt(mem, MemoryStack::nmalloc, (byte) 0);
    heightFieldGeometry.setHeightFieldFlags(meshGeometryFlags);

    PxShapeFlags shapeFlags = new PxShapeFlags((byte) (PxShapeFlagEnum.eSCENE_QUERY_SHAPE.value | PxShapeFlagEnum.eSIMULATION_SHAPE.value));
    this.shape = PxRigidActorExt.createExclusiveShape(actor, heightFieldGeometry, material, shapeFlags);

    //Are these all fine to destroy or are they referenced in native memory?
    shapeFlags.destroy();
    material.release();
    samples.destroy();
    stridedData.destroy();
    heightFieldDesc.destroy();
}