Extensible 3D (X3D)
Part 1: Architecture and base components

37 Rigid body physics

--- X3D separator bar ---

cube 37.1 Introduction

37.1.1 Name

The name of this component is "RigidBodyPhysics". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).

37.1.2 Overview

This clause describes how to model rigid bodies and their interactions through the application of basic physics principles to effect motion. Table 37.1 provides links to the major topics in this clause.

Table 37.1 — Topics

cube 37.2 Concepts

37.2.1 Overview

This component provides the ability to influence the visual output of the scene graph in accordance to some of the laws of physics. Only the subset of the laws of physics known as rigid body physics is supported. Rigid body physics models deal with objects as solid, unchangeable sets of mass with a velocity. These bodies can be connected together with the use of various forms of joints, that allow one body's motion to effect another.

Rigid body physics evaluation requires the solving of many different factors in parallel, typically through the use of ordinarly different equations. Because these are heavily floating point based, their accuracy is highly dependent on both the implementation of the solver and the computing hardware. Due to this non-precise nature of the calculations, modelling rigid body physics requires a lot of care and attention to detail. Small changes can very quickly lead to numerical instability, which results in visual representations that make the model look like it is exploding. Most of the node definitions in this component include factors that can be modified to trade off accuracy in visual output for the stability of the calculations. In many cases, the two are inversely proportional - a more accurate simulation has a far greater chance of suffering numerical instability than a less accurate result. Intersections between bodies and the way that they interact per frame can have significant effects on the application visuals.

A consequence of this problem is that using physically accurate values for masses and sizes in the physics model is not likely to produce the best results, or even lead to a stable simulation. The physics modelling presented by this component is independent of the visuals representation, allowing the user to create a stable physical model that has no relationship to the visual model that is driven by the physics.

37.2.2 Integration with X3D

37.2.2.1 Event model evaluation

Evaluating the physics model within the constraints of the X3D event model requires the ability to evaluate time in discreet time chunks. This is known as discreet event simulation.

Evaluation of the physics model is performed once per frame. Since the user needs to be able to modify the model on a frame-by-frame basis, this requires that the physics model is evaluated after all possible user input has been received for that frame. Thus, physics model evaluation is performed just after Step d in 4.4.8.3 Execution model. After evaluating the physics model, the results are used to further modify the existing scene graph. Then rendering is performed.

Physics modelling libraries typically require fixed length time intervals between iterations. A realtime 3D graphics environment typically varies the frame rates based on the current content in view, scripting and other interactions. The implementation of this specification shall be responsible for keeping the physics fixed time interval evaluations synchronised with the varying visual frame time intervals.

Some nodes offer output events that describe output of the physics model, such as the current separation between two bodies or the rate of separation between them. These values are exposed as a set of sensors that can be used to track the output of the physics model and report it at the start of the next frame, in accordance with the standard sensor node model.

37.2.2.2 Transformation hierarchy

The nodes defined in this component are not part of the transformation hierarchy. Instead, the nodes may be linked to parts of the scene graph that are part of the transformation hierarchy in order to affect their motion. They may also be linked as part of the n-body object collision detection capabilities so that a coordinated system of graphics and physics may be modelled.

37.2.3 Bodies

A body represents a section of mass in the system that can be effected by the physics model. A body is represented by the following properties:

A body is a standalone object within a collection. Bodies are influenced by joints that connect this body to another within the collection. Bodies are not required to be connected by a joint and may exist as a standalone entity. All bodies exist within the world space of their collection. There is no concept of a transformation hierarchy of bodies within bodies.

37.2.4 Joints

37.2.4.1 What a joint describes

A joint is used to connect two bodies together in a way that imposes a set of conditions of the movement of one body over the other. Many different joint types are provided allowing the user to constrain the motions of the bodies according to the desired physical properties.

37.2.4.2 Range of motion limits

Each of the joints has a range of motion through which they can travel. This range of motion may be radial angles or linear distance. Typically these values are limited to a single rotation in any one axis.

EXAMPLE 1  2π radians indicates full rotatability.

Each joint contains a set of fields that can be used to limit the range of motions to less than full ability. These fields are termed stops.

A stop is defined by its value and a number of parameters to control the effects output from the physics engine. Firstly, a stop may permit some amount of bouncing due to the action of the joint hitting it.

EXAMPLE 2  In the real world, a lot of stops have a rubber cushion on the end to absorb the impacts and help return the joint to the central position.

37.2.5 Coordinate systems

37.2.5.1 Initial coordinate system

When the two bodies are initially placed in the scene, their initial positions define the resting coordinate frames for the two bodies on that joint. Output values from those joints are then relative to this initial position.

The anchor position and axis values of joints are always specified in world coordinate positions, regardless of whether the two joining bodies have been offset or not.

Mass is defined in kilograms. It is important to note that rigid body physics models, due to floating point inaccuracy calculations cannot typically deal with real-world values. Values provided should be defined in relative proportions rather than absolute values. This will help the model stay stable over long calculation periods

37.2.5.2 Breaking joints

