Vizard 7 » Reference » Physics » Joints
7.3

Joints

Joints allow one or two objects to be connected to a common point. For instance in a door hinge the two objects are the door frame and the door itself, with the hinge being the common point between them.

 

For all the joints if only one object is linked to the joint, then the joint has one end attached to the world and does not move. If two objects are used in the creation of the joint, then the joint position moves with the two objects.

 

Some of the joints are affected by the function setAxisLimit which takes three arguments, axis, lower value and upper value. When specified, the movement of the joint along the specified axis is constricted to the boundaries.

 

Joint also have three breakable modes which the default is viz.JOINT_UNBREAKABLE and the others are viz.JOINT_BREAK_THRESH and viz.JOINT_BREAK_ACCUM. These modes are set through the use of the function setBreakMode. When using viz.JOINT_BREAK_THRESH a second argument is needed which specifies the amount of force needed to break the joint. When using viz.JOINT_BREAK_ACCUM a second and third argument is needed; the first specifies the total accumulated damage that must be reached before the joint breaks, and the second specifies the amount of force required to before damage is added. An optional parameter removeBroken can also be supplied to this function which when set to false leaves the joint in vizard once the joint is broken. By default the joints are removed when broken so any further calls on the joint will result in an error.

Ball Joint

A ball joint permits 360 degrees of rotation along each axis. A ball joint is created with the addBallJoint and then takes three optional parameters which specify each axis. Changing the axis in the ball joint only affect the setAxisLimit function. By default the axis are created relative to absolute world coordinates where axis0 is along the x, axis1 is along the y and axis2 is along the z. Make sure if changing an axis that it is perpendicular to the line (or the axis along the line) between the two objects when they are created.

 

The movement along each axis can be restricted by using the setAxisLimit function, and the joint is breakable as specified above.

 

The following is an example of a ball joint in which the moving ball is restricted to the right hemisphere and the joint will break after some amount of damage has occurred. A force will be applied to the ball by middle clicking on it.

#Add a ball
ball = viz.add('ball.wrl',pos=(1,1.8,5))
ball.collideSphere()

ANCHOR_POS = (0,1.8,5)
viz.add('white_ball.wrl',pos=ANCHOR_POS) # Anchor Model

joint = viz.phys.addBallJoint(ball,None,pos=ANCHOR_POS) # Create joint
joint.setAxisLimit(2,-90,90)
joint.setBreakMode(viz.JOINT_BREAK_ACCUM,100,2,removeBroken=False)

def pushBox():
    info = viz.pick(1)
    if info.valid:
        line = viz.MainWindow.screenToWorld(viz.mouse.getPosition())
        info.object.applyForce(dir=viz.Vector(line.dir,length=1),duration=0.1,pos=info.point)
vizact.onmousedown(viz.MOUSEBUTTON_MIDDLE,pushBox)

Hinge Joint

A hinge joint permits 360 degrees of rotation in one axis. All aspects of the hinge joint are the same except that it only has one axis which by default is along the world's x axis.

#Add a ball
ball = viz.add('ball.wrl',pos=(1,1.8,5))
ball.collideSphere()

ANCHOR_POS = (0,1.8,5)
viz.add('white_ball.wrl',pos=ANCHOR_POS) # Anchor Model

joint = viz.phys.addHingeJoint(ball,None,pos=ANCHOR_POS,axis0=[0,0,1])

Notice how axis0 was changed by specifying the world's z axis.

Universal Joint

A universal joint has two accesses and thus permits 360 degrees of rotation in two planes. Once again all aspects of this joint are similar to the ball joint with the exception of the joint only moving along two axis.

 

The following is similar to the ball joint example except this joint will not rotate about the z axis.

#Add a ball
ball = viz.add('ball.wrl',pos=(1,1.8,5))
ball.collideSphere()

ANCHOR_POS = (0,1.8,5)
viz.add('white_ball.wrl',pos=ANCHOR_POS) # Anchor Model

joint = viz.phys.addUniversalJoint(ball,None,pos=ANCHOR_POS)
joint.setBreakMode(viz.JOINT_BREAK_ACCUM,100,3,removeBroken=False)

