Multimaterial Mesh question

AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Multimaterial Mesh question

Post by AlexSilverman »

Hello,

I'm working on a multimaterial triangle mesh shape to give Bullet users a simple interface into the per triangle material system, and I've run into a problem. I chose to model the interface (at the start anyway) after the way one creates a btBvhTriangleMeshShape, so I created a btTriangleIndexVertexMaterialArray and btBvhTriangleMaterialMeshShape to hold and access an array of material information (which could probably be changed to a structure to allow users to expand it themselves, although this may not be necessary). Currently, a material consists of just friction and restitution data, and it all works fine, if a bit hacked togehter.

My problem is that the material data would (ideally) need to be accessed in btManifoldResult::AddContactPoint(), where the friction and restitution values are set, but by this point, the mesh has had its original collision shape replaced by the shape of the single triangle that is colliding. Right now I'm getting around this by setting the user pointer of the temporary shape to point to the original shape, but this is obviously not the best solution, as the user now has to go through another accessor to get to their data. Is there any other way to access the original shape of the body at this point, or alternatively, is there another point at which I should be changing the friction/restitution values?

Once this is taken care of, I can work on adding another interface to function something more like vicviper describes in this post.

Thanks.

- Alex
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Multimaterial Mesh question

Post by Erwin Coumans »

It sounds like the easiest way without modifying the Bullet source code is to support multi-material triangle meshes is using the partID: split the mesh (indices) in parts that have the same material, and create a sub part for each. Both partID and triangleId get propagated to the CustomMaterialCombinerCallback, so you can override the friction and restitution values (set by btManifoldResult::AddContactPoint).

Hope this helps,
Erwin
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Erwin,

Thanks for the reply. Sorry I'm slow in getting back to this.

Unfortunately, if I do the manipulation in the CustomMaterialCombinerCallback, I still do not have access to the original shape (the one that holds the index, vertex, and material data), as it's been replaced by the single triangle that's currently colliding.

I'm only still concerned with this because I see it as being beneficial to the rest of the community so I was trying to get it as cleanly integrated with Bullet as possible, instead of just getting it working in my own engine framework. If you disagree, for whatever reason, then I'll be content to let it go, as it's working satisfactorily for my purposes, in its patched together state :)

Thanks.

- Alex
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Multimaterial Mesh question

Post by Erwin Coumans »

AlexSilverman wrote:Unfortunately, if I do the manipulation in the CustomMaterialCombinerCallback, I still do not have access to the original shape (the one that holds the index, vertex, and material data), as it's been replaced by the single triangle that's currently colliding.
If we somehow manage to provide this 'root' shape into the CustomMaterialCombinerCallback, would that solve your problem?
Thanks for the discussion,
Erwin
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Yes. It would indeed. Having access to the original shape that the body was created with would solve it.

Thanks for following up.
- Alex
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Multimaterial Mesh question

Post by Erwin Coumans »

Good point. Ok, we will add it to the todo list:

You can track progress (or lack thereoff, because we are busy with other development) here:
http://code.google.com/p/bullet/issues/detail?id=50

Thanks,
Erwin
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Great. Thanks a lot.

- Alex
voxel
Posts: 14
Joined: Fri Jul 04, 2008 2:23 pm

Re: Multimaterial Mesh question

Post by voxel »

I'm wondering about the status of this and any temp workarounds?

I want to be able to have per-triangle properties (attached somehow to the collision mesh) and access this data in the from callback.

Is my current solution to use the index0 / index1 and iterate through the trimesh? I believe I may need to extend the btTriangleMesh class to hold extra data OR build a separate data structure to hold the per-triangle (or per-vertex) data.
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Hi voxel,

I had need of this in a project I'm currently working on, so I just implemented the parts I needed. Here's a possibly non-comprehensive list, as I'm not at work currently so I might be forgetting something.

For Issue 50, I added an owner pointer to the btTriangleShape as well as the necessary get/set methods. When the triangle shape is created as part of the mesh collision algorithm, I set the owner to the mesh. This way, you have access to the mesh that the triangle belongs to inside the ContactAddedCallback.

For the multimaterial problem, I extended the btIndexVertexArray (I believe that's the name) and created my own btIndexVertexMaterialArray, which, as you may guess, holds material data as well (on a per triangle basis). I then created a new shape, btMultimaterialTriangleMeshShape, which is built off of the data in the btIndexVertexMaterialArray (borrowing liberally from btBvhTriangleMeshShape). After that, the only thing left to do was change the contact properties in the ContactAddedCallback, based on the materials.

I can submit any or all of this to the community. I hadn't submitted my solution for Issue 50 simply because I wasn't sure if that would be the preferred method for fixing it. As for the whole material thing, I hadn't submitted that for at least several reasons, which perhaps Erwin can help answer.

1) It's more of a feature than a fix, and I wasn't sure about the process for adding features to the library.
2) I wasn't sure if the per-triangle material feature (as it currently stands in the Bullet distribution) was the intended endpoint for internal development, and any work to utilize it would be left to the developers using Bullet.
3) There are optimizations that could be done to my implementation (adding the triangle data to the mesh in groups instead of all at once, so that rather than each triangle knowing which material it uses, each group would know, thus saving space) that I haven't had time to do yet, being in the middle of a project and all :)

