Blitz3D+ Command Reference

ParticleCollision emitter,physics_world,radius#,bounce#,friction#

Parameters

emitter - CPU or GPU particle emitter entity

physics_world - Box3D world to collide against; 0 turns particle collision off

radius# - radius of each particle for collision, in world units

bounce# - how much speed is kept when bouncing, 0 to 1. 0 makes particles stick flat, 1 is a full bounce

friction# - how much sideways speed is scrubbed off on impact, 0 to 1. 0 slides freely, 1 stops sliding

Description

Makes an emitter's particles bounce off a Box3D physics world.

Collision is CPU-only. GPU emitters accept disabling with world 0; a nonzero world raises a runtime error and records ParticleError$ without changing the configuration.

This is what turns a spark shower into something that belongs in the scene: sparks that skitter across the floor, debris that piles against a wall, rain that stops at a roof instead of falling through it. Each particle is swept along its path every step, so fast particles cannot tunnel through thin geometry the way a simple point test would.

The world you pass is a Box3D physics world, so the geometry particles hit is whatever has a physics body in that world - not the visual meshes. Build the collision world first, then point the emitter at it. Pass 0 as the world to switch collision back off; the other arguments are still remembered.

Bounce and friction shape the impact. High bounce with low friction gives lively pinging sparks; low bounce with high friction gives wet debris that lands and stays. The radius should be about the visible size of a particle - too small and fast particles clip into surfaces before reacting, too large and they appear to stop short.

Gotcha: collision is the most expensive thing an emitter can do, because it is a swept query per particle per step. Keep collision-enabled emitters to modest particle counts and leave big atmospheric clouds uncollided. Loading a ParticlePreset switches collision off as part of its reset, so configure collision after the preset. Every bounce is counted by ParticleCollisionCount.

Requires Extended mode.

See also: ParticleCollisionCount, CreatePhysicsWorld, CreatePhysicsBody, ParticleGravity, ParticleMax.

Example

; ParticleCollision Example
; -------------------------
; Requires Extended mode.

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

camera=CreateCamera()
PositionEntity camera,0,2,-6
CameraClsColor camera,8,12,24

; A Box3D physics world with a static slab for particles to bounce on
world=CreatePhysicsWorld()
slab=CreateCube()
ScaleEntity slab,3,0.25,3
PositionEntity slab,0,0.25,0
EntityColor slab,55,60,72
slab_body=CreatePhysicsBody(world,slab,0)
slab_shape=PhysicsBodyBox(slab_body,6,0.5,6,0)

; Sparks raining down onto the slab
emitter=CreateParticleEmitter(600)
PositionEntity emitter,0,3.5,0
ParticlePreset emitter,4
ParticleEmissionRate emitter,120
ParticleGravity emitter,0,-6,0

; Enable swept collision against the physics world
ParticleCollision emitter,world,0.04,0.65,0.15
colliding=True

While Not KeyDown(1)

    ; Space toggles collision - pass zero as the world to disable it
    If KeyHit(57)
        colliding=Not colliding
        If colliding
            ParticleCollision emitter,world,0.04,0.65,0.15
        Else
            ParticleCollision emitter,0,0,0,0
        EndIf
    EndIf

    ; 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

    ; UpdateWorld also advances the particle simulation
    UpdateWorld
    RenderWorld

    Text 0,0,"Arrow keys: move camera   Space: toggle collision   Esc: exit"
    If colliding Then state$="ParticleCollision emitter,world,0.04,0.65,0.15 (sparks bounce)" Else state$="ParticleCollision emitter,0,0,0,0 (sparks fall through)"
    Text 0,20,state$

    Flip

Wend

FreePhysicsWorld world
End

Index