Question (and bug fix) regarding collision pairs and GImpact

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

Question (and bug fix) regarding collision pairs and GImpact

Post by AlexSilverman »

Hello,

I was wondering what governs when an object is the first or second collision object in a collision pair? I ask because I've found a small bug in GImpact that only occurs when the GImpact shape is the second collision object. Somehow I had this happening all the time in my game code, and when I transplanted my mesh loading code into the Bullet demo suite, it was just as regular. However, when I tried to make a very simple test case out of the GImpactTestDemo, it never happened. I got around this to create a test case by using a custom near callback to explicitly place the GImpact shape as the second collision object, but I still don't know why it never happened naturally.

In any case, the attached cpp file will exhibit the behavior. It sets up a btBoxShape ground plane and one torus GImpact shape that drops on it. The customNearCallback explicitly places the GImpact shape as the second collision object (argument #2 to processCollision), and it can be seen that inside the ContactAddedCallback (named CustomMaterialCombinerCallback) the partId and index are incorrect. I found that this was due to how swapping the collision objects is done internally to GImpact. The attached patch fixes this behavior by adding an additional check before the triangle index is assigned. What follows is a discussion/explanation of what's going on internally to GImpact (as I understand it). Feel free to skip over it if you're not interested. Perhaps Francisco can shed some light on anything I misinterpreted.

<GImpact discussion>
If the GImpact shape is passed in as collision object 1, then no swapping occurs. If it is collision object 2 however, the two are swapped, for the period in which the narrowphase collision detection is done, and then they are swapped back when the ContactAddedCallback is called, with the effect that the two objects are passed to the ContactAddedCallback in the same order as they appear in the contact pair. For example, if a collision pair has BoxA as proxy 0 and TorusA as proxy 1, the nearcallback will pass them to the GImpact collision algorithm, which will swap them when they are passed to the gimpact_vs_shape method for more narrowphase collision detection. They are left in this order (with TorusA being object 0) until the time comes to call the ContactAddedCallback, at which point they are swapped again (to the order in which they appear in the contact pair, BoxA being object 0 and TorusA being object 1) before calling that function. I don't know what the reason is for this second swap, but the system works, save for one line. In line 654 of btGImpactCollisionAlgorithm.cpp, m_triface0 is assigned the index, which effectively assumes that the objects are not swapped, and that the GImpact shape will be object 0 in the ContactAddedCallback. The fix was simply to replace it with a check as to whether the objects are swapped, and assign the index to m_triface0 or 1 accordingly.

I suppose my only question at this point, with regard to GImpact, is if there is a reason for the second swap, or if it was just a design decision.
</GImpact discussion>

Thanks, and congratulations if you read everything :)

- Alex
You do not have the required permissions to view the files attached to this post.