Codea icon Physics 3D

Reference › Dynamic motion with forces, joints and collisions in 3D

Guides

3D Physics in Codea top ↑

Overview

Use 3D physics to make objects fall, roll, and collide in a 3D world. Codea uses the Bullet physics engine to simulate their motion.

Add physics bodies to a scene for automatic simulation, or create a physics3d.world and advance it yourself.

Creating Physics Worlds

Create a world, add bodies, and advance it with world:step():

Show code (25 lines)
function setup()
    world = physics3d.world()
    world.gravity = vec3(0, -9.8, 0)

    -- Create a ground plane
    ground = world:body(physics3d.STATIC)
    ground:add(physics3d.plane(vec3(0, 1, 0), 0))

    -- Create a dynamic sphere
    ball = world:body(physics3d.DYNAMIC)
    ball:add(physics3d.sphere(0.5))
    ball.position = vec3(0, 5, 0)
end

function update(dt)
    world:update(dt)
end

function draw()
    -- Draw the ball position
    pushMatrix()
    translate(ball.position.x, ball.position.y, ball.position.z)
    sphere(0.5)
    popMatrix()
end

Body types:

  • physics3d.STATIC — does not move, acts as immovable scenery
  • physics3d.DYNAMIC — moved by forces and collisions
  • physics3d.KINEMATIC — moved manually via code, pushes dynamic bodies without being affected by gravity

Using Physics with Entities

When working with a scene, attach physics components directly to entities:

Show code (25 lines)
function setup()
    scn = scene()

    local cam = scn:entity("camera")
    cam:add(camera.perspective(60))
    cam:add(camera.rigs.orbit)
    cam.z = -10

    -- Static ground
    local ground = scn:entity("ground")
    ground:add(mesh.plane())
    ground:add(physics3d.body(physics3d.STATIC))
    ground:add(physics3d.box(vec3(10, 0.1, 10)))
    ground.material = material.lit()

    -- Dynamic box
    local box = scn:entity("box")
    box:add(mesh.box())
    box:add(physics3d.body(physics3d.DYNAMIC))
    box:add(physics3d.box(vec3(1, 1, 1)))
    box.y = 5
    box.material = material.lit()

    scene.main = scn
end

The scene automatically steps the physics simulation each frame.

Collision Shapes

Choose the collision shape that best matches your object’s visual appearance. Simpler shapes perform better:

  • physics3d.sphere(radius) — sphere
  • physics3d.box(halfExtents) — axis-aligned box, parameter is half-widths as a vec3
  • physics3d.capsule(radius, height) — capsule (good for characters)
  • physics3d.cylinder(radius, height) — cylinder
  • physics3d.cone(radius, height) — cone
  • physics3d.plane(normal, constant) — infinite plane, STATIC only
  • physics3d.hull(points) — convex hull around a set of points
body:add(physics3d.sphere(1))
body:add(physics3d.box(vec3(0.5, 1, 0.5)))
body:add(physics3d.capsule(0.4, 1.8))

Collision Callbacks

React to collisions through entity callbacks or body callbacks:

local box = scn:entity()
box:add(physics3d.body(physics3d.DYNAMIC))
box:add(physics3d.box(vec3(1,1,1)))

box.collisionBegan3d = function(contact)
    print("Hit something!", contact.impulse)
end

The contact object contains impulse (force magnitude) and normal (collision normal vector).

Forces and Impulses

Apply forces and impulses to dynamic bodies to set them in motion:

local body = ent:get(physics3d.body)

-- Continuous force (applied each frame, use in update)
body:applyForce(vec3(0, 100, 0))

-- Instant impulse (applied once)
body:applyImpulse(vec3(0, 10, 0))

-- Torque (rotational force)
body:applyTorque(vec3(0, 5, 0))

-- Set velocity directly
body.linearVelocity = vec3(1, 0, 0)
body.angularVelocity = vec3(0, 1, 0)

Physics 3D

physics3d.world

Type

Syntax

