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

37 Rigid body physics

# 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

37.1 Introduction 37.1.1 Name 37.1.2 Overview 37.2 Concepts 37.2.1 Overview 37.2.2 Bodies 37.2.2.1 Event model evaluation 37.2.2.2 Transformation hierarchy 37.2.3 Joints 37.2.3.1 What a joint describes 37.2.3.2 Range of motion limits 37.2.4 Coordinate systems 37.2.4.1 Initial coordinate system 37.2.4.2 Breaking joint 37.2.4.3 Collision contact description 37.3 Abstract types 37.3.1 X3DNBodyCollidableNode 37.3.2 X3DNBodyCollisionSpaceNode 37.3.3 X3DRigidJointNode 37.4 Node reference 37.4.1 BallJoint 37.4.2 CollidableOffset 37.4.3 CollidableShape 37.4.4 CollisionCollection 37.4.5 CollisionSensor 37.4.6 CollisionSpace 37.4.7 Contact 37.4.8 DoubleAxisHingeJoint 37.4.9 MotorJoint 37.4.10 RigidBody 37.4.11 RigidBodyCollection 37.4.12 SingleAxisHingeJoint 37.4.13 SliderJoint 37.4.14 UniversalJoint 37.5 Support levels Table 37.1 — Topics Table 37.2 — appliedParameters valid values Table 37.3 — Rigid body physics component support levels

# 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 ordinary differential equations. Because these equations 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 resulting in visual representations that may 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. That is, 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 immediately before rendering is performed.

Physics modelling libraries typically require fixed length time intervals between iterations. A real-time 3D graphics environment typically varies the frame rates based on:

1. the current content in view,
2. scripting, and
3. other interactions.

An implementation of this specification shall be responsible for keeping the physics fixed time interval evaluations synchronized 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 affected by the physics model. A body is represented by the following properties:

1. mass,
2. density model,
3. position and orientation,
4. linear velocity,
5. angular velocity, and
6. various forces and torques applied.

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 constraints on the movement of the two bodies relative to one another. 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. These same values are also used to perform internal self-correction of objects that have interpenetrated due to the discrete time step intervals that the evaluation of the physics model uses.

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 inaccuracy in floating point 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:

1. a unit vector describing the surface normal from body 1 to body 2 at the point of contact,
2. a primary direction of motion for body 1 relative to body 2, and
3. a second direction that is perpendicular to both the normal and the primary direction is implied for the purposes of providing various sets of coefficients.

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.

# 37.3 Abstract types

## 37.3.1 X3DNBodyCollidableNode

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

The X3DNBodyCollidableNode 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.2 X3DNBodyCollisionSpaceNode

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

The X3DNBodyCollisionSpaceNode 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.

The enabled field specifies whether the collision space is to be considered during collision processing.

## 37.3.3 X3DRigidJointNode

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

The X3DRigidJointNode abstract node type is the base type for all joint types.

The 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 a large number 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 array, all fields are to be updated. If "NONE" is specified, no updates are performed. If the list of values is empty, it shall be treated as if "NONE" were specified. Other values provided in addition to "NONE" shall be ignored.

Because computers are not guaranteed to be accurate in their mathematical calculations and because of the nature of the discrete time steps in the evaluation mechanisms, the behaviour of the system will not be 100% accurate.

EXAMPLE Objects may intersect that should not and joints may break that should not.

Every joint type will have a set of joint-specific fields that define a set of error correction conditions. This error correction conditions provide guidance as to how to automatically correct for internally calculated errors including such errors as object interpenetration. In addition, these error correction conditions 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.

