Blitz3D+ Command Reference

PhysicsBodyMassData body,mass#,x#,y#,z#,ixx#,iyy#,izz#[,ixy#][,ixz#][,iyz#]

Parameters

body - live physics-body handle

mass# - positive mass in kilograms

x# - local centre X coordinate, metres
y# - local centre Y coordinate, metres
z# - local centre Z coordinate, metres

ixx# - local tensor XX entry about the centre, kg m2

iyy# - local tensor YY entry about the centre, kg m2

izz# - local tensor ZZ entry about the centre, kg m2

ixy# (optional) - symmetric XY/YX tensor entry; 0 (default)
ixz# (optional) - symmetric XZ/ZX tensor entry; 0 (default)

iyz# (optional) - symmetric YZ/ZY tensor entry; 0 (default)

Description

Sets a dynamic body's mass, centre of mass and inertia tensor directly.

Assigns a dynamic body's complete mass properties: positive mass in kilograms, an unscaled body-local centre in metres, and a symmetric inertia tensor about that centre in kilograms times square metres. The six tensor entries are XX, YY, ZZ, XY, XZ and YZ; off-diagonal arguments are actual tensor entries, not unsigned products of inertia.

Handles must be live and of the correct kind. Readbacks do not wake or mutate bodies. Row and column arguments use 1=X, 2=Y, 3=Z; invalid indices raise a runtime error.

Density must be finite and non-negative. Density edits are checked for representable shape and combined mass properties before changing native data, including when staged. Recalculation includes every volumetric shape, including sensors; density zero contributes no mass. Triangle meshes and terrain have zero mass and inertia. Static and kinematic bodies have zero body mass and inertia, while their volumetric shapes still have individually computable mass.

PhysicsBodyMassData accepts dynamic bodies only. Mass must be positive with a finite reciprocal. The local centre and its velocity correction must be representable. The full symmetric tensor must be positive definite, physically admissible (its principal moments obey triangle inequalities), and invertible in native single precision. Diagonal values alone do not establish validity. Singular point/rod tensors and tensors whose determinant or inverse underflows/overflows are rejected; a nonsingular planar tensor such as diagonal (1,1,2) is accepted. Use PhysicsBodyMotionLocks for constrained rotation.

RecalculatePhysicsBodyMass, PhysicsShapeDensity with recalculate=True, adding/freeing a collider, changing body mode, and entering/leaving the state with all three angular axes locked replace custom mass with shape-derived data. Repeating the same density with True still recalculates; repeating the same body mode or lock mask does not. A density edit with False preserves current body mass until a later recalculation. Material changes and ResetPhysicsBody retain it. A fully angular-locked body reports zero effective body inertia, including after custom mass is assigned; partial locks retain the tensor.

Density recalculation and custom-mass assignment wake enabled bodies and keep the body origin/collider pose fixed. The centre-of-mass linear velocity is adjusted to preserve velocities at body-fixed points; linear/angular momentum need not be conserved. Disabled bodies stay disabled and receive the same correction to their saved velocities. Staging density alone does not wake the body. Existing motion locks continue to constrain motion. Mass edits are included in native physics recording/replay.

Requires Extended mode.

See also: PhysicsBodyMass, PhysicsShapeDensity, RecalculatePhysicsBodyMass, PhysicsBodyLocalInertia, PhysicsBodyWorldInverseInertia, PhysicsBodyMotionLocks.

Example

; PhysicsBodyMassData Example
; ---------------------------
; Requires Extended mode.

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Const PHYSICS_STATIC=0
Const PHYSICS_DYNAMIC=2

camera=CreateCamera()
PositionEntity camera,0,3,-7
RotateEntity camera,20,0,0

light=CreateLight()
RotateEntity light,45,-30,0
AmbientLight 60,60,60

; An independent Box3D world with standard gravity
world=CreatePhysicsWorld()

; Blue static floor
ground=CreateCube()
ScaleEntity ground,6,0.5,6
PositionEntity ground,0,-0.5,0
EntityColor ground,80,160,255
ground_body=CreatePhysicsBody(world,ground,PHYSICS_STATIC)
ground_shape=PhysicsBodyBox(ground_body,12,1,12)

; A hammer: one body with a light handle and a heavy head
hammer=CreatePivot()
grip=CreateCube(hammer)
ScaleEntity grip,0.1,1,0.1
EntityColor grip,200,150,90
head=CreateCube(hammer)
ScaleEntity head,0.5,0.25,0.25
PositionEntity head,0,1,0
EntityColor head,150,150,160
hammer_body=CreatePhysicsBody(world,hammer,PHYSICS_DYNAMIC)
grip_shape=PhysicsBodyBox(hammer_body,0.2,2,0.2,1)
head_shape=PhysicsBodyBox(hammer_body,1,0.5,0.5,8,0,1,0)
ResetPhysicsBody hammer_body,0,0.3,0,0,0,Pi/2

; A yellow marker shows the centre of mass
marker=CreateSphere(8)
ScaleEntity marker,0.12,0.12,0.12
EntityColor marker,255,230,60
EntityOrder marker,-1

custom=False

While Not KeyDown(1)

    ; Space tosses the hammer, R lays it down again
    If KeyHit(57)
        PhysicsBodyImpulse hammer_body,0,8,0
        PhysicsBodyAngularImpulse hammer_body,0,0,3
    EndIf
    If KeyHit(19) Then ResetPhysicsBody hammer_body,0,0.3,0,0,0,Pi/2

    ; M swaps between a custom centre of mass at the handle's end and the shapes' own
    If KeyHit(50)
        custom=Not custom
        If custom
            PhysicsBodyMassData hammer_body,5,0,-1,0,1,0.1,1
        Else
            RecalculatePhysicsBodyMass hammer_body
        EndIf
    EndIf

    StepPhysics world,1.0/60.0,4
    PositionEntity marker,PhysicsBodyCenterX(hammer_body),PhysicsBodyCenterY(hammer_body),PhysicsBodyCenterZ(hammer_body)

    ; Arrow keys move the camera
    If KeyDown(200) Then MoveEntity camera,0,0,0.1
    If KeyDown(208) Then MoveEntity camera,0,0,-0.1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    RenderWorld

    Text 0,0,"Arrow keys: move camera   Space: toss   R: reset   M: custom / shape mass"
    Text 0,20,"Esc: exit"
    Text 0,40,"Custom mass data: "+custom+"   mass "+PhysicsBodyMass(hammer_body)+" kg"
    Text 0,60,"(local centre: X "+PhysicsBodyLocalCenterX(hammer_body)+", Y "+PhysicsBodyLocalCenterY(hammer_body)+", Z "+PhysicsBodyLocalCenterZ(hammer_body)+")"

    Flip

Wend

FreePhysicsWorld world
End

Index