simple bullet questions

Post Reply
catchyid
Posts: 15
Joined: Thu Jul 30, 2015 2:12 pm

simple bullet questions

Post by catchyid »

(I have figured out some questions... )

Hi,

I am learning bullet and I have the following questions, any feedback would be appreciated:

1-When I simulate two rigidbodies falling under gravity, they fall down and don't penetrate (i.e. they collide while falling and don't penetrate, which is good). When I create a kinematic constraint between them (point to point), then the constraint gets satisfied but the two rigidbodies penetrate each other. Is this normal? and how to avoid this penetration?

EDIT: That was my mistake, when I create a constraint there is a boolean that determines whether to disable/enable collision between constrained objects. Check the second parameter in btDiscreteDynamicsWorld::addConstraint() function

2-If I want two rigidbodies to stick to each other (e.g. like having an unbreakable constraint), I create one (btGeneric6DofConstraint) constraint and:
(a) constraint.setLimit(i,0.f,0.f) for 6 >i > 0
(b) constraint.setBreakingImpulseThreshold(constant * total Mass)

This is similar to VoronoiFracture demo. However, in my simulation, objects rotate with respect to each other as if the constraints were downgraded to point to point! To fix the problem, I've tried to increase the "constant" value in the setBreakingImpulseThreshold function but that does not fix the problem, and if I increase it really high it could introduce an assertion in btSequentialImpluseSolver.
Now, I am not sure how to address this problem? should I introduce more constraints between rigidbodies? or maybe there is a better way to make rigidbody act as if they were one rigid body then eventually break it down gradually? My final goal is for example to have one large block of cement fall then break it gradually according to a predetermined scenario...

EDIT: other posts suggest that I need to increase number of joint iterations to increase solver accuracy hence eliminate this unwanted rotation, I did so (increased it to 3000 iterations) but this does not eliminate the problem, it just makes it slower, i.e. instead of happening in one second, it will happen in 3 seconds...When I look at how rigidbodies move, it seems like the constraint solver tries to satisfy the constraints on each step, sometimes it gets closer to the solution and sometimes it fails. I think it does not matter how much high I increase the number of joint iterations, this unwanted rotation will be always present?

3-This is not a question, I just want to verify my understanding of the difference between kinematic and static bodies: both must set have their masses to zero, however for kinematic body we must also :
(a) set
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState(DISABLE_DEACTIVATION);
and,
(b) override function getWorldTransform() and return pos/quaternion (and also compute velocity for better collision response)

Is this right?


Thanks in advance.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: simple bullet questions

Post by drleviathan »

If you want to join two btRigidBodys together then you could try the btFixedConstraint. I once used it for an experiment and it worked fine for just two bodies. I forget exactly how the stability scaled as the number of fixed bodies increased, but I think more than five did not work well (with substeps at 60Hz).

The way to make a KINEMATIC object is to give the object a custom MotionState. Bullet is guaranteed to call YourMotionState::getWorldTransform() once per substep on kinematic objects that have one. You will have to derive YourMotionState from btMotionState (which merely defines the Interface) and implement it yourself to do the right thing.

There is some information about MotionStates on this wiki page.
catchyid
Posts: 15
Joined: Thu Jul 30, 2015 2:12 pm

Re: simple bullet questions

Post by catchyid »

Thanks drleviathan for your quick reply.

I am testing only two rigidbodies, so have not reached 5 yet. I am using btFixedConstraint as you mentioned, however the constraint is not satisfied during the simulation, i.e. unwanted small rotation initially introduced then it accumulates during the simulation. I pumped up the internal frame rate to (1/1000) with 1000 substeps + joints iteration to 1000, but as I mentioned before that just slowed down the problem.

I still doing more tests, but I think one constraint is not enough, maybe I should use two constraints instead of one if I want to keep two rigidbodies stick to each other...

Thanks,
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

Re: simple bullet questions

Post by gdlk »

How much mass has each object? Also, just to check, do you calculate local inertia in the object creation?

In the other hand, you could try to simulate an "angular friction" in the constraint (maybe could fix your problem). For that, after create the constraint use the method getRotationalLimitMotor to get the rotational constraint motor, and then enable the motor and set some little max motor force with target velocity 0
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: simple bullet questions