# 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]
      MFString [in,out] forceOutput      "NONE" ["ALL","NONE",...]
      SFNode   [in,out] metadata         NULL   [X3DMetadataObject]
      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 {
      SFBool     [in out] bboxDisplay FALSE
      SFBool     [in,out] enabled     TRUE
      SFNode     [in,out] metadata    NULL     [X3DMetadataObject]
      SFRotation [in,out] rotation    0 0 1 0  [0,1]
      SFVec3f    [in,out] translation 0 0 0    (-∞,∞)
      SFBool     [in out] visible     TRUE
      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  {
      SFBool     [in out] bboxDisplay FALSE
      SFBool     [in,out] enabled     TRUE
      SFNode     [in,out] metadata    NULL     [X3DMetadataObject]
      SFRotation [in,out] rotation    0 0 1 0  [0,1]
      SFVec3f    [in,out] translation 0 0 0    (-∞,∞)
      SFBool     [in out] visible     TRUE
      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 node's geometry field as it may 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] slipFactors	             0 0      (-∞,∞)
      SFFloat  [in,out] softnessConstantForceMix 0.0001   [0,1]
      SFFloat  [in,out] softnessErrorCorrection  0.8      [0,1]
      SFVec2f  [in,out] surfaceSpeed             0 0      (-∞,∞)
    }

The CollisionCollection node holds a collection of objects in the collidables field 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 speed base units, 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 speed base units. 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:

- "BOUNCE": The bounce field value is used.
- "USER_FRICTION": The system will normally calculate the friction direction vector that is perpendicular to the contact normal. This setting indicates that the user-supplied value in this contact should be used.
- "FRICTION_COEFFICIENT-2": The frictionCoefficients field values are used.
- "ERROR_REDUCTION": The softnessErrorCorrection field value in the contact evaluation should be used.
- "CONSTANT_FORCE": The softnessConstantForceMix field value in the contact evaluation should be used.
- "SPEED-1": The surfaceSpeed field value first component is used.
- "SPEED-2": The surfaceSpeed field value second component is used.
- "SLIP-1": The slipFactors field value first component is used.
- "SLIP-2": The slipFactors field value second component is used.

## 37.4.5 CollisionSensor

    CollisionSensor : X3DSensorNode {
      SFNode [in,out] collider      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 collidables field specifies the nodes and spaces that are to be included in collision-detection computations.

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 this not be done. 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] bboxDisplay FALSE
      SFBool  [in,out] enabled     TRUE
      SFNode  [in,out] metadata    NULL     [X3DMetadataObject]
      SFBool  [in,out] useGeometry FALSE
      SFBool  [in out] visible     TRUE
      SFVec3f []       bboxCenter  0 0 0    (-∞,∞)
      SFVec3f []       bboxSize    -1 -1 -1 [0,∞) or -1 -1 -1
    }

The CollisionSpace node holds a collection of objects in the collidables field 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 collidable 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.7 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]
      SFVec3f  [in,out] contactNormal            0 1 0    (-∞,∞)
      SFFloat  [in,out] depth                    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      (-∞,∞)
      SFFloat  [in,out] softnessConstantForceMix 0.0001   [0,1]
      SFFloat  [in,out] softnessErrorCorrection  0.8      [0,1]
      SFVec2f  [in,out] surfaceSpeed             0 0      (-∞,∞)
    }

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

The body1 and body2 fields specify two top-level nodes that should be evaluated in the physics model as a single set of interactions with respect to each other.

The geometry1 and geometry2 fields specify information about body1 and body2.

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 speed base units, 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 speed base units. 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 valid values are specified in Table 37.2:

Table 37.2 — appliedParameters valid values

Value | Meaning
--- | ---
"BOUNCE" | The bounce field value is used.
"USER_FRICTION" | The system will normally calculate the friction direction vector that is perpendicular to the contact normal. This setting indicates that the user-supplied value in this contact should be used.
"FRICTION_COEFFICIENT−2" | The frictionCoefficients field values are used.
"ERROR_REDUCTION" | The softnessErrorCorrection field value in the contact evaluation should be used.
"CONSTANT_FORCE" | The softnessConstantForceMix field value in the contact evaluation should be used.
"SPEED-1" | The surfaceSpeed field value first component is used.
"SPEED-2" | The surfaceSpeed field value second component is used.
"SLIP-1" | The slipFactors field value first component is used.
"SLIP-2" | The slipFactors field value second component is used.

