Rigid Body Physics

Assigning Rigid Body Behavior

Instances of FBModel can be assigned to a Rigid Body Physical Property, allowing them to react to forces such as gravity. Models connected to a Rigid Body Physical Property can also collide among each other, as well as with the scene's ground plane.

A Rigid Body Physical Property object is instantiated via FBCreateObject(), using the 'Browsing/Templates/Physical Properties' Asset Browser path, and the 'Rigid Body' entry name. Models are connected to a Rigid Body Physical Property using FBConnect().

# Apply a Rigid Body physical property to the models.
# The pActivation parameter defines the Activation value.
# 0: Active | 1: Active at Collision | 2: Passive
def applyRigidBody(pModelList, pActivation):
    # Create the rigid body object from the Asset Browser.
    rigidBody = FBCreateObject( 'Browsing/Templates/Physical Properties', 'Rigid Body', 'Rigid Body' )
    
    # Set the Activation property.
    activationProp = rigidBody.PropertyList.Find('Activation')
    activationProp.Data = pActivation
    
    # If we are using Active activation, set the Correct Mass Center to false.
    if(pActivation == 0) :    
        correctMassCenter = rigidBody.PropertyList.Find('Correct Mass Center')
        correctMassCenter.Data = False
    
    # Connect the rigid body to the models.
    for model in pModelList:
        FBConnect(rigidBody, model)

The 'Activation' property of a Rigid Body Physical Property denotes when the rigid body behavior of the connected models activates. The accepted values for the 'Activation' property are described below.

Activation Value Description
0 Active. The connected models react to physical forces when the session is set to Live or when recording begins.
1 Active at Collision. A connected model only begins to react to physical forces when another model collides with it or if it is manipulated.
2 Passive. The connected models are not affected by physical forces (ex: gravity), but can collide with other objects.

Creating a Physics Solver

The rigid body calculations are solved by a Physics Solver, which must be added to the scene via FBCreateObject() using the Asset Browser path 'Browsing/Templates/Solvers' and the 'Physics Solver' entry name. The 'Gravity' property of the Physics Solver object defines the direction of gravity. The default value for the 'Gravity' property is (0, -9.81, 0).

# Create a physics solver.
def createPhysicsSolver():
    solver = FBCreateObject( 'Browsing/Templates/Solvers', 'Physics Solver', 'Physics Solver' )
    
    # Set the gravity to accelerate upwards.
    solver.PropertyList.Find('Gravity').Data = FBVector3d(0, 9.81, 0)
    
    # Activate the Physics solver.
    solver.Active = True
    solver.Live = True

Example: Grid Collision

Sample Viewport Output:

Program Summary: In the following program, a large cube collides with a grid of smaller cubes below it. The large cube's Rigid Body Physical Property has its Activation set to 0 (active), allowing it to fall when the program is run. The Rigid Body Physical Property bound to the smaller cubes has its Activation set to 1 (active on collision), making the smaller cubes fall to the ground plane if they experience a collision.

from pyfbsdk import *

###############################################################
# Helper Function(s).                                         #
###############################################################

# Create a primitive from the asset browser.
def createModel(pTranslation, pScalingCoefficient):    
    #model = FBCreateObject( 'Browsing/Templates/Elements/Primitives', 'polySphere', 'polySphere' )
    model = FBCreateObject( 'Browsing/Templates/Elements/Primitives', 'Cube', 'Cube' )
    model.Name = 'myModel'
    model.Translation = pTranslation
    model.Scaling = FBVector3d(pScalingCoefficient, pScalingCoefficient, pScalingCoefficient)
    model.Show = True
    
    return model


# Create a planar grid of models.
def createGrid(pCenter, pModelsPerSide):
    gridModels = []
    spacing = 20
    for i in range(-int(pModelsPerSide/2), int(pModelsPerSide/2) + 1):
        for j in range(-int(pModelsPerSide/2), int(pModelsPerSide/2) + 1):
            xOffset = pCenter[0] + i * spacing
            yOffset = pCenter[1]
            zOffset = pCenter[2] + j * spacing
            # Create the model at the specific offset.
            model = createModel(FBVector3d(xOffset, yOffset, zOffset), 0.65)
            gridModels.append(model)
    
    return gridModels


# Apply a Rigid Body physical property to the models.
# The pActivation parameter defines the Activation value.
# 0: Active | 1: Active at Collision | 2: Passive
def applyRigidBody(pModelList, pActivation):
    # Create the rigid body object from the Asset Browser.
    rigidBody = FBCreateObject( 'Browsing/Templates/Physical Properties', 'Rigid Body', 'Rigid Body' )
    
    # Set the Activation property.
    activationProp = rigidBody.PropertyList.Find('Activation')
    activationProp.Data = pActivation
    
    # If we are using Active activation, set the Correct Mass Center to false.
    if(pActivation == 0) :    
        correctMassCenter = rigidBody.PropertyList.Find('Correct Mass Center')
        correctMassCenter.Data = False
    
    # Connect the rigid body to the models.
    for model in pModelList:
        FBConnect(rigidBody, model)


# Create a physics solver.
def createPhysicsSolver():
    solver = FBCreateObject( 'Browsing/Templates/Solvers', 'Physics Solver', 'Physics Solver' )

    # Set the gravity to accelerate slowly downwards.
    solver.PropertyList.Find('Gravity').Data = FBVector3d(0, -2, 0)
    
    # Activate the Physics solver.
    solver.Active = True
    solver.Live = True



###############################################################
# Main.                                                       #
###############################################################

FBApplication().FileNew()

model = createModel(FBVector3d(0, 200, 20), 1.5)
applyRigidBody([model], 0) # Active

gridModels = createGrid(FBVector3d(0, 75, 0), 7)
applyRigidBody(gridModels, 1) # Active at Collision

createPhysicsSolver()