Each joint node will have two output-only fields that indicate the calculated location of the relative positions within their own frame of reference. By comparing the difference between these two values, it is possible to determine if the joint has broken as a result of the input from the last frame. If the joint broke, the difference between the two values will be non-zero (although the author should also allow a small tolerance due to the inaccuracy of floating point calculations.

37.2.5.3 Collision contact description

When a collision is found between two objects, it is described with the following details:

The CollisionCollection node specifies a set of default coefficients to use for all contacts unless overridden by geometry-specific information. These coefficients are generally described using SFVec2f fields. The 2D-vector describes the coefficients for the primary direction for the first value and secondary direction for the second value.

cube 37.3 Abstract types

37.3.1 X3DNBodyCollidableNode

X3DNBodyCollidableNode : X3DChildNode, X3DBoundedObject {
  SFNode     [in,out] metadata     NULL      [X3DMetadataObject]
  SFBool     [in,out] enabled      TRUE
  SFRotation [in,out] rotation     0 0 1 0   [0,1]
  SFVec3f    [in,out] translation  0 0 0     (-?,?)
  SFVec3f    []       bboxCenter   0 0 0     (-?,?)
  SFVec3f    []       bboxSize     -1 -1 -1  [0,?) or -1 -1 -1
}

This abstract node type represents objects that act as the interface between the rigid body physics, collision geometry proxy, and renderable objects in the scene graph hierarchy.

The enabled field is used to specify whether a collidable object is eligible for collision detection interactions.

The translation and rotation fields define an offset from and rotation about the body's center that the collidable node occupies. This can be used to place the collidable geometry in a different location relative to the actual rigid body that has the physics model being applied.

37.3.1 X3DNBodyCollisionSpaceNode

X3DNBodyCollisionSpaceNode : X3DNode, X3DBoundedObject {
  SFNode  [in,out] metadata    NULL      [X3DMetadataObject]
  SFBool  [in,out] enabled     TRUE
  SFVec3f []       bboxCenter  0 0 0     (-?,?)
  SFVec3f []       bboxSize    -1 -1 -1  [0,?) or -1 -1 -1
}

This abstract node type represents objects that act as a self-contained spatial collection of objects that can interact through collision detection routines. Different types of spaces may be defined depending on spatial organization or other optimization mechanisms.

37.3.3 X3DRigidJointNode

X3DRigidJointNode : X3DNode {
  SFNode   [in,out] body1      NULL   [RigidBody]
  SFNode   [in,out] body2      NULL   [RigidBody]
  SFNode   [in,out] metadata   NULL   [X3DMetadataObject]
  MFString [in,out] mustOutput "NONE" ["ALL","NONE",....]
}

This abstract node type is the base type for all joints types, A joint connects two bodies together and constrain the motions of those bodies based on the type of joint. The two fields body1 and body2 define the two bodies in any order. If a body reference is set to NULL then the joint attaches the other body to the ground. The ground is considered to be immovable and not effected by the physics modelling, though the fact that the joint is now connecting an object to the ground will effect how that body and further linked bodies behave. A joint that has neither body set is considered inactive and shall not interact in the physics simulation.

The mustOutput (should this field be called forceOutput?) field is used to control which output fields are to be generated for the next frame. In physics models, the amount of data that can be generated per frame can be quite extensive, particularly in complex models with large numbers of joints. A typical application will need only a few of them, if any at all. This field is used to control which of those outputs the author requires to be generated. The values of the array are to describe the names, exactly, of the output field(s) that are to be updated at the start of the next frame. Two special values are defined: "ALL" and "NONE". If "ALL" is specified anywhere in the string, all fields are to be updated. If "NONE" is specified as the only value, no updates are performed. If the list of values is empty, it shall be treated as if "NONE" were specified. If other values are provided in addition to "NONE", they shall be ignored.

Because computers are not guaranteed to be accurate in their mathematical calculations, and the nature of the discrete timesteps in the evaluation mechanisms, the behaviour of the system will not be 100% accurate. Objects intersect that should not, joints break that should not and so on. Every joint type will have a set of joint-specific fields that define a set of error correction conditions. This allows them to work out when to automatically correct for internally calculated errors, such as object interpenetration. In addition it can be used to control how quickly the errors should be corrected - fast corrections may not always be desirable for the appropriate visual output required.

cube 37.4 Node reference

37.4.1 BallJoint

BallJoint : X3DRigidJointNode {
  SFVec3f  [in,out] anchorPoint         0 0 0
  SFNode   [in,out] body1               NULL   [RigidBody]
  SFNode   [in,out] body2               NULL   [RigidBody]
  SFNode   [in,out] metadata            NULL   [X3DMetadataObject]
  MFString [in,out] mustOutput          "NONE" ["ALL","NONE",...]
  SFVec3f  [out]    body1AnchorPoint
  SFVec3f  [out]    body2AnchorPoint
}

The BallJoint node represents an unconstrained joint between two bodies that pivot about a common anchor point.

body1AnchorPoint and body2AnchorPoint represent the output that describes where the anchorPoint is relative to the two bodies local coordinate reference frame. This can be used to detect if the joint has caused a separation if the two values are not the same for a given frame.

37.4.2 CollidableOffset

CollidableOffset : X3DNBodyCollidableNode {
  SFNode     [in,out] metadata    NULL      [X3DMetadataObject]
  SFBool     [in,out] enabled     TRUE
  SFRotation [in,out] rotation    0 0 1 0   [0,1]
  SFVec3f    [in,out] translation 0 0 0     (-?,?)
  SFVec3f    []       bboxCenter  0 0 0     (-?,?)
  SFVec3f    []       bboxSize    -1 -1 -1  [0,?) or -1 -1 -1
  SFNode     []       collidable  NULL      [X3DNBodyCollidableNode]
}

The CollidableOffset node is used to reposition a piece of geometry relative to the center of the owning body while keeping it consistent within the geometry space.

The collidable field holds a reference to a single nested item of collidable scene graph. If there are multiple transformation paths to this reference, the results are undefined.

37.4.3 CollidableShape

CollidableShape : X3DNBodyCollidableNode  {
  SFNode     [in,out] metadata    NULL      [X3DMetadataObject]
  SFBool     [in,out] enabled     TRUE
  SFRotation [in,out] rotation    0 0 1 0   [0,1]
  SFVec3f    [in,out] translation 0 0 0     (-?,?)
  SFVec3f    []       bboxCenter  0 0 0     (-?,?)
  SFVec3f    []       bboxSize    -1 -1 -1  [0,?) or -1 -1 -1
  SFNode     []       shape       NULL      [Shape]
}

The CollidableShape node represents the glue between the collision detection system, the rigid body model, and the renderable scene graph. Its job is to take a single piece of geometry wrapped in a Shape node and provide a way for the physics model body to move the geometry. In addition, it allows the collision detection system to determine the location of the geometry primitives that it uses for collision management. When placed under a part of the transformation hierarchy, it can be used to visually represent the movement of the object.

The shape field uses the geometry proxy for specifying which geometry best represents the collidable object.

NOTE  Since the shape node is still writable, it is strongly recommended that the author not dynamically change the Shape’s geometry field as it will have large performance impacts due to optimizations used by the collision system.

Not all geometry types are mappable to the collision node type.

EXAMPLE  PointSet

If the containing shape node is given an explicit bounding box size, the geometry shall be approximated using that shape for the purposes of collision detection. If there is no bounding box, the results are implementation-dependent.

37.4.4 CollisionCollection

CollisionCollection : X3DChildNode {
  MFString [in,out] appliedParameters        "BOUNCE"   []
  SFFloat  [in,out] bounce                   0      [0,1]
  MFNode   [in,out] collidables              NULL   [X3DNBodyCollisionSpaceNode, X3DNBodyCollidableNode]
  SFBool   [in,out] enabled                  TRUE
  SFVec2f  [in,out] frictionCoefficients     0 0    [0,?)
  SFNode   [in,out] metadata                 NULL   [X3DMetadataObject]
  SFFloat  [in,out] minBounceSpeed           0.1    [0,?)
  SFVec2f  [in,out] surfaceSpeed             0 0
  SFVec2f  [in,out] slipFactors	             0 0
  SFFloat  [in,out] softnessErrorCorrection  0.8    [0,1]
  SFFloat  [in,out] softnessConstantForceMix 0.0001
}

The CollisionCollection node holds a collection of objects that can be managed as a single entity for resolution of inter-object collisions with other groups of collidable objects. A group consists of both collidable objects as well as spaces that may be collided against each other. A set of parameters are provided that specify default values that will be assigned to all Contact nodes generated from the CollisionSensor node. A user may then override the individual Contact node by inserting a script between the output of the sensor and the input to the RigidBodyCollection node if it is desired to process the contact stream.

The enabled field is used to control whether the collision detection system for this collection should be run at the end of this frame. A value of TRUE enables it while a value of FALSE disables it. A CollisionSensor node watching this collection does not report any outputs for this collection for this frame if it is not enabled.

The bounce field indicates how bouncy the surface contact is. A value of 0 indicates no bounce at all while a value of 1 indicates maximum bounce.

The minBounceSpeed field indicates the minimum speed, in metres per second, that an object shall have before an object will bounce. If the object is below this speed, it will not bounce, effectively having an equivalent value for the bounce field of zero.

The surfaceSpeed field defines the speed in the two friction directions in metres per second. This is used to indicate if the contact surface is moving independently of the motion of the bodies.

EXAMPLE  a conveyor belt.

The softnessConstantForceMix value applies a constant force value to make the colliding surfaces appear to be somewhat soft.

The softnessErrorCorrection determines how much of the collision error should be fixed in a set of evaluations. The value is limited to the range of [0,1]. A value of 0 specifies no error correction while a value of 1 specifies that all errors should be corrected in a single step.

The appliedParameters indicates globally which parameters are to be applied to the collision outputs when passing information into the the rigid body physics system. These parameters specify a series of defaults that apply to all contacts generated. Individual contacts may override which values are applicable, if needed, by setting the field of the same name in the contact itself. The following are valid values:

Each of the entries in the list above should have text describing the effect of that value.

37.4.5 CollisionSensor

CollisionSensor : X3DSensorNode {
  SFNode [in,out] collidables   NULL  [CollisionCollection]
  SFBool [in,out] enabled       TRUE
  SFNode [in,out] metadata      NULL  [X3DMetadataObject]
  MFNode [out]    intersections	      [X3DNBodyCollidableNode]
  MFNode [out]    contacts            [Contact]
  SFBool [out]    isActive
}

The CollisionSensor node is used to send collision detection information into the scene graph for user processing. The collision detection system does not require an instance of this class to be in the scene in order for it to run or affect the physics model. This class is used to report to the user contact information should the user require this information for other purposes.

The contacts field is used to report contacts that were generated as a result of the scene graph changes last frame. This field generates instances of the Contact node.

NOTE  While it is possible to route from this field to the set_contacts field of the RigidBodyCollection node, it is strongly advised that you not do this. The collision system will have already taken these into account internally and processed them in the visual results from the last frame. Setting the values again to the RigidBodyCollection node will result in undefined behaviour.

The contacts field is only available when using the RigidBodyPhysics support level 2 and above.

The CollisionSensor is active (isActive is TRUE) when contacts were located as a result of the movement of the watched objects from last frame.

The intersections field is used to report the colliding geometry that was detected in this last frame.

37.4.6 CollisionSpace

CollisionSpace : X3DNBodyCollisionSpaceNode {
  MFNode  [in,out] collidables NULL      [X3DNBodyCollisionSpaceNode, X3DNBodyCollidableNode]
  SFBool  [in,out] enabled     TRUE
  SFNode  [in,out] metadata    NULL      [X3DMetadataObject]
  SFBool  [in,out] useGeometry FALSE
  SFVec3f []       bboxCenter  0 0 0     (-?,?)
  SFVec3f []       bboxSize    -1 -1 -1  [0,?) or -1 -1 -1
}

The CollisionSpace node holds a collection of objects that can be considered as a single entity for resolution of inter-object collisions with other groups of collidable objects. A group consists of both collidable objects as well as nested collections. This grouping allows creation of efficient collision detection scenarios by grouping functional sets of objects together. Spaces may be collided against each other to determine if the larger group of objects are anywhere near each other. If there is some intersection between two spaces, or between a collidible space and a collidable object, the system will traverse into the contained objects looking for finer resolution on exactly which objects collided together.

The useGeometry field indicates whether the collision detection code should check for collisions down to the level of geometry or only make approximations using the bounds of the geometry. Using the geometry will be more accurate but slower. In most cases, just testing against the bounds of the object is sufficient.

37.4.6 Contact

Contact : X3DNode {
  MFString [in,out] appliedParameters        "BOUNCE"  []
  SFNode   [in,out] body1                    NULL      [RigidBody]
  SFNode   [in,out] body2                    NULL      [RigidBody]
  SFFloat  [in,out] bounce                   0         [0,1]
  SFFloat  [in,out] depth                    0         (-?,?)
  SFVec3f  [in,out] contactNormal            0 1 0     (-?,?)
  SFVec2f  [in,out] frictionCoefficients     0 0       [0,?)
  SFVec3f  [in,out] frictionDirection        0 1 0     (-?,?)
  SFNode   [in,out] geometry1                NULL      [X3DNBodyCollidableNode]
  SFNode   [in,out] geometry2                NULL      [X3DNBodyCollidableNode]
  SFNode   [in,out] metadata                 NULL      [X3DMetadataObject]
  SFFloat  [in,out] minbounceSpeed           0         [0,?)
  SFVec3f  [in,out] position                 0 0 0     (-?,?)
  SFVec2f  [in,out] slipCoefficients         0 0       (-?,?)
  SFVec2f  [in,out] surfaceSpeed             0 0       (-?,?)
  SFFloat  [in,out] softnessErrorCorrection  0.8       [0,1]
  SFFloat  [in,out] softnessConstantForceMix 0.0001    What is the range of this field?
}

The Contact node specifies information concerning a contact between collidible objects and/or spaces.

The position field indicates the exact location of the contact that was made between the two objects.

The contactNormal field is a unit vector describing the normal between the two colliding bodies.

The depth field indicates how deep the current intersection is along the normal vector.

The frictionDirection field is used to control the vector that describes which way friction is to be applied to the contact location. If there is no friction, the direction should be set to 0, 0, 0.

The bounce field indicates how bouncy the surface contact is. A value of 0 indicates no bounce at all while a value of 1 indicates maximum bounce.

The minBounceSpeed field indicates the minimum speed, in metres per second, that an object shall have before an object will bounce. If the object is below this speed, it will not bounce, effectively having an equivalent value for the bounce field of zero.

The surfaceSpeed field defines the speed in the two friction directions in metres per second. This is used to indicate whether the contact surface is moving independently of the motion of the bodies.

EXAMPLE  A conveyor belt mechanism may be stationary while its belt is moving. The object being placed on the conveyor belt will not be affected by the motion of the belt until it is in contact with it.

The softnessConstantForceMix value applies a constant force value to make the colliding surfaces appear to be somewhat soft.

The softnessErrorCorrection determines how much of the collision error should be fixed in a set of evaluations. The value is limited to the range of [0,1] where 0 specifies no error correction while a value of 1 specifies that all errors should be corrected in a single step.

The appliedParameters indicates globally which parameters are to be applied to the collision outputs when passing information into the the rigid body physics system. These parameters specify a series of defaults that apply to all contacts generated. Individual contacts may override which values are applicable, if needed, by setting the field of the same name in the contact itself. The following are valid values:

Each of the entries in the list above should have text describing the effect of that value.

37.4.7 DoubleAxisHingeJoint

DoubleAxisHingeJoint : X3DRigidJointNode {
  SFVec3f  [in,out] anchorPoint               0 0 0
  SFVec3f  [in,out] axis1                     0 0 0
  SFVec3f  [in,out] axis2                     0 0 0
  SFNode   [in,out] body1                     NULL   [RigidBody]
  SFNode   [in,out] body2                     NULL   [RigidBody]
  SFFloat  [in,out] desiredAngularVelocity1   0
  SFFloat  [in,out] desiredAngularVelocity2   0
  SFFloat  [in,out] maxAngle1                 3.147
  SFFloat  [in,out] maxTorque1                0
  SFFloat  [in,out] maxTorque2                0
  SFNode   [in,out] metadata                  NULL   [X3DMetadataObject]
  SFFloat  [in,out] minAngle1                 -3.147
  MFString [in,out] mustOutput                "NONE"  ["ALL","NONE",....]
  SFFloat  [in,out] stopBounce1               0       [0,1]
  SFFloat  [in,out] stopConstantForceMix1	  0.001	  [0,?)
  SFFloat  [in,out] stopErrorCorrection1      0.8     [0,1]
  SFFloat  [in,out] suspensionErrorCorrection 0.8     [0,1]
  SFFloat  [in,out] suspensionForce           0
  SFVec3f  [out]    body1AnchorPoint
  SFVec3f  [out]    body2AnchorPoint
  SFVec3f  [out]    body1Axis
  SFVec3f  [out]    body2Axis
  SFFloat  [out]    hinge1Angle
  SFFloat  [out]    hinge2Angle
  SFFloat  [out]    hinge1AngleRate
  SFFloat  [out]    hinge2AngleRate
}

The DoubleAxisHingeJoint node represents a joint that has two independent axes that are located around a common anchor point. Axis 1 is specified relative to the first body and axis 2 is specified relative to the second body. Axis 1 can have limits and a motor, axis 2 can only have a motor.

The minAngle and maxAngle fields are used to control the maximum angles that the hinge is allowed to travel through. A hinge may not travel more than PI radians in either direction from it's initial position.

The stopBounce1 field is used to set how bouncy the minimum and maximum angle stops are for axis 1. A value of zero means they are not bouncy while a value of 1 means maximum bounciness (full reflection of force arriving at the stop).

The maxTorque1 field defines the maximum amount of torque that the motor can apply on axis 1 in order to achieve the desired desiredAngularVelocity1 value. Similarly, maxTorque2 controls the maximum amount of torque to achieve desiredAngularVelocity2 on axis 2.

The hingeXAngle output fields report the current relative angle between the two bodies in radians and the hingeXAngleRate field describes the rate at which that angle is currently changing in radians per second.

The body anchor point and axis output fields report the current location of the anchor point relative to the corresponding body. This can be used to determine if the joint has broken.

37.4.8 MotorJoint

MotorJoint : X3DRigidJointNode {
  SFFloat  [in,out] axis1Angle           0      Need range limits for these six fields
  SFFloat  [in,out] axis2Angle           0
  SFFloat  [in,out] axis3Angle           0
  SFFloat  [in,out] axis1Torque          0
  SFFloat  [in,out] axis2Torque          0
  SFFloat  [in,out] axis3Torque          0
  SFNode   [in,out] body1                NULL   [RigidBody]
  SFNode   [in,out] body2                NULL   [RigidBody]
  SFNode   [in,out] metadata             NULL   [X3DMetadataObject]
  SFInt32  [in,out] enabledAxes          1	[0,3]
  SFVec3f  [in,out] motor1Axis           0 0 0
  SFVec3f  [in,out] motor2Axis           0 0 0
  SFVec3f  [in,out] motor3Axis           0 0 0
  MFString [in,out] mustOutput           "NONE" ["ALL","NONE",....]
  SFFloat  [in,out] stop1Bounce          0      [0,1]
  SFFloat  [in,out] stop2Bounce          0      [0,1]
  SFFloat  [in,out] stop3Bounce          0      [0,1]
  SFFloat  [in,out] stop1ErrorCorrection 0.8    [0,1]
  SFFloat  [in,out] stop2ErrorCorrection 0.8    [0,1]
  SFFloat  [in,out] stop3ErrorCorrection 0.8    [0,1]
  SFFloat  [out]    motor1Angle
  SFFloat  [out]    motor2Angle
  SFFloat  [out]    motor3Angle
  SFFloat  [out]    motor1AngleRate
  SFFloat  [out]    motor2AngleRate
  SFFloat  [out]    motor3AngleRate
  SFBool   []       autoCalc             FALSE
}

The MotorJoint node allows control of the relative angular velocities between the two bodies associated with a joint. This can be especially useful with a BallJoint where there is no restriction on the angular degrees of freedom.

The autoCalc field is used to control whether the user shall manually provide the individual angle rotations each frame or if they are to be automatically calculated from the motor’s implementation.

The motorAxis fields define the axis vector of the corresponding axis. If the value is 0, 0, 0, the corresponding axis is disabled and the motor does not apply a force or torque along that axis. The motor1Axis field is anchored to the global frame. The motor1Axis field is anchored to body1’s frame of reference, and the motor3Axis field is anchored to body3’s frame of reference.

The three axis angle fields provide angles (in radians) for this frame for the corresponding motor axis when in user-calculated mode.

When the autoCalc field is set to FALSE, the enabledAxes field indicates how many axes can currently be controlled and modified. If the value is zero, the motor is effectively disabled. If the value is 1, only axis1 is enabled, a value of 2 has axis 1 and axis 2 enabled and a value of 3 has all axes enabled.

The motorXAngle output fields provide the calculated angle for this motor joint from the last frame. The motorXAngleRate output fields describe the rate, in radians, that the motor is turning.

The stopXBounce fields describe how much the joint should bounce the body back on the corresponding axis if the joint limit has been reached or exceeded. A value of zero indicates no bounce at all, and a value of one says that it should bounce with velocity equal and opposite to the collision velocity of the contact.

The stopXErrorCorrection fields describe the amount of error correction to be performed in a timestep when the joint reaches the limit on the corresponding axis. A value of zero means no error correction is to be performed and a value of one means all error should be corrected in a single step.

37.4.9 RigidBody

RigidBody : X3DNode {
  SFFloat    [in,out] angularDampingFactor 0.001  [0,1]
  SFVec3f    [in,out] angularVelocity      0 0 0  (-?,?)
  SFBool     [in,out] autoDamp             FALSE
  SFBool     [in,out] autoDisable          FALSE
  SFVec3f    [in,out] centerOfMass         0 0 0  (-?,?)
  SFFloat    [in,out] disableAngularSpeed  0      [0,?)
  SFFloat    [in,out] disableLinearSpeed   0      [0,?)
  SFFloat    [in,out] disableTime          0      [0,?)
  SFBool     [in,out] enabled              TRUE
  SFVec3f    [in,out] finiteRotationAxis   0 0 0  [-1,1]
  SFBool     [in,out] fixed                FALSE
  MFVec3f    [in,out] forces               []
  MFNode     [in,out] geometry             []      [X3DNBodyCollidableNode]
  SFMatrix3f [in,out] inertia	           1 0 0  0 1 0  0 0 1
  SFFloat    [in,out] linearDampingFactor  0.001   [0,1]
  SFVec3f    [in,out] linearVelocity       0 0 0   (-?,?)
  SFFloat    [in,out] mass                 1       (0,?)
  SFNode     [in,out] massDensityModel     NULL    [Sphere, Box, Cone]
  SFNode     [in,out] metadata             NULL    [X3DMetadataObject]
  SFRotation [in,out] orientation          0 0 1 0 [0,1]
  SFVec3f    [in,out] position             0 0 0   (-?,?)
  MFVec3f    [in,out] torques              []
  SFBool     [in,out] useFiniteRotation    FALSE
  SFBool     [in,out] useGlobalGravity     TRUE
}

The RigidBody node describes a body and it's properties that can be effected by the physics model. A body is modelled as a collection of shapes that describe mass distribution rather than renderable geometry. Bodies are connected together using Joints and are represented by geometry.

The geometry field is used to connect the body modelled by the physics engine implementation to the real geometry of the scene through the use of Collidable nodes. This allows the geometry to be connected directly to the physics model as well as collision detection. Collidable objects have their location set to the same location as the body instance they are located in. Their position and location are not relative to this object, unless otherwise defined.

The massDensityModel field is used to describe the geometry type and dimensions used to calculate the mass density in the physics model. This geometry has no renderable property, other than for defining the model of the mass density. It is not rendered, nor modified by the physics model.

The useFiniteRotation field is used to influence the way the body's rotation is calculated. In very fast rotating objects, such as a wheel of a car, an infinitely small timestep can cause the modelling to explode. The default value is to use the faster infinite mode. Setting the field value to TRUE uses the finite calculation model. Using the finite model is more costly to compute but will be more accurate for high rotation speed bodies.

The useGlobalGravity field is used to indicate whether this particular body should be influenced by the containing RigidBodyCollection's gravity setting. A value of TRUE indicates that the gravity is used, a value of FALSE indicates that it will not. This only applies to this body instance. Contained sub-bodies shall not be effected by this setting.

The inertia field represents a 3x2 inertia tensor matrix. If the set values are less than 6 items, then the results are implementation dependent. If the value set is greater than 6 values, only the first 6 values of the array are used.

The fixed field is used to indicate that this body does not move. Any calculations involving collisions with this body should take into account that this body does not move. This is useful for representing objects such as the ground, walls etc that can be collided with, have an effect on other objects, but are not capable of moving themselves.

The mass field indicates the mass of the body in kilograms. All bodies shall have a non-zero mass, with the default value of 1Kg.

The damping factor fields allow the user to instruct the implementation to automatically damp the motion of the body over time. The value of the field is used to take a multiple of the value calculated in the last frame and apply it in opposition to the current motion for this frame. Damping is useful to provide an appearance of frictional forces and also to prevent the body from exploding due to numerical instability of the physics model calculations. Damping is proportional to the current velocity and/or rotation of the object. The application of damping is controlled through the use of the autoDamp field. When the value is FALSE no damping is applied. When the value is true, but rotational and translational damping is calculated and applied.

EXAMPLE: The body is calculated in the previous frame to have a velocity of (0 1 0). A damping factor of 0.01 is active. In this next simulation timestep, a force of 0.01 * (0 1 0) * -1 is applied to the object.

The torques and forces fields define zero or more sets of torque and force values that are applied to the object every frame. These are continuously applied until reset to zero by the user.

The velocity fields are used to provide a constant velocity value to the object every frame. If both forces and velocity are defined, the velocity is used only on the first frame that the node is active, and then the forces are applied. The velocity fields then report the changed values as a result of the application of the physics model in each frame. Setting a new value to the appropriate field will reset the body's velocity for the next frame. Caution must be used in doing this as the underlying physics models may assume some amount of caching between timestep evaluations and instantaneous velocity changes may lead to numerical instability.

The position and orientation fields are used to set the initial conditions of this body's location in world space. After the initial conditions have been set, these fields are used to report the current information based on the most recent physics model evaluation. Setting new values will cause the objects to be moved to the new location and orientation for the start of the next evaluation cycle. Care should be used in manually changing the positiona and orientation as the underlying physics models may cache information between timestep evaluations and sudden instantaneous changes may lead to numerical instability.

The disableX fields define conditions for when the body ceases to considered as part of the rigid body calculations and should be considered as at rest. Due to the numerical instability of physics models, even bodies initially declared to be at rest may gain some amount of movement, even when not effected by an external forces. These values define tolerances for which the physics model should start to ignore this object in any calculation, thus resulting in them being actually at rest and not subject to these instability conditions. Once any one of these values is acheived, then the body is considered as being at rest, unless acted upon by an external force (eg collision or action of connected joint). By default, this automatic disabling is turned off. It may be enabled by setting the autoDisable field to TRUE.

37.4.10 RigidBodyCollection

RigidBodyCollection : X3DChildNode {
  MFNode  [in]     set_contacts            [Contact]
  SFBool  [in,out] autoDisable             FALSE
  MFNode  [in,out] bodies                  []        [RigidBody]
  SFFloat [in,out] constantForceMix        0.0001    [0,?)
  SFFloat [in,out] contactSurfaceThickness 0         [0,?)
  SFFloat [in,out] disableAngularSpeed     0         [0,?)
  SFFloat [in,out] disableLinearSpeed      0         [0,?)
  SFFloat [in,out] disableTime             0         [0,?)
  SFBool  [in,out] enabled                 TRUE
  SFFloat [in,out] errorCorrection         0.8       [0,1]
  SFVec3f [in,out] gravity                 0 -9.8 0
  SFInt32 [in,out] iterations              10	     [0,?)
  MFNode  [in,out] joints                  []        [X3DRigidJointNode]
  SFFloat [in,out] maxCorrectionSpeed      -1        [0,?) or -1
  SFNode  [in,out] metadata                NULL      [X3DMetadataObject]
  SFBool  [in,out] preferAccuracy          FALSE
  SFNode  []       collider                NULL      [CollisionCollection]
}

The RigidBodyCollection node represents a system of bodies that will interact within a single physics model. The collection is not a renderable part of the scene graph nor are its children as a typical model may need to represent the geometry for physics separately, and in less detail, than those needed for visuals.

The bodies field contains a collection of the top-level nodes that comprise a set of bodies that should be evaluated as a single set of interactions.

The joints field is used to register all the joints between the bodies contained in this collection. If a joint is connected between bodies in two different collections, the result is implementation-dependent. If a joint instance is registered with more than one collection, the results are implementation dependent. Joints not registered with any collection are not evaluated.

The enabled field is used to control whether the physics model for this collection should be run this frame. If it was not enabled for the previous frame and is enabled for the first time for the current frame, the time step should be set to XXXXX.

The contactSurfaceThickness field represents how far bodies may interpenetrate after a collision. This allows simulation of softer bodies that may deform somewhat during collision. The default value is zero.

NOTE  Since a value of 0 may cause jittering due to floating point inaccuracy, a very small value of 0.001 may be useful.

The gravity field indicates direction and strength of the local gravity vector for this collection of bodies. The default gravity is standard earth gravity of 9.8m/s2 downwards.

The set_contacts input field is used to provide per-frame sets of information about contacts between bodies in this frame. These contacts are then used to modify the location of the bodies within the scene graph when the physics model is evaluated at the end of the frame. For efficiency, a user may reuse instances of the Contact node for each frame rather than allocating a new instance per frame. A browser implementation shall not make assumptions about the same object instance having the same values each frame.

The preferAccuracy field is used to provide a performance hint to the underlying evaluation about whether the user prefers to have very accurate models or fast models. Accuracy comes at a large penalty in both speed and memory usage, but may not be needed most of the time. The default setting is to optimize for speed rather than accuracy.

The iteractions field is used to control how many iterations over the collections of joints and bodies are to be performed each time the model is evaluated. Rigid body physics is a process of iterative refinement in order to maintain reasonable performance. As the number of iterations grow, the more stable the final results are at the cost of increasing evaluation time. Since maintaining real-time performance is a trade off between accuracy and frame rate, this setting allows the user to control that trade off to a limited extent.

The errorCorrection field describes how quickly the system should resolve intersection errors due to floating point inaccuracies. This value ranges between 0 and 1. A value of 0 means no correction at all while a value of 1 indicates that all errors should be corrected in a single step.

The constantForceMix field can be used to apply damping to the calculations by violating the normal constraints by applying a small, constant force to those calculations. This allows joints and bodies to be a fraction springy, as well as helps eliminate numerical instability. The larger the value, the more soft each of the constraints being evaluated. A value of zero indicates hard constraints, meaning everything is exactly honoured. By combining the errorCorrection and constantForceMix fields, various effects, such as spring-driven or spongy connections, can be emulated.

The collider field associates a collision collection with this rigid body collection allowing seamless updates and integration without the need to use the X3D event model.

The disableX fields define conditions for when the body ceases to considered as part of the rigid body calculations and should be considered as at rest. Due to the numerical instability of physics models, even bodies initially declared to be at rest may gain some amount of movement, even when not effected by an external forces. These values define tolerances for which the physics model should start to ignore this object in any calculation, thus resulting in them being actually at rest and not subject to these instability conditions. Once any one of these values is acheived, then the body is considered as being at rest, unless acted upon by an external force (eg collision or action of connected joint). By default, this automatic disabling is turned off. It may be enabled by setting the autoDisable field to TRUE.

37.4.11 SingleAxisHingeJoint

SingleAxisHingeJoint : X3DRigidJointNode {
  SFVec3f  [in,out] anchorPoint         0 0 0
  SFVec3f  [in,out] axis                0 0 0
  SFNode   [in,out] metadata            NULL   [X3DMetadataObject]
  SFNode   [in,out] body1               NULL   [RigidBody]
  SFNode   [in,out] body2               NULL   [RigidBody]
  SFFloat  [in,out] minAngle            -?
  SFFloat  [in,out] maxAngle            ?
  MFString [in,out] mustOutput "NONE" ["ALL","NONE",....]
  SFFloat  [in,out] stopBounce          0      [0,1]
  SFFloat  [in,out] stopErrorCorrection 0.8    [0,1]
  SFFloat  [out]    angle
  SFFloat  [out]    angleRate
  SFVec3f  [out]    body1AnchorPoint
  SFVec3f  [out]    body2AnchorPoint
}

This node represents a joint with a single axis about which to rotate. As the name suggests, this is a joint that works like a traditional door hinge. The axis of the hinge is defined to be along the unit vector described in the axis field and centered on the anchorPoint described in world coordinates.

The minAngle and maxAngle fields are used to control the maximum angles through which the hinge is allowed to travel. A hinge may not travel more than π radians in either direction from its initial position.

The stopBounce field describes how much the joint should bounce the body back if the joint limit has been reached or exceeded. A value of zero indicates no bounce at all, and a value of one says that it should bounce with velocity equal and opposite to the collision velocity of the contact.

The stopErrorCorrection field describes the amount of error correction to be performed in a timestep when the joint reaches the limit. A value of zero means no error correction is to be performed and a value of one means all error should be corrected in a single step.

The angle output field reports the current relative angle between the two bodies in radians and the angleRate field describes the rate at which that angle is currently changing in radians per second.

The body anchor point output fields report the current location of the anchor point relative to the corresponding body. This can be used to determine if the joint has broken.

37.4.12 SliderJoint

SliderJoint : X3DRigidJointNode {
  SFVec3f  [in,out] axis                0 1 0
  SFNode   [in,out] body1               NULL   [RigidBody]
  SFNode   [in,out] body2               NULL   [RigidBody]
  SFFloat  [in,out] maxSeparation       1      [0,?)
  SFNode   [in,out] metadata            NULL   [X3DMetadataObject]
  SFFloat  [in,out] minSeparation       0      [0,?)
  MFString [in,out] mustOutput          "NONE" ["ALL","NONE",....]
  SFFloat  [in,out] stopBounce          0      [0,1]
  SFFloat  [in,out] stopErrorCorrection 1      [0,1]
  SFFloat  [out]    separation
  SFFloat  [out]    separationRate
}

The SliderJoint node represents a joint where all movement between the bodies is constrained to a single dimension along a user-defined axis.

The axis field indicates which axis along which the two bodies will act. The value should represent a normalized vector.

The sliderForce field value is used to apply a force along the axis of the slider in equal and opposite directions to the two bodies.

If minSeparation is greater than maxSeparation, the stops become ineffective as if the object has no stops at all.

The separation output field is used to indicate the final separation of the two bodies.

The separationRate output field is used to indicate the change in separation over time since the last update.

The stopBounce field describes how much the joint should bounce the body back if the joint limit has been reached or exceeded. A value of zero indicates no bounce at all, and a value of one says that it should bounce with velocity equal and opposite to the collision velocity of the contact.

The stopErrorCorrection field describes the amount of error correction to be performed in a timestep when the joint reaches the limit. A value of zero means no error correction is to be performed and a value of one means all error should be corrected in a single step.

37.4.13 UniversalJoint

UniversalJoint : X3DRigidJointNode {
  SFVec3f  [in,out] anchorPoint          0 0 0
  SFVec3f  [in,out] axis1                0 0 0
  SFVec3f  [in,out] axis2                0 0 0
  SFNode   [in,out] body1                NULL   [RigidBody]
  SFNode   [in,out] body2                NULL   [RigidBody]
  SFNode   [in,out] metadata             NULL   [X3DMetadataObject]
  MFString [in,out] mustOutput           "NONE" ["ALL","NONE",....]
  SFFloat  [in,out] stop1Bounce          0      [0,1]
  SFFloat  [in,out] stop2Bounce          0      [0,1]
  SFFloat  [in,out] stop1ErrorCorrection 0.8    [0,1]
  SFFloat  [in,out] stop2ErrorCorrection 0.8    [0,1]
  SFVec3f  [out]    body1AnchorPoint
  SFVec3f  [out]    body2AnchorPoint
  SFVec3f  [out]    body1Axis
  SFVec3f  [out]    body2Axis
}

A universal joint is like a BallJoint that constrains an extra degree of rotational freedom. Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, the UniversalJoint node keeps axes perpendicular to each other. Thus, rotation of the two bodies about the direction perpendicular to the two axes will be equal.

The vectors specified by the axis1 and axis2 fields shall be perpendicular. If not, the interactions are undefined.

The stopXBounce fields describe how much the joint should bounce the body back on the corresponding axis if the joint limit has been reached or exceeded. A value of zero indicates no bounce at all, and a value of one says that it should bounce with velocity equal and opposite to the collision velocity of the contact.

The stopXErrorCorrection fields describe the amount of error correction to be performed in a timestep when the joint reaches the limit on the corresponding axis. A value of zero means no error correction is to be performed and a value of one means all error should be corrected in a single step.

The body anchor point and axis output fields report the current location of the anchor point relative to the corresponding body. This can be used to determine if the joint has broken.

cube 37.5 Support levels

The Rigid Body Physics component defines two levels of support as specified in Table 37.2.

Table 37.2 — Rigid body physics component support levels

LevelPrequisitesNodes/FeaturesSupport
Level 1 Core 1
Grouping 1
Shape 1
Geometry3D 1
X3DNBodyCollidableNode n/a
X3DNBodyCollisionSpaceNode n/a
CollidableOffset All fields fully supported
CollidableShape All fields fully supported
CollisionCollection All fields fully supported
CollisionSensor All fields fully supported except contacts_changed
CollisionSpace All fields fully supported
Level 2 Core 1
Grouping 1
Shape 1
Geometry3D 1
X3DRigidJointNode n/a
BallJoint All fields fully supported
CollisionSensor All fields fully supported
Contact All fields fully supported
DoubleAxisHingeJoint All fields fully supported
MotorJoint All fields fully supported
RigidBody All fields fully supported
RigidBodyCollection All fields fully supported
SingleAxisHingeJoint All fields fully supported
SliderJoint All fields fully supported
UniversalJoint All fields fully supported
--- X3D separator bar ---