Post by drleviathan »

If the objects really need to be stuck fast then they are effectively a single object. Why not just make one RigidBody using a btCompoundShape? When breaking the object apart you can rebuild its shape to keep one part and spawn a new RigidBody for the other. This would be slightly more complicated than removing one constraint, but not terribly so.

If you were to try this route you need to know that in order to update the shape of an RigidBody such that it collides correctly you must, in general, pull that object out of the DynamicsWorld and then reinsert it (*). The cost of inserting a new object into the world is linear with the number of objects already therein, so this might be a problem if your simulation has a large number of them -- dunno the number where you'd start to notice it but I'm guessing it is more than 10k and less than 100k.

(*) There is an exception to this rule: if the object's new shape is not larger than its old one, then there is a tradeoff you can make: don't reinsert into the world but know that its broadphase collision queries will tend to produce more false positives than usual because its Aabb will be larger than necessary -- the result would be an unoptimization and a theoretically slightly higher cost testing at the narrowphase.
catchyid
Posts: 15
Joined: Thu Jul 30, 2015 2:12 pm

Re: simple bullet questions

Post by catchyid »

Hey guys, first thanks for your replies.

Second, I will tell you exactly what I want to achieve because I am afraid I am using bullet the wrong way. In summary: I have a tornado that hits a barn and destroys it gradually, the barn is modelled in Maya and I wrote a bullet plugin that automatically parses maya scene (given some naming conventions) and builds corresponding rigidbodies with automatic constraints (e.g. if two rigidbodies intersect then create one constraint between them to lock down all 6 DOF similar to VoronoiFracture demo). See attached images. Note: Autodesk Bullet/Maya integration is "limited", so I wrote mine that is very specific to my task. Also, before the tornado hits the barn, I want the roof to wiggle, and as the tornado hits the barn I want to break the constraints and apply impulses to make parts of the barn fly. I have implemented a simple logic to apply these actions procedurally, e.g observe tornado distance from barn and at a certain distance start breaking the constraints and apply impulses.

My question now is about the "right" way to use Bullet:
Initially, I want to make the barn stand still before it gets hit by the tornado, so I modelled the barn structurally correct - e.g. having a kinematic|static base (0 mass) that carries vertical walls and these walls carry the roof. I also use constraints to glue horizontal pieces, i.e. the roof is made of tiles, so I glue these horizontal tiles using constraints. So is this the right way to model a structure like that in bullet? From my simple test (see image after_100tick.png) some walls start to rotate regardless of amount of constraint I use and other parts of the wall starts to fly up and down, which makes me believe I am using Bullet the wrong way. BTW, I don't think it's a programming error, I followed VoronoiFracture demo strictly and and that logic worked for simple use cases, e.g. having 4 or 5 rigidbodies, however it did not work when I applied it to my barn.

Finally, to answer your questions:

