Closed GoogleCodeExporter closed 9 years ago
I tried to replicate this, but the bodies would always collide after the link
was broken. So sample code would be good.
You can also try this recent (generic) build:
https://drive.google.com/folderview?id=0B2TPMwtggT0jYlo4RlhIb3BMdlU#list
Original comment by andres.traks
on 8 Nov 2014 at 11:03
Hi Andres.
Thanks for looking at this.
I derived a sample app from the SlimDX BasicDemo and attached it to demonstrate
the behavior. I pulled all the variables into PhysicsContext.cs, so that it's
easy to tweak everything from one spot. It's .net 4.5.1 and 64-bit.
As long as ConstrainTheSpheres = False, the simulation succeeds, regardless of
whether FrameIndependence_Enabled = True or False and regardless of whether
CCD_Enabled = True or False. Success means that all the spheres collide and
don't overlap.
As long as ConstrainTheSpheres = True, the simulation fails, regardless of
whether FrameIndependence_Enabled = True or False and regardless of whether
CCD_Enabled = True or False. Failure means that only the spheres that were not
previously constrained to each other collide, and the rest improperly overlap.
Therefore, as far as I can tell, frame independence and CCD both appear to be
irrelevant to this behavior. The only factor that I have found that causes the
overlapping behavior is the creation and breaking of fixed constraints.
I included all my notes on this in the comments, right above the variables in
PhysicsContext.cs. Maybe this is caused by some mistake that I've made
elsewhere in the code, but I can't seem to find it?
Original comment by patr...@shaughness.com
on 11 Nov 2014 at 3:30
Attachments:
This isn't necessary:
Body1.AddConstraintRef(myFixedConstraint);
Body2.AddConstraintRef(myFixedConstraint);
I think it adds double references, so the constraint solver thinks the
constraint still exists and collision aren't handled.
DynamicsWorld.AddConstraint already adds the constraint refs:
http://bulletphysics.org/Bullet/BulletFull/btDiscreteDynamicsWorld_8cpp_source.h
tml#l00649
Commenting out those two lines seems to fix the issue. :)
Original comment by andres.traks
on 11 Nov 2014 at 3:56
That's interesting. It makes sense that manually adding constraint refs to the
rigid bodies could cause duplicate references, but I was adding those
constraint refs to the rigid bodies manually, because I thought the constraint
refs were not being added automatically. This was a workaround a different
issue (which I had forgotten about), in which RigidBody.NumConstraintRefs
always returns zero, regardless of how many constraints a RigidBody has.
You can see this issue in action in the sample code that I uploaded if you:
1 - comment-out the two lines that you suggested should be removed and
2 - paste the following code at the bottom of the ScenarioCollisionIssue's
constructor (right after the call to AddGround):
//Dump .NumConstraintRefs for each Rigidbody
foreach (CollisionObject ThisCollisionObject in
myPhysicsContext.myDynamicsWorld.CollisionObjectArray) {
RigidBody ThisRigidBody = ThisCollisionObject as RigidBody;
Console.WriteLine(ThisRigidBody.NumConstraintRefs.ToString());
}
When you build and run, it creates all the rigid bodies and constrains them,
and then it iterates all of the rigid bodies and outputs .NumConstraintRefs for
each. They are all zero!
When you restore the two lines of code that you suggested be removed and rerun
the code, it outputs the correct .NumConstraintRefs for each rigid body. (Not
saying that my two lines are correct - they're not - just showing you why I put
them there.)
More generally, when I have a reference to a rigid body, I need a way to
iterate through all of its constraint refs, so that I can manually remove some
of them. Isn't this what .NumConstraintRefs is supposed to provide? -- a
count for an iterator?
Original comment by patr...@shaughness.com
on 11 Nov 2014 at 7:45
The refs are only added automatically if disableCollisionsBetweenLinkedBodies =
True (see the link above) and refs are only used to check if the collisin
should be ignored:
http://bulletphysics.org/Bullet/BulletFull/btRigidBody_8cpp_source.html#l00320
The constraint refs themselves aren't exposed by the bodies, so you'd have to
maintain the list of constraints yourself. The refs only include those
constraints with disableCollisionsBetweenLinkedBodies = true anyway
(NumConstraintRefs does increase in that case).
I was wrong about the double refs, that doesn't happen, because they check if
the ref exists:
http://bulletphysics.org/Bullet/BulletFull/btRigidBody_8cpp_source.html#l00339
If BreakingImpulseThreshold is exceeded, then the constraint is disabled, but
it's not removed from the world and the refs aren't removed either. However,
even if the refs exist, then the collision should occur, because there is the
additional condition "if (c->isEnabled())" in
btRigidBody::checkCollideWithOverride. So if the constraint is disabled, the
collision should be handled even with the refs existing. But it's not handled,
so there is something else wrong here.
Theoretically, for the fixed constraint, it shouldn't make any difference if
disableCollisionsBetweenLinkedBodies is set or not, because the bodies don't
interact anyway if this particular type of constraint is enabled. And if the
constraint is disabled, then btRigidBody::checkCollideWithOverride should
detect it and allow collisions.
I don't know what the problem is there, but I hope the explanation made some
sense. Particularly, the constraint refs don't have to exist if the constraint
exists. At least it works as intended (not doing AddConstraintRef manually).
Bullet classes sometimes expose members that aren't needed by users, but are
required internally to exchange information. I think NumConstraintRefs is one
of those.
Original comment by andres.traks
on 12 Nov 2014 at 12:25
Original comment by andres.traks
on 16 Nov 2014 at 7:59
Yes, your explanation was a big help. I stopped trying to get my references to
constraints via the rigid bodies and instead, I started managing the constraint
references myself. That way I was able to create and destroy constraints
programmatically, which lead to the collisions occurring as they should.
Thanks Andres!
Original comment by patr...@shaughness.com
on 17 Nov 2014 at 1:50
Original issue reported on code.google.com by
patr...@shaughness.com
on 7 Nov 2014 at 11:00