Sets physics body motion type (0=static immovable, 1=kinematic script-controlled, 2=dynamic physics-simulated).
Takes bodyHandle (physics body handle from b3dCreatePhysicsBody), bodyType (0=static, 1=kinematic, 2=dynamic).
Returns nothing (void function).
3D Graphics
Parameters & Returns
Parameters
bodyHandleInt
bodyTypeInt
Returns
Void
Quick Summary
Sets physics body motion type (0=static immovable, 1=kinematic script-controlled, 2=dynamic physics-simulated).
Takes bodyHandle (physics body handle from b3dCreatePhysicsBody), bodyType (0=static, 1=kinematic, 2=dynamic).
Returns nothing (void function).
Technical Exegesis...
Sets physics body motion type (0=static immovable, 1=kinematic script-controlled, 2=dynamic physics-simulated). Takes bodyHandle (physics body handle from b3dCreatePhysicsBody), bodyType (0=static immovable infinite mass, 1=kinematic script-controlled no physics forces, 2=dynamic fully physics-simulated affected by forces/gravity). Returns nothing (void function, no return value). Changes Jolt body's EMotionType, affects how body interacts with physics simulation.
Sets physics body motion type (0=static immovable, 1=kinematic script-controlled, 2=dynamic physics-simulated). Takes bodyHandle (physics body handle from b3dCreatePhysicsBody), bodyType (0=static immovable infinite mass, 1=kinematic script-controlled no physics forces, 2=dynamic fully physics-simulated affected by forces/gravity). Returns nothing (void function, no return value). Changes Jolt body's EMotionType, affects how body interacts with physics simulation.
Body types determine how physics bodies behave in simulation. Static (0): immovable infinite mass, not affected by any forces/collisions, never moves during simulation, collision layer NON_MOVING, used for walls/floors/terrain/buildings, most efficient (no simulation overhead), good for level geometry. Kinematic (1): movable by script only, not affected by physics forces/gravity/collisions, can be moved with b3dSetPhysicsBodyPosition/Rotation/Velocity, pushes dynamic bodies when moving (acts like moving platform), collision layer MOVING, used for elevators/doors/moving platforms/scripted animations, medium efficiency (collision detection but no force solving). Dynamic (2): fully physics-simulated, affected by gravity/forces/collisions/constraints, moves based on applied forces (b3dApplyPhysicsImpulse/Torque), collision layer MOVING, used for player/crates/projectiles/ragdolls, most expensive (full simulation every frame).
Type change process: (1) validates bodyHandle exists in g_bodyHandleToBodyID map (early return if not found), (2) validates g_physicsSystem initialized (early return if not), (3) converts bodyType Int to Jolt EMotionType enum (0→Static, 1→Kinematic, 2→Dynamic), (4) calls bodyInterface.SetMotionType(bodyID, motionType, EActivation::Activate), (5) SetMotionType handles all internal Jolt state changes (collision layer, activation state, mass properties). Thread safety: SetMotionType is thread-safe (Jolt handles locking internally), safe to call during simulation, change takes effect at next physics step.
Typical usage patterns: Anchor for pendulum: body1 = b3dCreatePhysicsBody(anchor, 0, 1.0, 2, 2, 2) creates with mass (dynamic initially), b3dSetPhysicsBodyType(body1, 0) converts to static immovable anchor, b3dCreatePointConstraint(body1, body2, ...) attaches dynamic body2 to static anchor. Moving platform: platform = b3dCreatePhysicsBody(plat, 0, 0.0, 10, 1, 10) creates static, b3dSetPhysicsBodyType(platform, 1) converts to kinematic, b3dSetPhysicsBodyPosition(platform, x, y + Sin(t), z) script-controlled movement, pushes player standing on platform. Temporary static: b3dSetPhysicsBodyType(body, 0) freeze object in place, later b3dSetPhysicsBodyType(body, 2) unfreeze to resume physics. Toggle physics: If frozen Then b3dSetPhysicsBodyType(body, 0) Else b3dSetPhysicsBodyType(body, 2) toggle between frozen and simulated.
Physics behavior changes: Static→Dynamic (0→2): body suddenly affected by gravity (falls if unsupported), begins responding to forces/collisions, activation state set to active (participates in simulation). Dynamic→Static (2→0): body freezes in current position (infinite mass), stops responding to gravity/forces, collision layer changes to NON_MOVING (improves broad-phase culling). Static→Kinematic (0→1): body becomes script-movable (can set position/velocity), still not affected by physics forces, collision layer changes to MOVING (can push dynamic bodies). Kinematic→Dynamic (1→2): body begins physics simulation from current state (velocity preserved), starts falling under gravity, begins responding to forces/collisions. Dynamic→Kinematic (2→1): body stops physics simulation (gravity/forces no longer apply), velocity preserved but not affected by forces anymore, can be controlled with Set functions.
Motion type details: Static (EMotionType::Static): GetInverseMass() returns 0 (infinite mass), GetInverseInertia() returns zero matrix (infinite rotational inertia), never activated (not in active body list), not updated by physics solver (zero cost), collision pairs cached aggressively (assumes never moves). Kinematic (EMotionType::Kinematic): GetInverseMass() returns 0 (acts like infinite mass for collisions), velocity can be set manually (moves at specified velocity), affects dynamic bodies in collision (pushes them), updated by integration step (applies velocity to position), can be activated/deactivated like dynamic. Dynamic (EMotionType::Dynamic): GetInverseMass() = 1/mass (finite mass from b3dCreatePhysicsBody), affected by gravity (acceleration = gravity * mass), force accumulation (F=ma applied each frame), constraint solving (participates in all constraints), continuous collision if fast-moving (prevents tunneling).
Activation behavior: EActivation::Activate parameter ensures body wakes up after type change, activated bodies participate in simulation immediately (not sleeping), deactivated bodies skip simulation until touched (performance optimization), type change to Static automatically deactivates (static never needs activation), type change to Dynamic/Kinematic activates (ensures immediate response). Manual deactivation: call b3dSetPhysicsBodyPosition then bodyInterface.DeactivateBody() to put body to sleep (advanced usage).
Common use cases: (1) Constraint anchors (create dynamic body with mass, set to static before creating constraint, ensures immovable anchor point), (2) Moving platforms (kinematic body moved by script, pushes dynamic player/objects), (3) Freeze/unfreeze objects (toggle between static frozen and dynamic simulated), (4) Doors (kinematic for scripted open/close animation), (5) Elevators (kinematic with script-controlled vertical movement), (6) Breakable supports (static support beam, set to dynamic when destroyed to fall). Performance: static bodies have zero simulation cost (not updated), kinematic bodies low cost (position integration only, no force solving), dynamic bodies full cost (gravity, forces, constraints, collisions).
Prerequisites: g_physicsSystem must be initialized (b3dInitPhysics called), bodyHandle must be valid (from b3dCreatePhysicsBody, exists in g_bodyHandleToBodyID). Returns early if: g_physicsSystem is null (not initialized), bodyHandle not found in map (invalid handle). No error messages printed (silent failure), check handle validity before calling if unsure. Body type persistence: type change persists until changed again or body destroyed, survives across frames (permanent change), not reset by collision or other events.
Mass property handling: Static→Dynamic preserves original mass from b3dCreatePhysicsBody (mass restored from g_bodyCreationData), Dynamic→Static sets infinite mass (GetInverseMass = 0), type changes update MotionProperties (Jolt internal structure for mass/inertia). Original mass stored in g_bodyCreationData.mass (created during b3dCreatePhysicsBody), restored if converting back to dynamic. Inertia tensor recalculated when changing to dynamic (based on shape and mass).
Collision layer changes: Static bodies use NON_MOVING layer (collision filter optimization), Dynamic/Kinematic use MOVING layer (collides with both static and dynamic), layer change happens automatically in SetMotionType (no manual layer management needed). Broad-phase optimization: static-static pairs never checked (both immovable), static-dynamic pairs checked once then cached (static never moves), dynamic-dynamic pairs checked every frame (both can move).
Common mistakes: forgetting to set anchor static before creating constraint (both bodies fall together if both dynamic), setting body to kinematic then expecting gravity to work (kinematic ignores forces), changing type mid-constraint without checking (can cause constraint solving issues), setting to static while body has velocity (velocity preserved but ignored until type changed back). Best practice: set to static BEFORE creating constraint as anchor (ensures constraint setup correct), set to kinematic BEFORE scripted movement (clear motion intent), set to dynamic AFTER positioning (prevents falling during setup).
Related functions: b3dCreatePhysicsBody sets initial mass (dynamic if mass>0, effectively static if mass=0 but not true static), b3dSetPhysicsBodyPosition moves body (works for all types but kinematic/dynamic may override), b3dSetPhysicsBodyVelocity sets velocity (only meaningful for kinematic/dynamic, ignored for static), b3dApplyPhysicsImpulse applies force (only affects dynamic bodies, no effect on static/kinematic), b3dCreatePointConstraint creates constraint (typically connects static anchor to dynamic weight). Body property queries: bodyInterface.GetMotionType(bodyID) returns current type (not exposed to BambooBasic yet), bodyInterface.GetInverseMass(bodyID) returns 0 for static/kinematic or 1/mass for dynamic.
Advanced usage: Scripted ragdoll (start kinematic for animation, switch to dynamic on death for physics), Destructible buildings (static parts, switch to dynamic when destroyed to fall), Kinematic character controller (kinematic body moved by input, pushes physics objects), Conveyor belts (kinematic with surface velocity to move objects), Crane physics (kinematic arm movement, dynamic hanging load on constraint). Debugging: print body position before/after type change (verify behavior), check if body falling (indicates dynamic type), try impulse to test if dynamic (b3dApplyPhysicsImpulse has no effect on static/kinematic).
Implementation notes: calls Jolt's BodyInterface::SetMotionType directly (no custom wrapper needed), BodyInterface handles all state transitions internally (safe to call at any time), no validation of bodyType parameter (out-of-range values default to dynamic via switch default case), supports all Jolt motion type transitions (any type can change to any other type). Motion type enum: 0 maps to EMotionType::Static, 1 maps to EMotionType::Kinematic, 2 maps to EMotionType::Dynamic (direct integer mapping for simplicity).
Example
Example.bam
; Create anchor body (initially dynamic with mass)Local anchor:Int = b3dCreateCube(1, 0, 0)
b3dPositionEntity(anchor, 0, 10, 0)
Local anchorBody:Int = b3dCreatePhysicsBody(anchor, -1, 1.0, 0, 0, 0)
; Convert to static BEFORE creating constraint
b3dSetPhysicsBodyType(anchorBody, 0) ; 0 = static (immovable)
; Create dynamic weightLocal weight:Int = b3dCreateCube(1, 0, 0)
b3dPositionEntity(weight, 0, 5, 0)
Local weightBody:Int = b3dCreatePhysicsBody(weight, -1, 1.0, 0, 0, 0)
; weightBody is already dynamic (type 2); Create constraint between static anchor and dynamic weightLocal constraint:Int = b3dCreatePointConstraint(anchorBody, weightBody, 0, -1, 0, 0, 1, 0)
; Later: make anchor kinematic to move it with script
b3dSetPhysicsBodyType(anchorBody, 1) ; 1 = kinematic
b3dSetPhysicsBodyPosition(anchorBody, 0, 10 + Sin(GetTimer()), 0)
; Or freeze weight in mid-air
b3dSetPhysicsBodyType(weightBody, 0) ; 0 = static (freeze)