@ gdlk:
I checked masses computed by Maya and here are some samples: 33,975 142,3402 642,064. After some testing I realized these numbers might not be correct, e.g. two identical pieces of geometry might have significantly different masses, or even worse a small volume has a heavier mass than a bigger volume. To resolve the issue I just used 10 as a fixed mass value for all bodies (I know this is wrong, but I hoped it's better than what maya computes).

When it comes to inertia, I use bullet to compute it for me, here is a pseudo code:

btConvexHullShape* chShape = new btConvexHullShape();
//populate shape by reading maya points
chShape->addPoint(btVector3(maya vertex), true);
btScalar mass(10); //fixed mass as I am not sure maya returns the right volume
btVector3 localInertia(0.f, 0.f, 0.f);
chShape->calculateLocalInertia(mass, localInertia);

I don't understand physics much, but I even think that the above logic is wrong as Bullet assumes the shape is already aligned to its inertia principal axes, but in my case I am passing Bullet raw points without any preprocessing to satisfy Bullet requirements?

As per using motorized joints with target velocity = 0, I did so and it did not help ( I tried different combination of the code below):

btGeneric6DofSpring2Constraint* dof6 = new btGeneric6DofSpring2Constraint(...);
dof6->setEquilibriumPoint();
dof6->setOverrideNumSolverIterations(10000);
dof6->setBreakingImpulseThreshold(1000000*totalMass);
for (int i = 0; i < 6; i++)
{
dof6->enableMotor(i, true);
dof6->enableSpring(i, true);
dof6->setStiffness(i, 1000, true);
dof6->setDamping(i, 1000, true);
dof6->setLimit(i, 0, 0);
dof6->setTargetVelocity(i, 0.f);
dof6->setMaxMotorForce(i, 1000000*totalMass);
}

@drleviathan:
I like your idea of breaking compound shape rigidbodies on demand. Let me ask you 3 questions first:

a- when I break a compound shape rigidbody into two smaller ones, I think the only physical property I need to copy from the parent|original rigidbody to the new ones is velocity, right? meaning: the parent rigidbody will be moving at a certain linear/angular velocity so to keep the continuity of the scene I just need to copy these values to new rigidbodies

b-I have "bad" geometrical models, where let's say roof tiles intersect with each other. Let's say I group a bunch of intersecting tiles as compound shape, would that break the simulation, i.e would the collision detection module in Bullet complain about these intersections? Or maybe the moment I break the objects and reinsert them then they will move away quickly as a result of the intersection..

c-I am not using Bullet built-in collision shapes, instead I am reading whatever the modeller creates in Maya and feed that into bullet as collision shapes, the only requirements I have is that all shapes must be convex hull, is this correct? I think this is "wrong" because the shape must be aligned to its principle axes of moments of inertia as I mentioned to gdlk before?

Thanks guys and sorry for the long email...
Attachments
I only simulated the base of the barn and side walls, i.e. the rest is left out
I only simulated the base of the barn and side walls, i.e. the rest is left out
after_100tick.png (27.59 KiB) Viewed 13047 times
The cylinder represents the tornado
The cylinder represents the tornado
scene_setup.png (21.89 KiB) Viewed 13047 times
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

Re: simple bullet questions

Post by gdlk »

ok, at least is not a mass ratio issue because you are using the same mass to all objects =P

Also, I suppose you are using btRigidBody, and after calculate the local inertia in the way you show you are calling the setMassProps.

I am out of idea by the moment why could be happen that
Basroil
Posts: 463
Joined: Fri Nov 30, 2012 4:50 am

Re: simple bullet questions

Post by Basroil »

There's an old fracture demo at https://code.google.com/p/bullet/source ... actureDemo , did you get a chance to study it to see differences in approach?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: simple bullet questions

Post by drleviathan »

If you use one btCompoundShape for the barn then it would be hard to make the pieces wiggle as the tornado approaches the barn. It is doable, but seems complicated: you'd have to perform your own animation/simulation and compute the parent-relative positions of all the pieces.

You could make each part its own btRigidBody and make them kinematic at first and then set them dynamic when you want to let the Bullet rigidbody simulation take over. You'd have to write custom kinematic simulation for the pieces that wiggle, but wiggling each piece individually seems a little easier than animating inside a btCompoundShape. In order to break off multiple pieces that stick together you could join them with btFixedConstraints and let the collection tumble and then use some fracture logic to decide when these partial-barns should break.

To answer your questions:

(a) When you break pieces apart the best thing to do would be to give them each the correct linear and angular velocities they had in the collection. These can be computed from the geometry of the child parts relative to the collection center of mass and the parent's velocities. The angular velocity is easy -- it's identical to that of the parent at the moment of break. The linear velocity is trickier -- you have to add a term that is related to the angular velocity of the whole object and the offset of the child part relative to the collection's center of mass:

linear_velocity_of_child_part = linear_velocity_of_collection + angular_velocity_of_collection X offset_of_child_part

where X is the "vector cross product".

(b) Yes, if parts overlap when you break them apart they may separate in a "non-physical" way, however Bullet's penetration resolution code is not particularly explosive and I wouldn't expect it to pump too much energy into the simulation. Try it first and then worry about it if it looks bad.

(c) Yes, the pieces should be convex: hulls, boxes, cylinders, or sphere. You could make them all convex hulls but, if an object's shape does not align well with its local bounding box then it could end up with strange dynamics since its inertia tensor will be wrong. (Note: you can only specify diagonal inertia tensors in Bullet but what is really stored internally is the full inverse inertia tensor -- I haven't looked into it but it may be possible to inject the correct local inverse inertia tensor for convex hulls that don't align well with their local axes, and then you could, in theory, use inertia tensors with large off-diagonal values.) For best physics results you might try to make your Maya exporter output boxes with rotations rather than raw points for convex hulls.
catchyid
Posts: 15
Joined: Thu Jul 30, 2015 2:12 pm

Re: simple bullet questions

Post by catchyid »

https://drive.google.com/open?id=0B3_Wd ... V9JeHYyTTQ
https://drive.google.com/open?id=0B3_Wd ... XZNNHRSX2M
https://drive.google.com/open?id=0B3_Wd ... WhXRnJORVE

Hello...

thanks guys for your feedback, it's very appreciated.

I've done some testing and wanted to update you:

1) As per fixed constraints problem (i.e. fixed constraints that yet rotate during simulation)

