InteractiveComputerGraphics / PositionBasedDynamics

PositionBasedDynamics is a library for the physically-based simulation of rigid bodies, deformable solids and fluids.
MIT License
1.89k stars 358 forks source link

Collision detection problem #132

Closed bztsrc closed 2 years ago

bztsrc commented 2 years ago

Hi,

I'm looking at the examples in the Demos/DistanceFieldDemos directory. I've added a spike to the torus, and checked how the simulation reacts to that.

  1. RigidBodyCollisionDemo worked as it should (rigid body - plane collision)
  2. the other two, ClothCollisionDemo and DeformableCollisionDemo not so much (disregarded the actual shape, calculating incorrect collisions, as if the spike wasn't there.)

Here's a screenshot of these three. On the first two images, you can see the problem. On the last one, you can see rigid-body demo worked as expected. pbd_disterror

My question is, is this a bug in the library or is this a bug in the demos? If it's in the demo (which I believe is more likely), then how should one set up a soft-body (cloth) rigid-body mesh collision?

To be clear, I would like to replicate the red cloth over Stanford dragon example in your paper. This one: pbd_expected

Is the source to this available? I'd like to take a look at it, because I'm unable to figure it out how to do a cloth-mesh collision with your library. (I have just modified the torus as a first step, I'd like to replace it with another mesh eventually. The goal is to load different triangle meshes in run-time, so repeating the simulation with different meshes without recompilation).

Thanks, bzt

janbender commented 2 years ago

This is probably a problem of the scene setup. Can you please post the scene files?

bztsrc commented 2 years ago

This is probably a problem of the scene setup. Can you please post the scene files?

Haven't used any scene files. I'm just running the demos provided in the repo, in the Demos/DistanceFieldDemos directory. The one and only thing I've modified is the wavefront file, I've added a spike to it by modifying the second column of the vertex list for the first 5 vertexes.

bin/resources/models/torus.obj:

- v 0.475529 0.000000 -0.154509
- v 0.404509 0.000000 -0.293893
- v 0.293893 0.000000 -0.404509
- v 0.154509 0.000000 -0.475529
- v 0.000000 0.000000 -0.500000
+ v 0.475529 1.000000 -0.154509
+ v 0.404509 1.000000 -0.293893
+ v 0.293893 1.000000 -0.404509
+ v 0.154509 1.000000 -0.475529
+ v 0.000000 1.000000 -0.500000

I haven't changed anything else, and just executed bin/ClothCollisionDemo, bin/DeformableCollisionDemo, and bin/RigidBodyCollisionDemo.

Cheers, bzt

janbender commented 2 years ago

These demos use a torus signed distance function and the geometry is just used for rendering. If you want to use an arbitrary mesh as collision object, you must set the collision object type accordingly. The easiest way to test this, is to set up a scene file.

bztsrc commented 2 years ago

Thanks, just as I thought.

If it's in the demo (which I believe is more likely), then how should one set up a soft-body (cloth) rigid-body mesh collision?

So this is the question.

The easiest way to test this, is to set up a scene file.

No thanks, I'm only interested in the API. If the ClothCollisionDemo uses addCollisionTorus, then what API should I call to get a mesh collision object? I've looked it in DistanceFieldCollisionDetection.h.

        void addCollisionBox(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Vector3r &box, const bool testMesh = true, const bool invertSDF = false);
        void addCollisionSphere(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Real radius, const bool testMesh = true, const bool invertSDF = false);
        void addCollisionTorus(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Vector2r &radii, const bool testMesh = true, const bool invertSDF = false);
        void addCollisionObjectWithoutGeometry(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const bool testMesh);
        void addCollisionHollowSphere(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Real radius, const Real thickness, const bool testMesh = true, const bool invertSDF = false);
        void addCollisionHollowBox(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Vector3r &box, const Real thickness, const bool testMesh = true, const bool invertSDF = false);
        void addCollisionCylinder(const unsigned int bodyIndex, const unsigned int bodyType, const Vector3r *vertices, const unsigned int numVertices, const Vector2r &dim, const bool testMesh = true, const bool invertSDF = false);

There seems to be no addCollisionMesh. So, how does one set up a mesh collision with this library?

Thanks, bzt

janbender commented 2 years ago

Indeed the required function is still missing. I will put it on my to-do list.

You have to generate an SDF as it is done in the SceneLoaderDemo in line 513 and following:

https://github.com/InteractiveComputerGraphics/PositionBasedDynamics/blob/136469f03f7869666d907ea8d27872b098715f4a/Demos/SceneLoaderDemo/SceneLoaderDemo.cpp#L513

bztsrc commented 2 years ago

Thank you very much for your answers!

Indeed the required function is still missing. I will put it on my to-do list.

That would be awesome, I'm waiting for that! In the meantime I'll take a look at how SceneLoaderDemo does it.

You have to generate an SDF as it is done in the SceneLoaderDemo in line 513 and following:

For the records, I've tried with scene too, same results. I've used the provided cloth scene ClothCollisionScene.json.

It didn't work, same issue as with the previous demo (obviously, it uses a torus collision). Then I've changed the collision type to SDF, and it got even worse: the cloth simply fall through the torus. (I haven't changed the physics parameters in the scene, only some coordinates to move the sphere out of the way.)

Here's the result (on the left, with the original collision type 4, and on the right, with SDF, 5): pbd_errscene

Here's the scene file (for the scene on the right with SDF). What am I doing wrong? ClothCollisionScene.json.gz

Thank you for your answers, bzt

bztsrc commented 2 years ago

Ok, reading through the source, I've figured one has to set a collision mesh too explicitly, setting the geometry alone is not enough. So I've added

            "collisionObjectType": 5,
+           "collisionObjectFileName": "../models/torus.obj",

but this resulted in a run-time error:

Load SDF: /home/bzt/Documents/sources/PositionBasedDynamics/bin/resources/models/torus.obj
terminate called after throwing an instance of 'std::length_error'
  what():  vector::_M_default_append
Aborted (core dumped)

Now I'm stuck. Sorry that I'm so presistent about this, but I'm really interested in integrating rigid bodies with attached cloth-like soft bodies into my project, and so far this library seems to be the best candidate doing that by far.

And I've checked lots of FOSS physics engines... really lots. This one is simple to use and fast. The second candidate is mujoco, but it has serious issues to solve (for example, it does not have a documented API, just the XML interface, it cannot handle adding/removing objects, and it's not PBD, so has lot worse performance and may not reach stability at all).

Cheers, bzt

janbender commented 2 years ago

Are you sure the path to the file is correct?

bztsrc commented 2 years ago

Are you sure the path to the file is correct?

Yes, I'm sure. It's the same as in geometryFile, and there's no problem loading that. Besides, if it were a path specification issue, then the error message would be

ERROR: Discrete grid can not be loaded. Input file does not exist!

(I've more than 30 years of programming experience, I wouldn't waste your time on such a trivial issue :-) Here are some of my projects, you can see I am not a novice. I usually solve problems on my own, I very rarely ask. So when I do, that means I'm really truly stuck.)

BTW, if it's not too much trouble for you, could you please add a scene file with a cloth falling on a rigid triangle mesh to the repo? I could then just study that and then I wouldn't have to bother you with my stupid questions. And I'm sure it would be very beneficial to others too who come after me.

Cheers, bzt

janbender commented 2 years ago

I will add an example next week. Unfortunately, I don't have enough time for documenting everything. But I think I can add some more scene files.

Am 14. August 2022 11:34:55 MESZ schrieb Zoltan Baldaszti @.***>:

Are you sure the path to the file is correct?

Yes, I'm sure. It's the same as in geometryFile, and there's no problem loading that. Besides, if it were a path specification issue, then the error message would be

ERROR: Discrete grid can not be loaded. Input file does not exist!

(I've more than 30 years of programming experience, I wouldn't waste your time on such a trivial issue :-) Here are some of my projects, you can see I am not a novice. I usually solve problems on my own, I very rarely ask. So when I do, that means I'm really truly stuck.)

BTW, if it's not too much trouble for you, could you please add a scene file with a cloth falling on a rigid triangle mesh to the repo? I could then just study that and then I wouldn't have to bother you with my stupid questions. And I'm sure it would be very beneficial to others too who come after me.

Cheers, bzt

-- Reply to this email directly or view it on GitHub: https://github.com/InteractiveComputerGraphics/PositionBasedDynamics/issues/132#issuecomment-1214321042 You are receiving this because you commented.

Message ID: @.***>

janbender commented 2 years ago

I just added the scene file ClothOnBunny.json, where I also added a comment. You have to set "collisionObjectType" to 5 (SDF). Then you can either set "collisionObjectFileName" to a path of a precomputed SDF file or let it empty. If it is empty, the simulator will generate an SDF using the mesh in "geometryFile". Keep in mind that using a low "resolutionSDF" can also lead to penetrations.

bztsrc commented 2 years ago

I just added the scene file ClothOnBunny.json

That's just perfect, thank you very much!

If it is empty, the simulator will generate an SDF using the mesh in "geometryFile".

That's what I was expecting, but didn't work. So I assume this has been fixed too, perfect!

Keep in mind that using a low "resolutionSDF" can also lead to penetrations.

I'm aware. The low-res mesh must include all the high-res vertexes and their edges.

Thank you! bzt