## 37.4.8 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      (-∞,∞)
      MFString [in,out] forceOutput               "NONE" ["ALL","NONE",...]
      SFFloat  [in,out] maxAngle1                 π      [-2π,2π]
      SFFloat  [in,out] maxTorque1                0      (-∞,∞)
      SFFloat  [in,out] maxTorque2                0      (-∞,∞)
      SFNode   [in,out] metadata                  NULL   [X3DMetadataObject]
      SFFloat  [in,out] minAngle1                 -π     [-2π,2π]
      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      [0,∞)
      SFVec3f  [out]    body1AnchorPoint
      SFVec3f  [out]    body1Axis
      SFVec3f  [out]    body2AnchorPoint
      SFVec3f  [out]    body2Axis
      SFFloat  [out]    hinge1Angle
      SFFloat  [out]    hinge1AngleRate
      SFFloat  [out]    hinge2Angle
      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 (specified by the body1 field) and axis 2 is specified relative to the second body (specified by the body2 field). Axis 1 can have limits and a motor, axis 2 can only have a motor.

The minAngle1 and maxAngle1 fields are used to control the maximum angles through which the hinge is allowed to travel. A hinge may not travel more than π radians (or the equivalent angle base units) in either direction from its 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 stopErrorCorrection1 and suspensionErrorCorrection fields describe 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 stopConstantForceMix1 and suspensionForce fields 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 helping to eliminate numerical instability. The larger the value, the more soft each of the constraints being evaluated. A value of zero indicates hard constraints so that everything is exactly honoured. By combining the stopErrorCorrection1 and stopConstantForceMix1 fields and/or the suspensionErrorCorrection and suspensionForce fields, various effects, such as spring-driven or spongy connections, can be emulated.

The maxTorque1 field defines the maximum amount of torque that the motor can apply on axis 1 in order to achieve the 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 angle base units and the hingeXangleRate field describes the rate at which that angle is currently changing in angular_rate angular velocity base units.

The body anchor point and body 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.9 MotorJoint

MotorJoint : X3DRigidJointNode { SFFloat [in,out] axis1Angle 0 [-π,π] SFFloat [in,out] axis1Torque 0 (-∞,∞) SFFloat [in,out] axis2Angle 0 [-π,π] SFFloat [in,out] axis2Torque 0 (-∞,∞) SFFloat [in,out] axis3Angle 0 [-π,π] SFFloat [in,out] axis3Torque 0 (-∞,∞) SFNode [in,out] body1 NULL [RigidBody] SFNode [in,out] body2 NULL [RigidBody] SFInt32 [in,out] enabledAxes 1 [0,3] MFString [in,out] forceOutput "NONE" ["ALL","NONE",...] SFNode [in,out] metadata NULL [X3DMetadataObject] SFVec3f [in,out] motor1Axis 0 0 0 SFVec3f [in,out] motor2Axis 0 0 0 SFVec3f [in,out] motor3Axis 0 0 0 SFFloat [in,out] stop1Bounce 0 [0,1] SFFloat [in,out] stop1ErrorCorrection 0.8 [0,1] SFFloat [in,out] stop2Bounce 0 [0,1] SFFloat [in,out] stop2ErrorCorrection 0.8 [0,1] SFFloat [in,out] stop3Bounce 0 [0,1] SFFloat [in,out] stop3ErrorCorrection 0.8 [0,1] SFFloat [out] motor1Angle SFFloat [out] motor1AngleRate SFFloat [out] motor2Angle SFFloat [out] motor2AngleRate SFFloat [out] motor3Angle SFFloat [out] motor3AngleRate SFBool [] autoCalc FALSE }

The MotorJoint node allows control of the relative angular velocities between the two bodies (specified by the body1 and body2 fields) 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 motorAxis1 field is anchored to the global frame. The motorAxis2 field is anchored to frame of reference for body1, and the motorAxis3 field is anchored to frame of reference for body2.

The three axis angle fields provide angles (in angle base units) 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 motor angle output fields provide the calculated angle in angle base units for this motor joint from the last frame. The motor angle rate output fields describe the rate, in angular_rate angular velocity base units, that the motor is turning.