def pushBox():
    info = viz.pick(1)
    if info.valid:
        line = viz.MainWindow.screenToWorld(viz.mouse.getPosition())
        info.object.applyForce(dir=viz.Vector(line.dir,length=1),duration=0.1,pos=info.point)
vizact.onmousedown(viz.MOUSEBUTTON_MIDDLE,pushBox)

Wheel Joint

A wheel joint is much like the universal joint in that it permits 360 degrees of rotation in two planes. It also has an added suspension along its axis0 which gives it a more realistic look. A further restriction on this joint is that it must be created between two objects and thus cannot be passed the None keyword as one of its arguments.

 

The following is a simple wheel example, in which the front ball is connected by a wheel joint and the two rear balls are connected through hinge joints. This example also makes use of the setMotorAngle motor and setMotorThrottle motor which are covered in the motors section.

body = viz.add('box.wrl',scale=[.75,.5,2],pos=[0,1,0]) # Body
body.collideBox()

front = viz.add('ball.wrl',pos=[0,.5,1.5]) # Front Wheel
front.collideSphere()
frontJoint = viz.phys.addWheelJoint(body,front,pos=(0,.5,1.5),axis0=(0,-1,0),axis1=(1,0,0))

rearLeft = viz.add('ball.wrl',pos=[-1,.5,-1.5]) # Rear Left Wheel
rearLeft.collideSphere()
rearLeftJoint = viz.phys.addHingeJoint(body,rearLeft,pos=(-1,.5,-1.5),axis0=(-1,0,0))
rearRight = viz.add('ball.wrl',pos=[1,.5,-1.5]) # Rear Right Wheel
rearRight.collideSphere()
rearRightJoint = viz.phys.addHingeJoint(body,rearRight,pos=(1,.5,-1.5),axis0=(-1,0,0))

def steer(val):
    frontJoint.setMotorAngle(0,val,0xFF,.1)

def SetThrottle(val):
    frontJoint.setMotorThrottle(1,-val,.1,1e6)
   
vizact.onkeydown(viz.KEY_UP,SetThrottle,1) # Move forward
vizact.onkeydown(viz.KEY_RIGHT,steer,45) # Steer Right
vizact.onkeydown(viz.KEY_LEFT,steer,-45) # Steer Left
vizact.onkeydown(viz.KEY_DOWN,SetThrottle,-1) # Move backwards

Slider Joint

A slider joint allows movement away from or towards the anchor point in a straight line. The slider joint is affected by the setAxisLimit, setAxisBounce, and setAxisFriction functions. The axis limits specify how far in each direction the object can move. Axis Bounce specifies how much energy is transferred in the opposite direction when the limit is reached. Finally axis friction is the amount of resistance in the slider.

anchorPos = [0,1.5,6]
b = viz.add('box.wrl',pos=anchorPos,scale=[2.1,.31,.31],color=viz.YELLOW)
box = anchor = viz.add('box.wrl',pos=anchorPos,scale=[2,.3,.3],color=viz.GREEN)
box.collideBox()

joint = viz.phys.addSliderJoint(box,None,pos=anchorPos,axis0=(1,0,0))
joint.setAxisLimit(0,-1,1) # Limit sliding distance
joint.setAxisBounce(0,.5) # Change end bounce properties

vizact.onkeydown(viz.KEY_RIGHT,box.applyForce,[10,0,0]) # Move Right
vizact.onkeydown(viz.KEY_LEFT,box.applyForce,[-10,0,0]) # Move left

Fixed Joint

The fixed joint permanently links one object to another from their current location.

 

In the following example the ball is permanently linked to it's starting location. If this were linked to another object then the two objects would always move with each other.

ball = viz.add('ball.wrl',pos=(-0.5,1.8,6))
ball.collideSphere()
joint = viz.phys.addFixedJoint(ball,None)

More on Joints

See also

In this section:

Physics basics

Physics Shapes - In depth discussion of the collide methods.

Forces - More detail on applyForce and applyTorque.

Joints - In depth overview of the joint types.

Motors - In depth explanation of how each motor works with each joint.

Physics Command Table

Other sections:

Tutorial: Physics

Event Reference

Example scripts:

Basic physics

Tracking an object

Collision plane

Callbacks & complex shapes

Forces & materials