It was my mistake :oops: Somewhere in the code, I was still using the "wrong" mass values which produced high mass ratios, hence the extra "wrong" rotation. So, gdlk, you were completely right. But, I am thinking, are these unneeded rotations numerical errors due to these high ratios?

2) @ Basroil : Thanks for your suggestion :) I saw two similar demos : VoronoiFracture and fracture. They do similar jobs, however I chose Voronoi as it's easier to understand (i.e. fracture code introduced a new dynamic world and I felt I needed to understand it & learn bullet API as well)

3) @ drleviathan : first, thanks for taking the time to reply. Second, pls have a look @ links, they show some testing. Luckily, I did not have to go down the route of using btCompoundShape then recreate smaller pieces during simulation. When I used the right mass values, simulation scaled up nicely and I was able to wiggle/fix pieces. In the attached simulation videos, I am using approximately 60 constraints.
(b) Yes, if parts overlap when you break them apart they may separate in a "non-physical" way, however Bullet's penetration resolution code is not particularly explosive and I wouldn't expect it to pump too much energy into the simulation. Try it first and then worry about it if it looks bad.
You are right. I did a simple test and yes bullet fixes the penetration in a "nice" way, so it's still acceptable.
(c) Yes, the pieces should be convex: hulls, boxes, cylinders, or sphere. You could make them all convex hulls but, if an object's shape does not align well with its local bounding box then it could end up with strange dynamics since its inertia tensor will be wrong. (Note: you can only specify diagonal inertia tensors in Bullet but what is really stored internally is the full inverse inertia tensor -- I haven't looked into it but it may be possible to inject the correct local inverse inertia tensor for convex hulls that don't align well with their local axes, and then you could, in theory, use inertia tensors with large off-diagonal values.) For best physics results you might try to make your Maya exporter output boxes with rotations rather than raw points for convex hulls.
You said : "if an object's shape does not align well with its local bounding box then it could end up with strange dynamics since its inertia tensor will be wrong".
Question: I don't understand how a bounding box can be misaligned with its shape (i.e. what scenario causes this problem to happen)? I understand that Bullet computes the bounding box based on the shape given to it, so it cannot be misaligned?

Alright, Once more, thanks guys for your help :)
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: simple bullet questions

Post by drleviathan »

You said : "if an object's shape does not align well with its local bounding box then it could end up with strange dynamics since its inertia tensor will be wrong".
Question: I don't understand how a bounding box can be misaligned with its shape (i.e. what scenario causes this problem to happen)? I understand that Bullet computes the bounding box based on the shape given to it, so it cannot be misaligned?
What I meant was: if the local bounding box was very dissimilar to the tightest possible bounding box (at any orientation) then the inertia tensor would be off.

For example: take a long skinny box with dimensions 1, 1, 9 that is aligned with its local axes and you'll have a diagonal inertia tensor with one small eigenvalue and two large ones. Now take the same box but orient it in local space such that its long side is parallel to the direction <1, 1, 1> local inertia tensor in local space will have significant off-diagonal elements -- such an object's local frame has been poorly chosen.

It is possible to create such a "diagonal box" shape using 8 appropriate corner points for a btConvexHullShape.
Post Reply