The stop bounce 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 stop error correction fields describe the amount of error correction to be performed in a time step 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.10 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,∞)
      SFTime     [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 its properties that can be affected 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 nodes have their location set to the same location as the body instance in which they are located. 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 finiteRotationAxis field specifies a vector around which the object rotates.

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 time step 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 is not used. This only applies to this body instance. Contained sub-bodies shall not be affected by this setting.

The inertia field represents a 3x2 inertia tensor matrix. If the set values are less than six items, the results are implementation dependent. If the value set is greater than six values, only the first six 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 mass base units. All bodies shall have a non-zero mass, with the default value of 1 mass base unit.

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, 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 time step, 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 should be used in doing this as the underlying physics models may assume some amount of caching between time step 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 position and orientation as the underlying physics models may cache information between time step evaluations and sudden instantaneous changes may lead to numerical instability.

The disable 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 affected 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 achieved, the body is considered as being at rest unless acted upon by an external force (e.g., 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.

The enabled field controls whether the information in this node is submitted to the physics engine for processing. If the enabled field is set TRUE, the node is submitted to the physics engine. If the enabled field is set FALSE, the node is not submitted to the physics engine for processing.

## 37.4.11 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,∞)
      SFTime  [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.

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 typically small value of 0.001 length base units may be useful.

The gravity field indicates direction and strength (in acceleration base units) of the local gravity vector for this collection of bodies. The default gravity is standard earth gravity of 9.8 meters/second2 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 iterations 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 helping to eliminate numerical instability. The larger the value, the more soft each of the constraints being evaluated. A value of zero indicates hard constraints so that 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 disable 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 affected 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 achieved, the body is considered as being at rest, unless acted upon by an external force (e.g., 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.12 SingleAxisHingeJoint

    SingleAxisHingeJoint : X3DRigidJointNode {
      SFVec3f  [in,out] anchorPoint         0 0 0
      SFVec3f  [in,out] axis                0 0 0
      SFNode   [in,out] body1               NULL   [RigidBody]
      SFNode   [in,out] body2               NULL   [RigidBody]
      MFString [in,out] forceOutput         "NONE" ["ALL","NONE",...]
      SFFloat  [in,out] maxAngle            π      [-2π,2π]
      SFFloat  [in,out] minAngle            -π     [-2π,2π]
      SFNode   [in,out] metadata            NULL   [X3DMetadataObject]
      SFFloat  [in,out] pickable            -π
      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 objects on each side of the hinge are specified by the body1 and body2 fields.

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 (or the equivalent angle base units) 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 time step 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 angle base units and the angleRate field describes the rate at which that angle is currently changing in angular_rate angular velocity base units.

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.13 SliderJoint

    SliderJoint : X3DRigidJointNode {
      SFVec3f  [in,out] axis                0 1 0
      SFNode   [in,out] body1               NULL   [RigidBody]
      SFNode   [in,out] body2               NULL   [RigidBody]
      MFString [in,out] forceOutput         "NONE" ["ALL","NONE",...]
      SFFloat  [in,out] maxSeparation       1      [0,∞)
      SFNode   [in,out] metadata            NULL   [X3DMetadataObject]
      SFFloat  [in,out] minSeparation       0      [0,∞)
      SFFloat  [in,out] sliderForce         0      [-∞,∞)
      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 specified by the body1 and body2 fields 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 (specified in force base units) along the axis of the slider in equal and opposite directions to the two bodies. A positive value applies a force such that the two bodies accelerate away from each other while a negative value applies a force such that the two bodies accelerate toward each other.

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 indicates 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 time step 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.14 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] forceOutput          "NONE" ["ALL","NONE",...]
      SFFloat  [in,out] stopBounce1          0      [0,1]
      SFFloat  [in,out] stop1ErrorCorrection 0.8    [0,1]
      SFFloat  [in,out] stop2Bounce          0      [0,1]
      SFFloat  [in,out] stop2ErrorCorrection 0.8    [0,1]
      SFVec3f  [out]    body1AnchorPoint
      SFVec3f  [out]    body1Axis
      SFVec3f  [out]    body2AnchorPoint
      SFVec3f  [out]    body2Axis
    }

A universal joint is like a BallJoint that constrains an extra degree of rotational freedom. Given the axis specified by the axis1 field on the body specified by the body1 field, and the axis specified by the axis2 field on body2 that is perpendicular to axis1, the UniversalJoint node keeps the 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 stop bounce 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 indicates that it should bounce with velocity equal and opposite to the collision velocity of the contact.

The stop error correction fields describe the amount of error correction to be performed in a time step 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 body 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.5 Support levels

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

Table 37.3 — Rigid body physics component support levels

Level | Prerequisites | Nodes/Features | Support
--- | --- | --- | ---
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.
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.