I'm using a MouseJoint
to move bodies around in libgdx
. It has been working fine with dynamic
bodies, but with a certain kinematic
body I get a weird error that makes the game crash. The error is:
Assertion failed: (d + h * k > 1.19209290e-7F), function InitVelocityConstraints, file /Users/badlogic/jenkins/workspace/libgdx-mac/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Dynamics/Joints/b2MouseJoint.cpp, line 125.
Unfortunately, the stack is not shown upon crashing so I can't provide that. The error seems to be connected to the MouseJoint
creation, but I did go step-by-step in debug and the creation itself goes by smoothly (or so it seems at least). Has anyone had the same error and survive to share his/her wisdom?
The code that creates the MouseJoint
(which, as stated above, goes by fine. The game crashes elsewhere, I have no idea where) is:
mTmpMouseJointDef.bodyA = mWorld.createBody(mTmpBodyDef); // Create dummy body
mTmpMouseJointDef.bodyB = b_body;
mTmpMouseJointDef.collideConnected = true;
mTmpMouseJointDef.target.set(pTargetVec.x, pTargetVec.y);
mTmpMouseJointDef.maxForce = 1000.0f * b_body.getMass();
mouseJoint = (MouseJoint)mWorld.createJoint(mTmpMouseJointDef);
You simply can't use a MouseJoint
with a kinematic body as bodyB
, that's what is causing the assert (see this other SO post about the same problem).
About the part from the Box2D manual you quote, it just states that in general, a joint between two bodies that are either kinematic or static can be created, but have no effect. However, this is not true with a MouseJoint
, as it requires the bodyB
mass to be non-zero (and in Box2D all kinematic and static bodies have zero mass).
We can see that by looking at the code in the initVelocityConstraints
function (from the JBox2D Github):
public void initVelocityConstraints(final SolverData data) {
// some code...
float mass = m_bodyB.getMass();
// Frequency
float omega = 2.0f * MathUtils.PI * m_frequencyHz;
// Damping coefficient
float d = 2.0f * mass * m_dampingRatio * omega;
// Spring stiffness
float k = mass * (omega * omega);
// magic formulas
// gamma has units of inverse mass.
// beta has units of inverse time.
float h = data.step.dt;
assert (d + h * k > Settings.EPSILON);
// some code...
}
If mass
is zero, then both the damping coefficient d
and the spring stiffness k
are zero, and d + h * k
is zero, causing the assert.