That said, if anyone has an interest in getting their mitts on this stuff, just let me know. Unfortunately it'll have to wait until Monday when I'm back in the office, but I'll put it on my list.

Hope this helps.

- Alex
voxel
Posts: 14
Joined: Fri Jul 04, 2008 2:23 pm

Re: Multimaterial Mesh question

Post by voxel »

Yes, I'd be very interested in getting access to this and to be the guinea pig. I thought about two ways about going about the assigning extra physics data to triangles.

1) Per-vertex data (ala vertex colour) - easiest.
2) Using the UV (or UVW) to access a texture map - most flexible, but collision meshes are rarely UV mapped.
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Great. I'll take some time on Monday to put together the files necessary, and maybe even some instructions. We'll see how that goes :wink:

As for how to store the material data, it's largely a personal preference, as I see it. There are costs and benefits associated with each method. Perhaps this is a motivation for leaving the implementation out of the library itself, assuming that was the intent.

I chose to have an array of material data, and give each face an index into that array. I'll try to write up a bit more of a complete summary of what I did when I post the package on Monday.

- Alex
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

My apologies for being later posting this than I had hoped but here it is.

I organized this so that it can be extracted to the Bullet directory, and everything goes where it needs to. A few things to note...

1 - This was built against the Bullet repository. If you're not using that, you need to integrate the fix from issue 53 in the Google Code issue database. Bullet 2.70 will have this fix integrated.
2 - The demo that shows the added functionality is ConcavePhysicsDemo, which will be overwritten upon extraction, so beware :)

A rough list of changes is as follows
  • Added a parent pointer to the triangle shape (src\BulletCollision\CollisionShapes\btTriangleShape.h)
  • Assign the parent shape to the newly created triangle shape as part of the Convex Concave collision algorithm (src\BulletCollision\CollisionDispatch\btConvexConcaveCollisionAlgorithm.cpp)
  • Added a Multimaterial Triangle Mesh Shape, based on the BvhTriangleMeshShape (src\BulletCollision\CollisionShapes\btMultimaterialTriangleMeshShape.(h/cpp))
  • Added a Index/Vertex/Material array structure, based on the Index/Vertex array structure (src\BulletCollision\CollisionShapes\btTriangleIndexVertexMaterialArray.(h/cpp))
  • Added the new multimaterial mesh shape to the list of proxys (src\BulletCollision\BroadphaseCollision\btBroadphaseProxy.h)
I tried to add some explanation in the demo code, so hopefully it explains itself, but if there are any questions or comments, I'm around.

Enjoy, and any feedback is welcome.

- Alex
Attachments
MultimaterialPackage.7z
(10.84 KiB) Downloaded 310 times
Last edited by AlexSilverman on Wed Jul 09, 2008 11:40 am, edited 2 times in total.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Multimaterial Mesh question

Post by Erwin Coumans »

Hi Alex,

Nice work, we'll check it out and try to integrate it into the upcoming Bullet 2.70 release.

Thanks for the contribution.
Erwin
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Multimaterial Mesh question

Post by AlexSilverman »

Hi Erwin,

That's great. Thanks for taking a look. One thing to note is that this package includes a fix for issue 50 in the Google database. I can submit this fix through Google if it'll help keep things organized. Let me know if there are any changes you'd like me to make to any part of this.

- Alex
voxel
Posts: 14
Joined: Fri Jul 04, 2008 2:23 pm

Re: Multimaterial Mesh question

Post by voxel »

AlexSilverman wrote:I tried to add some explanation in the demo code, so hopefully it explains itself, but if there are any questions or comments, I'm around.

Enjoy, and any feedback is welcome.

- Alex
The demo makes sense - you've padded a btMaterial to a custom VertexArray and MeshShape class which IMO is the best long-term choice.
  • Now, your btMaterial is in the btMultimaterialTriangleMeshShape.h header file. I'm wondering if templating btMultimaterialTriangleMeshShape would be a better solution for those who will have custom btMaterials.

    I know BULLET seems to avoid templated shape classes, but I dislike the type-unsafe btScalar* returned by getMaterialProperties(). I also understand BULLET generally doesn't mind return raw pointers to buffers :)
  • If I wanted to "space-saving" version of material assignment where I avoid per-triangle material data and only have an index to a material, I should be able to make a btMaterial with a single integer, subclass btMultimaterialTriangleMeshShape and override getMaterialProperties() - right?

    btIndexMaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex) would use the material index to get the material in the shape and return the proper values;
Post Reply