Box2D Joints #2 – Revolute Joints

Revolute Joints
Revolute joints can be used to create rotating joints (aka motors) or joints with friction. Both types can have angular limits placed on them. Take a look at the TestRagdoll, TestCrankGearsPulley and TestTheoJansen for more examples of how to use this joint type.

Creating Motors
The motor features of a revolute joint provide a lot of functionality. Just look at the Crank/Gear/Pulley and Theo Jansen Walker test bed examples for a hint of their potential. When creating a motor the maxMotorTorque is the most import property. Measured in newton meters (N•m), when using the normal units (not converted to pixels as in my example), it determines the amount of mass the motor can rotate. If your motors is not rotating or rotating poorly you likely need to increase its maxMotorTorque. Simple Motor Example:

//Create and setup a revolute joint as a simple motor
pivot.position.Set(80,250);
var pivotBody1:b2Body = m_world.CreateBody(pivot);
pivotBody1.CreateShape(pivotPoly)
pivotBody1.SetMassFromShapes();

var motorPoly:b2PolygonDef = new b2PolygonDef();
motorPoly.SetAsOrientedBox(30, 10, new b2Vec2(0, 0), 0);
motorPoly.friction = .3;
motorPoly.density = .01;
motorPoly.restitution = .1;
			
var motorDef:b2BodyDef = new b2BodyDef();
motorDef.position.Set(110, 250);
var motorBody:b2Body = m_world.CreateBody(motorDef);
motorBody.CreateShape(motorPoly);
motorBody.SetMassFromShapes();

//Setup the revolute joint definition for later instantiation. rjd is a predefined b2RevoluteJointDef object.
rjd.Initialize(pivotBody1, motorBody, new b2Vec2(80,250));
rjd.motorSpeed = 3;
rjd.maxMotorTorque = 10000000;
rjd.enableMotor = true;
rjd.enableLimit = false;
//Create the motor joint and cast it as a b2RevoluteJoint
var joint1:b2RevoluteJoint = m_world.CreateJoint(rjd) as b2RevoluteJoint;

Limits
Revolute joints are not limited to continuous rotation. You can set upper and lower limits to the joint (in radians). When used with the enableMotor property set to false, this joint is ideal for simulating limbs. See the TestRagdoll example for a great demo of this.

Combining joint limits, motors and conditionals allows for creation of some interesting systems. I could see this used as valves, platforms in games, fins on fish, etc. In this example I have setup a motor to oscillate between its limits.

//Setup a limited revolute joint that oscillates between its limits
pivot.position.Set(80,100);
var pivotBody2:b2Body = m_world.CreateBody(pivot);
pivotBody2.CreateShape(pivotPoly)
pivotBody2.SetMassFromShapes();

var limitMotorPoly:b2PolygonDef = new b2PolygonDef();
limitMotorPoly.SetAsOrientedBox(30, 10, new b2Vec2(0, 0), 0);
limitMotorPoly.friction = .3;
limitMotorPoly.density = .01;
limitMotorPoly.restitution = .1;
			
var limitedMotorDef:b2BodyDef = new b2BodyDef();
limitedMotorDef.position.Set(110, 100);
var limitedMotorBody:b2Body = m_world.CreateBody(limitedMotorDef);
limitedMotorBody.CreateShape(limitMotorPoly);
limitedMotorBody.SetMassFromShapes();
			
//Setup the revolute joint definition for later instantiation
rjd.Initialize(pivotBody2, limitedMotorBody, new b2Vec2(80,100));
rjd.motorSpeed = 3;
rjd.lowerAngle = 0;
//Convert the angle in degrees to radians
rjd.upperAngle = 270*(Math.PI/180);
rjd.enableLimit = true;
rjd.maxMotorTorque = 10000000;
rjd.referenceAngle = 0;
rjd.enableMotor = true;
//Create the motor joint and cast it as a b2RevoluteJoint. Store the joint object in a class var for use later in the update method.
limitMotorJoint = m_world.CreateJoint(rjd) as b2RevoluteJoint;