physics3d.world

physics3d.world()

Constructor

Syntax

physics3d.world()

Create a new physics world

Returns

physics3d.world

physics3d.world:body(type, x, y, z)

Method

Syntax

physics3d.world:body(type, x, y, z)

Create a new rigidbody in this world

Parameters

type enum.

The type of body, STATIC, DYNAMIC or KINEMATIC

x number.

The initial x position of the new body

y number.

The initial y position of the new body

z number.

The initial z position of the new body

Returns

physics3d.body

The newly created body

physics3d.world:step(deltaTime)

Method

Syntax

physics3d.world:step(deltaTime)

Steps the simulation by deltaTime

Parameters

deltaTime number, optional.

Simulation timestep, in seconds.

physics3d.world:draw()

Method

Syntax

physics3d.world:draw()

Draws a debug representation of the physics world using primitive shapes

physics3d.world:raycast(origin, direction, distance, mask)

Method

Syntax

physics3d.world:raycast(origin, direction, distance, mask)

Performs a raycast on the physics world from origin in the direction of direction for the distance of distance

The raycast itself is filtered by the optional mask parameter, a bitfield which is compared to collider categories

Parameters

origin vec3.

The origin of the ray

direction vec3.

The direction of the ray

distance number.

The maximum distance for the ray to travel

mask integer, optional.

Collision category bit mask restricting which bodies can be hit.

Returns

physics3d.rayHit

The raycast hit info or nil is no collider was hit

physics3d.world:sphereCast(origin, direction, distance, radius, mask)

Method

Syntax

physics3d.world:sphereCast(origin, direction, distance, radius, mask)

Performs a sphere cast on the physics world from origin in the direction of direction for the distance of distance

The sphere cast itself is filtered by the optional mask parameter, a bitfield which is compared to collider categories

Parameters

origin vec3.

The origin of the ray

direction vec3.

The direction of the ray

distance number.

The maximum distance for the ray to travel

radius number.

The radius of the sphere used to perform the cast

mask integer, optional.

Collision category bit mask restricting which bodies can be hit.

Returns

physics3d.rayHit

The raycast hit info or nil is no collider was hit

physics3d.world.gravity

Property

Syntax

physics3d.world.gravity

The current gravity vector for this world

physics3d.body

Type

Syntax

physics3d.body

A three dimensional rigidbody that simulated within a physics3d.world. Used to simulate both dynamic and static objects, responding to physical forces, collisions and physics queries (i.e. raycast, queryBox, etc…)

physics3d.body:destroy()

Method

Syntax

physics3d.body:destroy()

Destroys this body, removing it from the world in the next simluation step

physics3d.body:sphere(radius, offsetX, offsetY, offsetZ)

Method

Syntax

physics3d.body:sphere(radius, offsetX, offsetY, offsetZ)

Creates and attaches a sphere collider to this body

Parameters

radius number.

The radius of the circle

offsetX number, optional.

The local x offset of the circle

offsetY number, optional.

The local y offset of the circle

offsetZ number, optional.

The local y offset of the circle

Returns

physics3d.sphere

The new circle collider

physics3d.body:box(halfWidth, halfHeight, halfDepth, offsetX, offsetY, offsetZ)

Method

Syntax

physics3d.body:box(halfWidth, halfHeight, halfDepth, offsetX, offsetY, offsetZ)

Creates and attaches a box collider to this body

Parameters

halfWidth number.

half width of the box

halfHeight number.

half height of the box

halfDepth number.

half depth of the box

offsetX number, optional.

The local x offset of the circle

offsetY number, optional.

The local y offset of the circle

offsetZ number, optional.

The local y offset of the circle

Returns

physics3d.box

The new box collider

physics3d.body:capsule(radius, height, offsetX, offsetY, offsetZ)

Method

Syntax

physics3d.body:capsule(radius, height, offsetX, offsetY, offsetZ)

Creates and attaches a capsule collider to this body

Parameters

radius number.

The radius of the capsule

height number.

