# Physics 3D

Dynamic motion with forces, joints and collisions in 3D

[Reference](index.md)

<a id="section-Guides"></a>

## Guides

<a id="3D-Physics-in-Codea"></a>

### 3D Physics in Codea

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()`:

```lua
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:

```lua
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

```lua
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:

```lua
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:

```lua
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)
```

<a id="section-Physics-3D"></a>

## Physics 3D

<a id="physics3d"></a>

### physics3d

<a id="physics3d.world"></a>

### physics3d.world

```lua
physics3d.world
```

create a new 3D physics world

<a id="physics3d.world-2"></a>

### physics3d.world()

```lua
physics3d.world()
```

Create a new physics world

create a new 3D physics world

#### Returns

- **physics3d.world**: 

<a id="physics3d.world:body"></a>

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

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

Create a new rigidbody in this world

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

<a id="physics3d.world:step"></a>

### physics3d.world:step(deltaTime)

```lua
physics3d.world:step(deltaTime)
```

Steps the simulation by `deltaTime`

step the physics simulation

#### Parameters

- **deltaTime** (number, optional): Simulation timestep, in seconds.

<a id="physics3d.world:draw"></a>

### physics3d.world:draw()

```lua
physics3d.world:draw()
```

Draws a debug representation of the physics world using primitive shapes

draw a debug representation of the physics world

<a id="physics3d.world:raycast"></a>

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

```lua
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

perform a raycast in this physics world

#### 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

<a id="physics3d.world:sphereCast"></a>

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

```lua
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

perform a sphere cast in this physics world

#### 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

<a id="physics3d.world.gravity"></a>

### physics3d.world.gravity

```lua
physics3d.world.gravity
```

The current gravity vector for this world

get or set the 3D physics gravity vector

<a id="physics3d.body"></a>

### physics3d.body

```lua
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…)

destroy this body

<a id="physics3d.body:destroy"></a>

### physics3d.body:destroy()

```lua
physics3d.body:destroy()
```

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

destroy this body

<a id="physics3d.body:sphere"></a>

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

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

Creates and attaches a sphere collider to this body

attach 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

<a id="physics3d.body:box"></a>

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

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

Creates and attaches a box collider to this body

attach 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

<a id="physics3d.body:capsule"></a>

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

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

Creates and attaches a capsule collider to this body

attach 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

<a id="physics3d.body:mesh"></a>

### physics3d.body:mesh(mesh, convex)

```lua
physics3d.body:mesh(mesh, convex)
```

Creates and attaches a mesh collider to this body

attach 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

<a id="physics3d.body:hinge"></a>

### physics3d.body:hinge(anchor, axis)

```lua
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

attach a hinge joint to this body

#### 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

<a id="physics3d.body:applyForce"></a>

### physics3d.body:applyForce(force, worldPoint)

```lua
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

apply a continuous force to this body

#### Parameters

- **force** (vec3): The force to apply
- **worldPoint** (vec3, optional): The world-space location to apply the force at

<a id="physics3d.body:applyTorque"></a>

### physics3d.body:applyTorque(torque)

```lua
physics3d.body:applyTorque(torque)
```

apply a torque to this body

#### Parameters

- **torque** (vec3): The torque vector to apply

<a id="physics3d.body:applyLinearImpulse"></a>

### physics3d.body:applyLinearImpulse(impulse)

```lua
physics3d.body:applyLinearImpulse(impulse)
```

apply a linear impulse to this body

#### Parameters

- **impulse** (vec3): The linear impulse to apply

<a id="physics3d.body:applyAngularImpulse"></a>

### physics3d.body:applyAngularImpulse(impulse)

```lua
physics3d.body:applyAngularImpulse(impulse)
```

apply an angular impulse to this body

#### Parameters

- **impulse** (vec3): The angular impulse to apply

<a id="physics3d.body:worldPoint"></a>

### physics3d.body:worldPoint(localPoint)

```lua
physics3d.body:worldPoint(localPoint)
```

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

transform a local point to world space

#### Parameters

- **localPoint** (vec3): The local space point to transform

#### Returns

- **vec3**: 

<a id="physics3d.body:worldVector"></a>

### physics3d.body:worldVector(localVector)

```lua
physics3d.body:worldVector(localVector)
```

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

transform a local vector to world space

#### Parameters

- **localVector** (vec3): The world space vector to transform

#### Returns

- **vec3**: 

<a id="physics3d.body:localPoint"></a>

### physics3d.body:localPoint(worldPoint)

```lua
physics3d.body:localPoint(worldPoint)
```

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

transform a world point to local space

#### Parameters

- **worldPoint** (vec3): The world space point to transform

#### Returns

- **vec3**: 

<a id="physics3d.body:localVector"></a>

### physics3d.body:localVector(worldVector)

```lua
physics3d.body:localVector(worldVector)
```

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

transform a world vector to local space

#### Parameters

- **worldVector** (vec3): The world space vector to transform

#### Returns

- **vec3**: 

<a id="physics3d.body:velocityAtLocalPoint"></a>

### physics3d.body:velocityAtLocalPoint(localPoint)

```lua
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

sample the body velocity at a local point

#### Parameters

- **localPoint** (vec3): The local point to sample velocity from

#### Returns

- **vec3**: 

<a id="physics3d.body:velocityAtWorldPoint"></a>

### physics3d.body:velocityAtWorldPoint(worldPoint)

```lua
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