Friction Joints
Friction joints are revolute joints with the motor enabled, a non-zero maxMotorTorque and the motor speed set to 0. This will cause the joint to resist rotation but give when the maxMotorTorque is exceeded, giving the effect of a joint with friction at the pivot. Once the force to the joint is removed it stops moving. Example:

//Setup a friction joint
pivot.position.Set(190,100);
var pivotBody3:b2Body = m_world.CreateBody(pivot);
pivotBody3.CreateShape(pivotPoly)
pivotBody3.SetMassFromShapes();
			
var armPoly:b2PolygonDef = new b2PolygonDef();
armPoly.SetAsOrientedBox(90, 10, new b2Vec2(0, 0), 0);
armPoly.friction = .5;
armPoly.density = .01;
armPoly.restitution=0;
			
var armBodyDef:b2BodyDef = new b2BodyDef();
armBodyDef.position.Set(280,100);
var armBody = m_world.CreateBody(armBodyDef);
armBody.CreateShape(armPoly)
armBody.SetMassFromShapes();
			
rjd.Initialize(pivotBody3, armBody, new b2Vec2(190,100));
rjd.motorSpeed = 0;
rjd.maxMotorTorque = 10000000;
rjd.enableMotor = true;
rjd.enableLimit = false;
var joint2:b2RevoluteJoint = m_world.CreateJoint(rjd) as b2RevoluteJoint;

Example:

If you are seeing this you need to enable javascript. This is a flash example of three different uses of the Box2D revolute joint.


Full Source not including Box2D

5 Responses to “Box2D Joints #2 – Revolute Joints”

  1. luke Says:

    Great stuff. You should chuck this in the useful pages wiki just created. http://www.box2d.org/wiki/index.php?title=List_of_useful_articles.

  2. luke Says:

    Also, if you want to see what a box with a broken leg might look like….

    // car body
    var carDef:b2PolygonDef = new b2PolygonDef();
    carDef.SetAsOrientedBox(20, 20, new b2Vec2(0, 0), 0);
    carDef.friction = .5;
    carDef.density = .5;
    carDef.restitution=0;
    var carBodyDef:b2BodyDef = new b2BodyDef();
    carBodyDef.position.Set(110,250);
    var carBody = m_world.CreateBody(carBodyDef);
    carBody.CreateShape(carDef)
    carBody.SetMassFromShapes();

    //===========================
    // Motor Example
    // A simple motor example
    //===========================
    pivot.position.Set(80,250);
    var pivotBody1:b2Body = m_world.CreateBody(pivot);
    pivotBody1.CreateShape(pivotPoly)
    pivotBody1.SetMassFromShapes();

    var motorPoly:b2PolygonDef = new b2PolygonDef();
    motorPoly.SetAsOrientedBox(30, 10, new b2Vec2(0, 0), 0);
    motorPoly.friction = .3;
    motorPoly.density = .01;
    motorPoly.restitution = .1;

    var motorDef:b2BodyDef = new b2BodyDef();
    motorDef.position.Set(110, 250);
    var motorBody:b2Body = m_world.CreateBody(motorDef);
    motorBody.CreateShape(motorPoly);
    motorBody.CreateShape(carDef);
    motorBody.SetMassFromShapes();

    //Setup the revolute joint definition for later instantiation. rjd is a predefined b2RevoluteJointDef object.
    rjd.Initialize(carBody, motorBody, new b2Vec2(80,250));
    rjd.motorSpeed = -3;
    rjd.maxMotorTorque = 10000000;
    rjd.enableMotor = true;
    rjd.enableLimit = false;
    //Create the motor joint and cast it as a b2RevoluteJoint
    var joint1:b2RevoluteJoint = m_world.CreateJoint(rjd) as b2RevoluteJoint;

  3. Vincent Says:

    The link “Full Source not including Box2D” is broken. Can you send me file plz ?

  4. Brettf Says:

    It’s fixed now.

  5. Andre Vidal Says:

    Great talking, it helps alot while trying to figure out the BedTest stuff.
    You should set the background to a darker color though ;)