The height of the capsule

offsetX number, optional.

The local x offset of the circle

offsetY number, optional.

The local y offset of the circle

offsetZ number, optional.

The local y offset of the circle

Returns

physics3d.polygon

The new capsule collider

physics3d.body:mesh(mesh, convex)

Method

Syntax

physics3d.body:mesh(mesh, convex)

Creates and attaches a mesh collider to this body

Parameters

mesh mesh.

Mesh defining the collision geometry.

convex boolean, optional.

Whether to use a convex hull instead of the triangle mesh.

Returns

physics3d.mesh

The new capsule collider

physics3d.body:hinge(anchor, axis)

Method

Syntax

physics3d.body:hinge(anchor, axis)

Creates and attaches a hinge joint to this body. When no other body is provided the hinge joint attaches to the world itself

For two-body joints when one anchor and axis is provided, it will be interpreted as a world space location, which will attach to the relative locations of both bodies

When two anchors and axes are provided (anchorA / axisA and anchorB / axisB) are provided, they will be interpreted in local space and attach to those locations directly

Parameters

anchor vec3.

The world-space anchor for one or two-body hinges

axis vec3.

The world-space axis for one or two-body hinges

Returns

physics3d.hinge

The new hinge joint

physics3d.body:applyForce(force, worldPoint)

Method

Syntax

physics3d.body:applyForce(force, worldPoint)

Applies a force to this body over time (non-instantanious). Ideal for physical effects such as wind, bouyancy and springs

The optional parameter worldPoint can be used to apply forces to a specific location in world-space

Parameters

force vec3.

The force to apply

worldPoint vec3, optional.

The world-space location to apply the force at

physics3d.body:applyTorque(torque)

Method

Syntax

physics3d.body:applyTorque(torque)

Parameters

torque vec3.

The torque vector to apply

physics3d.body:applyLinearImpulse(impulse)

Method

Syntax

physics3d.body:applyLinearImpulse(impulse)

Parameters

impulse vec3.

The linear impulse to apply

physics3d.body:applyAngularImpulse(impulse)

Method

Syntax

physics3d.body:applyAngularImpulse(impulse)

Parameters

impulse vec3.

The angular impulse to apply

physics3d.body:worldPoint(localPoint)

Method

Syntax

physics3d.body:worldPoint(localPoint)

Transforms localPoint from local space to world space in respect to this body

Parameters

localPoint vec3.

The local space point to transform

Returns

vec3

physics3d.body:worldVector(localVector)

Method

Syntax

physics3d.body:worldVector(localVector)

Transforms localVector from world space to local space in respect to this body

Parameters

localVector vec3.

The world space vector to transform

Returns

vec3

physics3d.body:localPoint(worldPoint)

Method

Syntax

physics3d.body:localPoint(worldPoint)

Transforms worldPoint from world space to local space in respect to this body

Parameters

worldPoint vec3.

The world space point to transform

Returns

vec3

physics3d.body:localVector(worldVector)

Method

Syntax

physics3d.body:localVector(worldVector)

Transforms worldVector from world space to local space in respect to this body

Parameters

worldVector vec3.

The world space vector to transform

Returns

vec3

physics3d.body:velocityAtLocalPoint(localPoint)

Method

Syntax

physics3d.body:velocityAtLocalPoint(localPoint)

Samples the velocity of the body at localPoint in local space

Useful for determining velocity on a body at a specific location for calculating effects, sounds and damage during collisions

Parameters

localPoint vec3.

The local point to sample velocity from

Returns

vec3

physics3d.body:velocityAtWorldPoint(worldPoint)

Method

Syntax

physics3d.body:velocityAtWorldPoint(worldPoint)

Samples the velocity of the body at worldPoint in world space

Useful for determining velocity on a body at a specific location for calculating effects, sounds and damage during collisions

Parameters

worldPoint vec3.

The world point to sample velocity from

Returns

vec3

physics3d.body.destroyed

Property

Syntax

physics3d.body.destroyed