sample the body velocity at a world point

#### Parameters

- **worldPoint** (vec3): The world point to sample velocity from

#### Returns

- **vec3**: 

<a id="physics3d.body.destroyed"></a>

### physics3d.body.destroyed

```lua
physics3d.body.destroyed
```

Flag indicating that this body has already been destroyed

get whether this body is destroyed

<a id="physics3d.body.position"></a>

### physics3d.body.position

```lua
physics3d.body.position
```

The position of this body in the simulated world

get or set the position of this body

<a id="physics3d.body.mass"></a>

### physics3d.body.mass

```lua
physics3d.body.mass
```

The mass of this body in kilograms

get or set the mass of this body

<a id="physics3d.body.inertia"></a>

### physics3d.body.inertia

```lua
physics3d.body.inertia
```

The interial tensor in kg m^2

get the inertia tensor of this body

<a id="physics3d.body.linearDamping"></a>

### physics3d.body.linearDamping

```lua
physics3d.body.linearDamping
```

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

get or set the linear damping

<a id="physics3d.body.angularDamping"></a>

### physics3d.body.angularDamping

```lua
physics3d.body.angularDamping
```

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

get or set the angular damping

<a id="physics3d.body.sleepingAllowed"></a>

### physics3d.body.sleepingAllowed

```lua
physics3d.body.sleepingAllowed
```

Flag for allowing sleeping for this body

get or set whether sleeping is allowed

<a id="physics3d.body.awake"></a>

### physics3d.body.awake

```lua
physics3d.body.awake
```

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

get or set whether this body is awake

<a id="physics3d.body.enabled"></a>

### physics3d.body.enabled

```lua
physics3d.body.enabled
```

Flag for whether simulation is enabled

get or set whether this body is enabled

<a id="physics3d.body.constraints"></a>

### physics3d.body.constraints

```lua
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`

get or set the motion constraints bitfield

<a id="physics3d.body.bullet"></a>

### physics3d.body.bullet

```lua
physics3d.body.bullet
```

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

get or set whether bullet mode is enabled

<a id="physics3d.collider"></a>

### physics3d.collider

```lua
physics3d.collider
```

TODO

<a id="physics3d.sphere"></a>

### physics3d.sphere

```lua
physics3d.sphere
```

TODO

<a id="physics3d.box"></a>

### physics3d.box

```lua
physics3d.box
```

TODO

<a id="physics3d.capsule"></a>

### physics3d.capsule

```lua
physics3d.capsule
```

TODO

<a id="physics3d.mesh"></a>

### physics3d.mesh

```lua
physics3d.mesh
```

TODO

<a id="physics3d.cylinder"></a>

### physics3d.cylinder

```lua
physics3d.cylinder
```

TODO

<a id="physics3d.cone"></a>

### physics3d.cone

```lua
physics3d.cone
```

TODO

<a id="physics3d.joint"></a>

### physics3d.joint

```lua
physics3d.joint
```

TODO

<a id="physics3d.hinge"></a>

### physics3d.hinge

```lua
physics3d.hinge
```

TODO

<a id="physics3d.slider"></a>

### physics3d.slider

```lua
physics3d.slider
```

TODO

<a id="physics3d.ballSocket"></a>

### physics3d.ballSocket

```lua
physics3d.ballSocket
```

TODO

<a id="physics3d.coneTwist"></a>

### physics3d.coneTwist

```lua
physics3d.coneTwist
```

TODO

<a id="physics3d.generic"></a>

### physics3d.generic

```lua
physics3d.generic
```

TODO

<a id="physics3d.weld"></a>

### physics3d.weld

```lua
physics3d.weld
```

TODO

<a id="physics3d.rayHit"></a>

### physics3d.rayHit

```lua
physics3d.rayHit
```

get the raycast hit point

<a id="physics3d.rayHit.point"></a>

### physics3d.rayHit.point

```lua
physics3d.rayHit.point
```

The world position of the raycast hit location

get the raycast hit point

<a id="physics3d.rayHit.normal"></a>

### physics3d.rayHit.normal

```lua
physics3d.rayHit.normal
```

The world normal of the raycast hit location

get the raycast hit normal

<a id="physics3d.rayHit.fraction"></a>

### physics3d.rayHit.fraction

```lua
physics3d.rayHit.fraction
```

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

get the raycast hit fraction

<a id="physics3d.rayHit.triangleIndex"></a>

### physics3d.rayHit.triangleIndex

```lua
physics3d.rayHit.triangleIndex
```

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

get the raycast hit triangle index

<a id="physics3d.rayHit.uv"></a>

### physics3d.rayHit.uv

```lua
physics3d.rayHit.uv
```

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

get the raycast hit UV coordinate

<a id="physics3d.rayHit.barycentric"></a>

### physics3d.rayHit.barycentric

```lua
physics3d.rayHit.barycentric
```

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

get the raycast hit barycentric coordinate

<a id="physics3d.rayHit.collider"></a>

### physics3d.rayHit.collider

```lua
physics3d.rayHit.collider
```

The collider that was hit by the ray

get the raycast hit collider

<a id="physics3d.rayHit.body"></a>

### physics3d.rayHit.body

```lua
physics3d.rayHit.body
```

The body of the collider that was hit by the ray

get the raycast hit body
