Hey all,
I'm trying to implement a ragdoll physics engine. I don't understand how the constraint is interpreting the transforms that go into it on creation. I mean, what should the transforms do to the rigid bodies. Should they rotate them so their z-axis point towards each other and are co-linear? If I have a box for a chest with x,y,z being right, up, and backwards, respectively, and another box for an arm with the same rotation, how should I create a cone-twist constraint so that the "twist" will actually twist the arm? I think i'm messing up the transforms and the twist is rotating the arm or something weird to that effect.
I tried to look for documentation on cone twist constraints but I couldn't find any. Does anyone know of a place where I can see a definition or something?
I made a render of the model to help illustrate what I'm trying to do:
I have created boxes for the chest and arm and I would like to make a cone twist constraint between them.
Transforms for creating a btConeTwistConstraint
-
- Posts: 25
- Joined: Thu Dec 20, 2007 4:03 am
-
- Posts: 13
- Joined: Tue Mar 18, 2008 1:08 am
Re: Transforms for creating a btConeTwistConstraint
Hi,
There are some pictures that may be helpful:
Page 184/298 in COLLADA 1.4.1 specification: http://www.khronos.org/files/collada_spec_1_4.pdf
Slide of presentation Physics in COLLADA: http://www.khronos.org/developers/libra ... s-2007.pdf
As my understanding, cone twist are two hinge constraints under different direction combined together. It is possible to create it generic constraint from setting two axis. If I am wrong, please correct me!
I have two questions as well:
1. Why constraint between PELVIS and SPINE is hinge, not cone_twist?
2. If in physics engine, we should always use world coordinates. Why in bullet, when setting constraint, local frame is applied? For example, here is the code from RagdollDemo in bullet engine:
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB);
hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2));
m_joints[JOINT_PELVIS_SPINE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true);
Thanks,
There are some pictures that may be helpful:
Page 184/298 in COLLADA 1.4.1 specification: http://www.khronos.org/files/collada_spec_1_4.pdf
Slide of presentation Physics in COLLADA: http://www.khronos.org/developers/libra ... s-2007.pdf
As my understanding, cone twist are two hinge constraints under different direction combined together. It is possible to create it generic constraint from setting two axis. If I am wrong, please correct me!
I have two questions as well:
1. Why constraint between PELVIS and SPINE is hinge, not cone_twist?
2. If in physics engine, we should always use world coordinates. Why in bullet, when setting constraint, local frame is applied? For example, here is the code from RagdollDemo in bullet engine:
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB);
hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2));
m_joints[JOINT_PELVIS_SPINE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true);
Thanks,
-
- Posts: 13
- Joined: Tue Mar 18, 2008 1:08 am
Re: Transforms for creating a btConeTwistConstraint
Official documentation address:
http://www.continuousphysics.com/mediaw ... e=Download
And link for user manual: http://www.continuousphysics.com/ftp/pu ... Manual.pdf
Link for API: http://www.continuousphysics.com/Bullet/BulletFull
Is documentation updated?
1. Point 2 Point (or Ball and Socket in ODE)
2. Hinge with axis along X
3. Hinge with axis along Y
4. Hinge with axis along Z
http://www.continuousphysics.com/mediaw ... e=Download
And link for user manual: http://www.continuousphysics.com/ftp/pu ... Manual.pdf
Link for API: http://www.continuousphysics.com/Bullet/BulletFull
Is documentation updated?
I was wrong, cone and twist is a special point to point constraint that adds cone and twist axis limits. (page 13/28, bullet user manual). So in general, you got 3 axises, let's assume them as X, Y, Z. Tow for cone and one for twist. A easy example is your waist, which can move as a cone and then twist along axis from feet to head. And you need to set anchor for this joint as well. So in fact, it is composed of 4 constraints:vagr wrote:Hi,
There are some pictures that may be helpful:
Page 184/298 in COLLADA 1.4.1 specification: http://www.khronos.org/files/collada_spec_1_4.pdf
Slide of presentation Physics in COLLADA: http://www.khronos.org/developers/libra ... s-2007.pdf
1. Point 2 Point (or Ball and Socket in ODE)
2. Hinge with axis along X
3. Hinge with axis along Y
4. Hinge with axis along Z
I guess that twist in RagDoll effect is not important. There could be a little bit but most action is from rotation along positive X, (from right to left?).As my understanding, cone twist are two hinge constraints under different direction combined together. It is possible to create it generic constraint from setting two axis. If I am wrong, please correct me!
I need help on this question because that we are using ODE now and COLLADA physics is similar to bullet engine. So could anyone tell me relation between local transformation set up and set up as world axis directly?1. Why constraint between PELVIS and SPINE is hinge, not cone_twist?
2. If in physics engine, we should always use world coordinates. Why in bullet, when setting constraint, local frame is applied? For example, here is the code from RagdollDemo in bullet engine:
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB);
hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2));
m_joints[JOINT_PELVIS_SPINE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true);
Thanks,
-
- Posts: 25
- Joined: Thu Nov 29, 2007 7:08 pm
Re: Transforms for creating a btConeTwistConstraint
DigitalGhost, [cool model, btw]
First of all, there was a bug in the btConeTwistConstraint class that Marcus Hennix found and has a fix for. I'm not sure if it made its way into version 2.67, but it wasn't in 2.66. Line 146 (or thereabouts) of btConeTwistConstraint.cpp should read:
btScalar EllipseAngle = btFabs(swing1*swing1)* RMaxAngle1Sq + btFabs(swing2*swing2) * RMaxAngle2Sq;
rather than
btScalar EllipseAngle = btFabs(swing1)* RMaxAngle1Sq + btFabs(swing2) * RMaxAngle2Sq;
As for the role of the transforms in the constraint constructor, they describe the constraint's transform wrt each of the bodies' local spaces. Using these, you could - for instance - have the constraint align the y-axis of one body with the x-axis of another.
The easiest way to visualize/explain it is to, for a moment, think of the constraint and your bodies in world space. Once these are chosen, you can build the constraint as follows:
btXXXConstraint(
[btRigidBody&] childBody, // (eg. ragdoll shin)
[btRigidBody&] parentBody, // (eg. ragdoll thigh)
[const btTransform&] childBodyWorldTransform.inverse() * constraintWorldTransform, // = constraint in child body space
[const btTransform&] parentBodyWorldTransform.inverse() * constraintWorldTransform, // = constraint in parent body space
);
You don't always want to think in these terms/spaces, but it's one way to ensure that the constraint transform matches from both bodies' perspective, eliminating any initial snapping.
As for the btConeTwistConstraint constraint, the twist axis is along x, swing1 is along z, and swing2 is along y. (I think. This was deduced via trial and error. I agree with you that some documentation is needed here.)
Also, I've found the default values in the setLimit() method to be a little unstable. I don't understand their meaning yet, but I've had better luck when lowering the _softness and _biasFactor values by 50% or more.
Overall, I've found the btConeTwistConstraint to be a little shaky/unstable (particularly with tight limits) compared to Bullet's other constraints. That said, it's a very useful constraint type for ragdoll joints. Hopefully some improvements are in the pipe...
Hope this helps. And feel free to correct me (anyone) if any of this is wrong.
Cheers,
Eddy
First of all, there was a bug in the btConeTwistConstraint class that Marcus Hennix found and has a fix for. I'm not sure if it made its way into version 2.67, but it wasn't in 2.66. Line 146 (or thereabouts) of btConeTwistConstraint.cpp should read:
btScalar EllipseAngle = btFabs(swing1*swing1)* RMaxAngle1Sq + btFabs(swing2*swing2) * RMaxAngle2Sq;
rather than
btScalar EllipseAngle = btFabs(swing1)* RMaxAngle1Sq + btFabs(swing2) * RMaxAngle2Sq;
As for the role of the transforms in the constraint constructor, they describe the constraint's transform wrt each of the bodies' local spaces. Using these, you could - for instance - have the constraint align the y-axis of one body with the x-axis of another.
The easiest way to visualize/explain it is to, for a moment, think of the constraint and your bodies in world space. Once these are chosen, you can build the constraint as follows:
btXXXConstraint(
[btRigidBody&] childBody, // (eg. ragdoll shin)
[btRigidBody&] parentBody, // (eg. ragdoll thigh)
[const btTransform&] childBodyWorldTransform.inverse() * constraintWorldTransform, // = constraint in child body space
[const btTransform&] parentBodyWorldTransform.inverse() * constraintWorldTransform, // = constraint in parent body space
);
You don't always want to think in these terms/spaces, but it's one way to ensure that the constraint transform matches from both bodies' perspective, eliminating any initial snapping.
As for the btConeTwistConstraint constraint, the twist axis is along x, swing1 is along z, and swing2 is along y. (I think. This was deduced via trial and error. I agree with you that some documentation is needed here.)
Also, I've found the default values in the setLimit() method to be a little unstable. I don't understand their meaning yet, but I've had better luck when lowering the _softness and _biasFactor values by 50% or more.
Overall, I've found the btConeTwistConstraint to be a little shaky/unstable (particularly with tight limits) compared to Bullet's other constraints. That said, it's a very useful constraint type for ragdoll joints. Hopefully some improvements are in the pipe...
Hope this helps. And feel free to correct me (anyone) if any of this is wrong.
Cheers,
Eddy
-
- Posts: 25
- Joined: Thu Nov 29, 2007 7:08 pm
Re: Transforms for creating a btConeTwistConstraint
One more thing I just noticed. The following code at the beginning of the btConeTwistConstraint constructor is a bit odd:
// flip axis for correct angles
m_rbBFrame.getBasis()[1][0] *= btScalar(-1.);
m_rbBFrame.getBasis()[1][1] *= btScalar(-1.);
m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
When using the constructor in the way I mentioned in the previous post, I also need to "undo" the above basis change (by commenting out this code, or pre-flipping to cancel the flip). Otherwise my constraint ends up... flipped.
Hope this helps.
Eddy
// flip axis for correct angles
m_rbBFrame.getBasis()[1][0] *= btScalar(-1.);
m_rbBFrame.getBasis()[1][1] *= btScalar(-1.);
m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
When using the constructor in the way I mentioned in the previous post, I also need to "undo" the above basis change (by commenting out this code, or pre-flipping to cancel the flip). Otherwise my constraint ends up... flipped.
Hope this helps.
Eddy
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Transforms for creating a btConeTwistConstraint
Hi Eddy,
If you make your suggested changes, the RagdollDemo doesn't work anymore.
Can you verify? Do you have a suggested patch that is compatible with the RagdollDemo?
Thanks,
Erwin
If you make your suggested changes, the RagdollDemo doesn't work anymore.
Can you verify? Do you have a suggested patch that is compatible with the RagdollDemo?
If you can provide some reproduction test case, we can check it out and try to improve it.Hopefully some improvements are in the pipe...
Thanks,
Erwin
-
- Posts: 25
- Joined: Thu Nov 29, 2007 7:08 pm
Re: Transforms for creating a btConeTwistConstraint
I just submitted a patch to fix some of the known problems (mostly taken from LvR's and Marcus's suggestions, thanks):
http://code.google.com/p/bullet/issues/detail?id=47
It contains a fix for:
- the quaternion inverse
- a btHingeConstraint constructor
- the btConeTwistConstraint swing calculation bug
- the btConeTwistConstraint axis flipping. Specifically, I removed the flipping and updated RagdollDemo.cpp so the bone-constraint-spaces are consistent.
DigitalGhost, feel free to apply it locally and let me know if it works better for you now.
Cheers,
Eddy
http://code.google.com/p/bullet/issues/detail?id=47
It contains a fix for:
- the quaternion inverse
- a btHingeConstraint constructor
- the btConeTwistConstraint swing calculation bug
- the btConeTwistConstraint axis flipping. Specifically, I removed the flipping and updated RagdollDemo.cpp so the bone-constraint-spaces are consistent.
DigitalGhost, feel free to apply it locally and let me know if it works better for you now.
Cheers,
Eddy
-
- Posts: 25
- Joined: Thu Dec 20, 2007 4:03 am
Re: Transforms for creating a btConeTwistConstraint
hey Eddy,
Thanks for your help! I switched to point-to-point constraints awhile back, but I will revisit this shortly.
Thanks for your help! I switched to point-to-point constraints awhile back, but I will revisit this shortly.
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Transforms for creating a btConeTwistConstraint
Just to confirm, the changes/fixes by Marcus and Eddy were included in Bullet 2.69.
Thanks for the help!
Erwin
Thanks for the help!
Erwin