Flag indicating that this body has already been destroyed

physics3d.body.position

Property

Syntax

physics3d.body.position

The position of this body in the simulated world

physics3d.body.mass

Property

Syntax

physics3d.body.mass

The mass of this body in kilograms

physics3d.body.inertia

Property

Syntax

physics3d.body.inertia

The interial tensor in kg m^2

physics3d.body.linearDamping

Property

Syntax

physics3d.body.linearDamping

The amount of linear damping to apply, slowing velocity proportionally over time

physics3d.body.angularDamping

Property

Syntax

physics3d.body.angularDamping

The amount of linear damping to apply, slowing rotation propotionally over time

physics3d.body.sleepingAllowed

Property

Syntax

physics3d.body.sleepingAllowed

Flag for allowing sleeping for this body

physics3d.body.awake

Property

Syntax

physics3d.body.awake

Flag for the current awake state of this body, set to true to wake immediately

physics3d.body.enabled

Property

Syntax

physics3d.body.enabled

Flag for whether simulation is enabled

physics3d.body.constraints

Property

Syntax

physics3d.body.constraints

Flags to lock movement and rotation along each axis, using the following flags:

  • physics3d.freezePositionX
  • physics3d.freezePositionY
  • physics3d.freezePositionZ
  • physics3d.freezeRotationX
  • physics3d.freezeRotationY
  • physics3d.freezeRotationZ
  • physics3d.freezeRotation
  • physics3d.freezePosition
  • physics3d.freezeAll

These flags can also be combined, i.e. myBody.constraints = physics3d.freezePositionX | physics3d.freezeRotation

physics3d.body.bullet

Property

Syntax

physics3d.body.bullet

Continuous physics switch for this body, used to prevent tunneling for fast moving objects

physics3d.collider

Type

Syntax

physics3d.collider

TODO

physics3d.sphere

Type

Syntax

physics3d.sphere

TODO

physics3d.box

Type

Syntax

physics3d.box

TODO

physics3d.capsule

Type

Syntax

physics3d.capsule

TODO

physics3d.mesh

Type

Syntax

physics3d.mesh

TODO

physics3d.cylinder

Type

Syntax

physics3d.cylinder

TODO

physics3d.cone

Type

Syntax

physics3d.cone

TODO

physics3d.joint

Type

Syntax

physics3d.joint

TODO

physics3d.hinge

Type

Syntax

physics3d.hinge

TODO

physics3d.slider

Type

Syntax

physics3d.slider

TODO

physics3d.ballSocket

Type

Syntax

physics3d.ballSocket

TODO

physics3d.coneTwist

Type

Syntax

physics3d.coneTwist

TODO

physics3d.generic

Type

Syntax

physics3d.generic

TODO

physics3d.weld

Type

Syntax

physics3d.weld

TODO

physics3d.rayHit

Type

Syntax

physics3d.rayHit

physics3d.rayHit.point

Property

Syntax

physics3d.rayHit.point

The world position of the raycast hit location

physics3d.rayHit.normal

Property

Syntax

physics3d.rayHit.normal

The world normal of the raycast hit location

physics3d.rayHit.fraction

Property

Syntax

physics3d.rayHit.fraction

The fraction of the total ray distance travelled before a hit was detected

physics3d.rayHit.triangleIndex

Property

Syntax

physics3d.rayHit.triangleIndex

The index of the triangle hit (if we hit a mesh collider)

physics3d.rayHit.uv

Property

Syntax

physics3d.rayHit.uv

The uv coorindate of the triangle hit (if we hit a mesh collider)

physics3d.rayHit.barycentric

Property

Syntax

physics3d.rayHit.barycentric

The barycentric coorindate of the triangle hit (if we hit a mesh collider)

physics3d.rayHit.collider

Property

Syntax

physics3d.rayHit.collider

The collider that was hit by the ray

physics3d.rayHit.body

Property

Syntax

physics3d.rayHit.body

The body of the collider that was hit by the ray