Craft

Reference ❯ Advanced 3D Rendering, Physics and Voxels

Overview

Craft top ↑

Craft provides extended capabilities to Codea that make it much easier to create 3D scenes, physics and game logic. Craft introduces a number of new classes. These include craft.entity, which is the basic building block of 3D scenes.

Several systems are introduced, including: craft.scene - The core class in craft, draws and updates all other objects and systems craft.physics - Physics settings and helper functions craft.voxels - Streaming voxel terrain, block types and helper functions craft.ar - Augmented Reality, world tracking and helper functions

Each system can be used to access built-in objects, change settings or trigger specialised features.

Entities

craft.scene top ↑

Syntax

scene = craft.scene() 

In order to use craft you must make a scene. Scenes are used to create, update and draw all entities and components. Scenes also control basic things, such as ambient lighting, fog, the sky and contain references to some built-in entities.

Built-in entities include: a main camera that renders the scene by default a 'sun' which is a directional light a 'sky' which is a renderer with a Materials:Skybox material used to draw the background

camera

entity, the main camera entity (contains a camera component)

sun

entity, the sun entity (contains a directional light component)

sky

sky, the sky entity (contains a renderer with a Skybox material)

ambientColor

color, the ambient light color (for materials with lighting)

fogEnabled

bool, turns fog on and off

fogNear

float, the distance where fog begins

fogFar

float, the distance where fog reaches maximum density

fogColor

color, the color of the fog

renderBatchCount

int, the current number of batches being rendered (the less the better performance you can expect)

renderBatchCullCount

int, the current number of batches saved by frustum culling

Examples

function setup() -- Create the scene scene = craft.scene() -- Move the main camera scene.camera.position = vec3(0, -10, 0) -- Adjust the scene lighting scene.sun.rotation = quat.eulerAngles(45,0,45) scene.ambientColor = color(90,90,90) -- Turn on fog and set distances and color scene.fogEnabled = true scene.fogNear = 10 scene.fogFar = 50 scene.fogColor = color(255,255,255) -- Get the sky material and change the sky and horizon colors local skyMaterial = scene.sky.material skyMaterial.sky = color(255,100,150) skyMaterial.horizon = color(0,0,0) end function update(dt) -- Update the scene (including physics, voxels and other systems) scene:update(dt) end function draw() update(DeltaTime) -- Draw the scene (must be done within the draw function) scene:draw() end

craft.entity top ↑

Syntax

myEntity = scene:entity()

Entities are flexible objects that can be customised to change their appearance and behaviour. You can customise an entity by adding components. Each type of component serves a different purpose. Renderer components change entity appearance, physics components give entities physical behaviour.

model

model, the model used for drawing this entity (stored within the attached renderer component)

material

material, the material used for drawing this entity (stored within the attached renderer component)

position

vec3, the position of this entity in local coordinate space

worldPosition

vec3, the position of this entity in world coordinate space

rotation

quat, the rotation of this entity in local coordinate space

worldRotation

quat, the rotation of this entity in world coordinate space

scale

vec3, the scale of this entity in local coordinate space

x

float, the x position of this entity in local coordinate space

y

float, the y position of this entity in local coordinate space

z

float, the z position of this entity in local coordinate space

eulerAngles

vec3, the rotation of this entity in local coordinate space expressed in euler angles

parent

entity, the parent of this entity (in the transform hierarchy)

children

table [readonly], an array of children entities attached to this entity

active

bool, turn on and off to enable and disable entity in the scene

Examples

scene = craft.scene() -- Create a new entity entity = scene:entity() -- Attach a model and material for rendering entity.model = craft.model.cube(vec3(1,1,1)) entity.material = craft.material("Materials:Standard") -- Rotate the entity entity.eulerAngles = vec3(45, 0, 45) -- Set the z position of the entity entity.z = -10 -- Destroy the entity entity:destroy()

entity.add( type, ... ) top ↑

Syntax

myEntity:add( craft.renderer, myModel )
myEntity:add( craft.shape.box, vec3(1,1,1) )
myEntity:add( LuaClass, p1, p2, p3, ... )

Adds a component to this entity. There are several built-in components that can be added, such as craft.renderer, craft.shape.box and others. Lua classes can also be added as a component. Any additional parameters beyond the type will be forwarded to the component itself. For Lua classes the first parameter passed to the init() function will be the entity itself (followed by the rest of the arguments) allowing it to be stored for later use. Some special callback methods can be implemented in Lua classes to provide extra functionality.

The update() method will be called once per frame (useful for animations and game logic). The fixedUpdate() method will be called once per physics update (useful for physics related behaviour).

If the component is successfully added, the component will be returned. Only one of a given component type can be added at a time.

type

type, the type of component to add to this entity

Examples

-- Lua classes can be attached to entities to customise behaviour Mover = class() function Mover:init(entity, speed) self.entity = entity self.speed = speed end function Mover:update() -- Move the entity to the right at speed meters per second self.entity.x = self.entity.x + self.speed * DeltaTime self.entity.eulerAngles = vec3(0, ElapsedTime * 90, 270) end function setup() -- Create a new craft scene scene = craft.scene() -- Create an entity and attach a Mover to make it move automatically local entity = scene:entity() entity.model = craft.model("SpaceKit:spaceCraft6") entity.scale = vec3(0.1, 0.1, 0.1) entity.x = -10 entity:add(Mover, 1.5) scene.camera.z = 20 scene.camera.eulerAngles = vec3(0,0,180) end function update(dt) scene:update(dt) end function draw() update(DeltaTime) scene:draw() end

Returns

object, the component added to this entity

entity.get( type ) top ↑

Syntax

myEntity:get( craft.renderer )
myEntity:get( craft.shape.box )
myEntity:get( craft.rigidbody )
myEntity:get( LuaClass )

Gets a component of a particular type attached to this entity. If the component does not exist, nil is returned.

type

type, the type of component to get from this entity

Returns

object, the requested component (or nil if it does not exist)

entity.remove( componentType ) top ↑

Syntax

myEntity:remove( craft.renderer )
myEntity:remove( craft.shape.box )
myEntity:get( craft.rigidbody )
myEntity:remove( LuaClass )

Removes a component of a particular type attached to this entity, if it exists.

type

type, the type of component to remove from this entity

entity.destroy() top ↑

Syntax

myEntity:destroy()

Marks this entity for destruction in the next frame. Any children will also be marked for destruction.

entity.transformPoint() top ↑

Syntax

myEntity:transformPoint(point)

Transforms a point from local space into world space using this entity's transform.

point

vec3, the point to transform

Returns

vec3, the transformed point

entity.inverseTransformPoint() top ↑

Syntax

myEntity:inverseTransformPoint(point)

Transforms a point from world space into local space using this entity's transform.

point

vec3, the point to transform

Returns

vec3, the transformed point

entity.transformDirection() top ↑

Syntax

myEntity:transformDirection(point)

Transforms a direction from local space into world space using this entity's transform.

direction

vec3, the direction to transform

Returns

vec3, the transformed direction

entity.inverseTransformDirection() top ↑

Syntax

myEntity:inverseTransformDirection(direction)

Transforms a direction from world space into local space using this entity's transform.

direction

vec3, the direction to transform

Rendering

craft.camera top ↑

Syntax

myEntity:add(craft.camera, fov, nearPlane, farPlane, false)
myEntity:add(craft.camera, orthoSize, nearPlane, farPlane, true)

A component used to draw the scene from its point of view.

fieldOfView

float, the field of view of the camera in degrees

ortho

bool, orthographic rendering mode for this camera

nearPlane

float, the near plane for the camera (the closest thing that can be rendered)

farPlane

float, the far plane for the camera (the farthest thing that can be rendered)

clearDepthEnabled

bool, the depth clearing flag for the camera (when set to true the existing depth buffer will be cleared before rendering)

clearColorEnabled

bool, the color clearing flag for the camera (when set to true the existing color buffer will be cleared before rendering)

clearColor

color, the color to use when clearing the color buffer before rendering with the camera

entity

entity, the entity that the camera is attached to

Examples

-- create a new entity and add a camera to it camera = scene:entity():add(craft.camera, 45, 0.1, 1000, false)

camera.screenToWorld( position ) top ↑

Syntax

myCamera:screenToWorld( position )

Converts a position given in screen coordinates (x, y) and a depth value (z) to world space relative to this camera.

position

vec3, the position to convert to world space

Returns

vec3

camera.screenToRay( position ) top ↑

Syntax

origin, dir = myCamera:screenToRay( position )

Converts a position in screen coordinates (x, y) to a ray in the form of an origin and direction relative to this camera.

position

vec2, the position to generate a ray with

Returns

vec3, vec3

camera.viewport( x, y, width, height ) top ↑

Syntax

myCamera:viewport(x, y, width, height)
x, y, w, h = myCamera:viewport()

Sets or gets the current viewport using normalized coordinates. Can be used for adjusting the rendered area of the camera relative to the screen. For instance, calling camera:viewport(0.0, 0.0, 0.5, 1.0) will render the camera to only the left half of the screen.

x

float, the x position of the viewport

y

float, the y position of the viewport

width

float, the width viewport

height

float, height of the viewport

Returns

x, y, w, h

craft.renderer top ↑

Syntax

myEntity:add(craft.renderer, model)

A component used to draw a 3D model in the scene. Renderers can be attached to entities by using entity:add(craft.renderer) or by setting entity.model and entity.material directly.

material

material, the material to apply to this renderer

model

model, the model to render

Examples

-- create a new entity entity = scene.entity() entity.model = craft.model.icosphere(1, 3, false) entity.material = craft.material("Materials:Standard")

craft.light top ↑

Syntax

myEntity:add(craft.light, DIRECTIONAL)
myEntity:add(craft.light, SPOT)
myEntity:add(craft.light, POINT)

A component that casts light onto the scene. Different types of lights can be used to achieve different lighting effects, these include: DIRECTIONAL, SPOT and POINT. The position and rotation of the entity controls the position and rotation of the attached light source. By default the scene contains a single directional light known as the sun.

The scene also contains an ambient light controlled by scene.ambientColor. The ambient light term is added to the emission of all other lights and is generally used for simulating scattered environmental light.

type

the type of light, can be DIRECTIONAL, SPOT, POINT

color

color, the color of the light

intensity

float, how intense the emitted light is (can be higher than one)

distance

float, how far the light can travel (only applies for spot and point lights)

angle

float, the spread angle of the light (only applies to spot lights)

penumbra

float, the angle where light intensity begins to fade (only applies to spot lights)

decay

float, the rate at which the intensity of the light fades due to distance (only applies to spot and point lights)

mask

bitmask, the mask for which renderers should be effected by this light source

Examples

-- Create a new entity entity = scene.entity() light = entity:add(craft.light, POINT) light.distance = 10 light.intensity = 1 light.color = color(255,128,128) entity.position = vec3(0,5,0)

DIRECTIONAL top ↑

Syntax

DIRECTIONAL

This constant specifies the directional light type. Directional lights simulate an infinitely distant light source where all rays are parallel (similar to the sun). The position of a directional light is ignored.

Returns

int

SPOT top ↑

Syntax

SPOT

This constant specifies the spot light type. Spotlights simulate a cone of light within a specified angle (see the angle property). The distance and decay properties define how far the light travels and how quickly the intensity falls off over distance.

The penumbra property defines how hard the edge of the spotlight is. The closer this value is to angle the harder the edge will appear. Setting this to zero will give the appearance of very soft spotlight.

Returns

int

POINT top ↑

Syntax

POINT

This constant specifies the point light type. Point lights simulate a omnidirectional light source emitting from a single point. The distance and decay properties define how far the light travels and how quickly the intensity falls off over distance.

Returns

int

craft.material top ↑

Syntax

myMaterial = craft.material("Materials:Basic")
myMaterial = craft.material("Materials:Standard")
myMaterial = craft.material("Materials:Specular")
myMaterial = craft.material("Materials:Skybox")    

This type represents a surface material. Materials are used to control the physical appearance of 3D objects, such as models, sky boxes and voxels.

Set the material property on a craft.renderer component to apply a given material to it. Materials are built out of modular shaders with a set of dynamic properties.

Each named property has a different effect on the material's appearance. For instance, the map property can be set with an image or asset string to change the surface appearance of the Standard material. Other properties can change the normals, roughness, metalness and reflectiveness of materials.

blendMode

int, the blend mode to use for this material (can be NORMAL, ADDITIVE or MULTIPLY)

renderQueue

int, the render queue to use for this material (can be OPAQUE or TRANSPARENT)

Examples

local e = scene:entity() e.model = craft.cube(vec3(1,1,1)) -- Load the standard material (physically based rendering) local m = craft.material("Materials:Standard") e.material = m -- Surface color m.diffuse = color(255, 255, 255) -- Opacity (0.0 fully transparent, 1.0 fully opaque) m.opacity = 1.0 -- Surface color texture map m.map = "Surfaces:Basic Bricks Color" -- Texture map offset and repeat (tiling) m.offsetRepeat = vec4(0.0, 0.0, 3.0, 3.0) -- Normal map for small scale surface details m.normalMap = "Surfaces:Basic Bricks Normal" -- How intense the normal map effect is in tangent space (also used for flipping) m.normalScale = vec2(1, 1) -- How rough the material is m.roughness = 1.0 -- A texture that controls the roughness m.roughnessMap = "Surfaces:Basic Bricks Roughness" -- How metallic the material is m.metalness = 1.0 -- A texture that controls how metallic the surface is m.metalnessMap = nil -- The environment map (a CubeTexture), specular illumination m.envMap = nil -- The ambient occlusion map, used for self-occluding shadows m.aoMap = "Surfaces:Basic Bricks AO" -- How intense the aoMap is m.aoMapIntensity = 2.5 -- The displacement map which modifies vertex positions based on normals m.displacementMap = nil -- Base offset of the displacement map m.displacementBias = 0 -- Scale of the displacement map m.displacementScale = 1

craft.model top ↑

Syntax

myModel = craft.model()
myModel = craft.model( asset )

This type represents a model. Used in conjunction with a craft.renderer component to draw 3D objects. Existing model assets can be loaded by using craft.model(asset), which also has picker support. Currently only the OBJ format is supported, however there are plans to add support for other common formats.

Models are made up of a number of triangles, which are in-turn made up of vertices. Each vertex has a number of attributes that control their appearance, such as position, color and normal.

To make a triangle you must set the indices of the model using the indices property. You can resize the number of indices and vertices by using the resizeIndices() and resizeVertices() functions.

vertexCount

int, the number of vertices in this model

indexCount

int, the number of indices in this model

positions

array, the positions of the vertices of this model

normals

array, the normals of the vertices of this model

colors

array, the colors of the vertices of this model

uvs

array, the uvs of the vertices of this model

indices

array, the primitive indices of this model used to form triangles

material

material, the material for this model (overridden by renderer materials)

Examples

-- Create a blank model m = craft.model() -- Blank models include attributes for position, normal, color and uv local positions = {vec3(-1.0,-1.0,0), vec3(-1.0,1.0,0), vec3(1.0,1.0,0), vec3(1.0,-1.0,0)} local normals = {vec3(0,0,-1), vec3(0,0,-1), vec3(0,0,-1), vec3(0,0,-1)} local uvs = {vec2(0,0), vec2(0,1), vec2(1,1), vec2(1,0)} local c = color(245, 3, 3, 255) local colors = {c, c, c, c} -- Indices are used to create triangles using groups of 3 vertices local indices = {3,2,1,4,3,1} -- Update model vertices using tables m.positions = positions m.normals = normals m.uvs = uvs m.colors = colors m.indices = indices

craft.model.cube top ↑

Syntax

myModel = craft.model.cube()
myModel = craft.model.cube(size)
myModel = craft.model.cube(size, offset)

Creates a cube model with the specified size and offset. By default the size parameter is set to (1,1,1), and the offset parameter is (0,0,0).

size

vec3, the size of the cube

offset

vec3, the offset of the center of the cube

craft.model.icosphere top ↑

Syntax

myModel = craft.model.icosphere(radius)
myModel = craft.model.icosphere(radius, subdivisions)
myModel = craft.model.icosphere(radius, subdivisions, flat)

Creates an icosphere model. An icosphere is a geodesic dome made from equally sized triangles. The number of subdivisions specified will control how dense the sphere is (increasing the number of triangles). Setting the icosphere to flat will created faceted faces, otherwise the icosphere will have a smooth appearance.

radius

float, the radius of the icosphere

subdivisions

int, the number of subdivisions to apply the base icosphere

craft.model.plane top ↑

Syntax

myModel = craft.model.plane()
myModel = craft.model.plane(size)
myModel = craft.model.plane(size, offset)

Creates a horizontal plane model with the specified size and offset. By default the size parameter is set to (1, 1), and the offset parameter is (0, 0, 0).

size

vec2, the size of the plane (x, z dimensions)

offset

vec3, the offset of the center of the plane

model.resizeVertices( size ) top ↑

Syntax

myModel:resizeVertices( size )

Sets the number of vertices in the model.

size

int, the number of vertices

model.resizeIndices( size ) top ↑

Syntax

myModel:resizeIndices( size )

Sets the number of indices in the model where each set of 3 indices forms a triangle.

size

int, the number of indices

model.position( index, ... ) top ↑

Syntax

myModel:position( index )
myModel:position( index, p )
myModel:position( index, x, y, z )

Set or get the position for a vertex within this model.

Use with only the index parameter to return the x, y, z values of a vertex position (as 3 separate values).

index

int,

model.normal( index, ... ) top ↑

Syntax

x, y, z = myModel:normal( index )
myModel:normal( index, n )
myModel:normal( index, x, y, z )

Set or get the normal for a vertex within this model.

Use with only the index parameter to return the x, y, z values of a vertex normal (as 3 separate values).

index

int,

model.color( index, ... ) top ↑

Syntax

r, g, b, a = myModel:color( index )
myModel:color( index, c )
myModel:color( index, r, g, b, a )

Set or get the color for a vertex within this model.

Use with only the index parameter to return the r, g, b, a values of a vertex color (as 4 separate values).

index

int,

model.uv( index, ... ) top ↑

Syntax

u, v = myModel:uv( index )
myModel:uv( index, p )
myModel:uv( index, u, v )

Set or get the uv for a vertex within this model.

Use with only the index parameter to return the u, v values of a vertex uv (as 2 separate values).

index

int,

model.addElement( index ) top ↑

Syntax

myModel:addElement( index1, index2, ..., indexN )

Adds a variable number of indices to the model. Each index must be within the range 1..model.vertexCount

index

int,

Physics

craft.physics top ↑

The system governing all 3D physics in a scene.

paused

bool, use to pause and unpause the physics simulation

gravity

vec3, the current force of gravity effecting all rigidbodies (measured in ms^2)

physics.raycast top ↑

Syntax

scene.physics:raycast(origin, direction, distance)
scene.physics:raycast(origin, direction, distance, group)
scene.physics:raycast(origin, direction, distance, group, mask)

Performs a raycast in the scene against any rigidbodies with attached shapes.

origin

vec3, the origin of the ray

direction

vec3, the direction of the ray

distance

float, the maximum distance the ray can travel

group

int, the group of the ray (used for filtering)

mask

int, the mask of the ray (used for filtering)

Returns

table, if the raycast intersects a rigidbody this function will return a table containing the following key-value pairs:

entity => entity hit
point => point of intersection
normal => normal at the point of intersection
fraction => fraction of total ray length from start to intersecton point

physics.spherecast top ↑

Syntax

scene.physics:spherecast(origin, direction, distance, radius)
scene.physics:spherecast(origin, direction, distance, radius, group)
scene.physics:spherecast(origin, direction, distance, radius, group, mask)

Performs a spherecast in the scene against any rigidbodies with attached shapes. A spherecast works by projecting a sphere in the direction of the cast and detecting any shapes that it intersects.

origin

vec3, the origin of the spherecast

direction

vec3, the direction of the spherecast

distance

float, the maximum distance the spherecast can travel

radius

float, the radius of the spherecast

group

bitmask, the group of the ray (used for filtering)

mask

bitmask, the mask of the ray (used for filtering)

Returns

table, if the spherecast intersects a rigidbody this function will return a table containing the following key-value pairs:

entity => entity hit
point => point of intersection
normal => normal at the point of intersection
fraction => fraction of total ray length from start to intersecton point

craft.rigidbody top ↑

Syntax

myRigidbody = myEntity:add( craft.rigidbody, STATIC )
myRigidbody = myEntity:add( craft.rigidbody, KINEMATIC )
myRigidbody = myEntity:add( craft.rigidbody, DYNAMIC, mass )

This type represents a 3D rigidbody. Attach this to an entity to make it respond to forces and collisions. When creating a rigidbody you must specify the type you want to create. Refer to the documentation for DYNAMIC, STATIC and KINEMATIC for more details.

type

the type of the body, can be STATIC, DYNAMIC or KINEMATIC

mass

float, the mass of the rigid body in kilograms

centerOfMass

vec3, the center of mass of the rigid body in world space

linearVelocity

vec3, the current linear velocity of the body in meters per second

angularVelocity

vec3, the angular velocity of the body in degrees per second

awake

bool, is the rigid body currently awake

sleepingAllowed

bool, is sleeping allowed for this rigid body

linearDamping

float, linear damping factor, slows rigid body movement over time

angularDamping

float, angular damping factor, slows rigid body rotation over time

friction

float, sliding friction factor

rollingFriction

float, rolling friction factor

restitution

float, restitution factor, the bounceyness of this rigid body

group

bitmask, the collision filtering group for this rigid body

mask

bitmask, the collision filtering mask for this rigid body

Examples

-- create a sphere with a 1 meter radius sphere = scene:entity() -- Attach a dynamic rigidbody sphere:add(craft.rigidbody, DYNAMIC, 1) -- Add a sphere shape to respond to collisions sphere:add(craft.shape.sphere, 1) -- Attach a renderer and sphere model for visuals sphere.model = craft.model.icosphere(1, 3) sphere.material = craft.material("Materials:Standard")

DYNAMIC top ↑

Syntax

DYNAMIC

This constant specifies the dynamic body type. Dynamic bodies move under the influence of collisions, forces, joints and gravity.

Returns

int

STATIC top ↑

Syntax

STATIC

This constant specifies the static body type. Static bodies are unaffected by forces and collisions. They also do not collide with other static or kinematic bodies.Also note that you cannot attach two static/kinematic bodies together with a joint.

Returns

int

KINEMATIC top ↑

Syntax

KINEMATIC

This constant specifies the kinematic body type. Kinematic bodies are unaffected by forces and collisions. Unlike static bodies, kinematic bodies are meant to be moved, usually by setting linear velocity directly. They also do not collide with other static or kinematic bodies. Also note that you cannot attach two static/kinematic bodies together with a joint.

Returns

int

rigidbody.applyForce( force ) top ↑

Syntax

myBody:applyForce( force )
myBody:applyForce( force, worldPoint )

Applies a force to this rigidbody. If worldPoint is not specified then the force will be applied to the center of the rigidbody.

force

vec3, the amount of force (in newtons per second) to apply as a vector

worldPoint

vec3, the point to apply the force from, in world coordinates

rigidbody.applyTorque( torque ) top ↑

Syntax

myBody:applyTorque( torque )

Applies torque to this rigidbody.

force

vec3, the amount of torque (in newton meters per second) to apply as a vector

craft.shape.box top ↑

Syntax

myShape = myEntity:add(craft.shape.box, size)
myShape = myEntity:add(craft.shape.box, size, offset)

This component represents a box physics shape. Attach this to an entity with a rigidbody to make it respond to physical forces.

size

vec3, the size of the box

offset

vec3, the offset of the box (center)

Examples

-- create a new entity e = scene:entity() e:add(craft.rigidbody, DYNAMIC, 1) e:add(craft.shape.box, vec3(1,1,1), vec3(0,0,0))

craft.shape.sphere top ↑

Syntax

myShape = myEntity:add(craft.shape.sphere, radius)
myShape = myEntity:add(craft.shape.sphere, radius, offset)

This component represents a sphere physics shape. Attach this to an entity with a rigidbody to make it respond to physical forces.

Examples

-- create a new entity e = scene:entity() e:add(craft.rigidbody, DYNAMIC, 1) e:add(craft.shape.sphere, 1, vec3(0,0,0))

craft.shape.model top ↑

Syntax

myShape = myEntity:add(craft.shape.model, model)

This component represents an arbitrary physics shape made from a model. Attach this to an entity with a rigidbody to make it respond to physical forces.

Examples

-- create a new entity local model = craft.model("CastleKit:wallNarrowStairsFence") e = scene:entity() e.model = model e:add(craft.rigidbody, STATIC) e:add(craft.shape.model, model)

craft.shape.capsule top ↑

Syntax

myShape = myEntity:add(craft.shape.capsule, radius, height)

This component represents a capsule physics shape. Attach this to an entity with a rigidbody to make it respond to physical forces.

Examples

-- create a new entity e = scene:entity() e:add(craft.rigidbody, DYNAMIC, 1) e:add(craft.shape.capsule, 1, vec3(0,0,0))

Voxels

craft.voxels top ↑

Syntax

craft.voxels

The voxel system, used to manage streaming voxel terrain. Initially no voxels exist as the terrain is completely empty. Using voxels:resize() will create an empty patch of terrain, consisting of empty blocks. Once some terrain has been allocated voxels:generate() can be used to generate the landscape one chunk at a time via a multi-threaded generation system. See the Voxel Terrain project for an example of how this works.
Using voxels:enableStorage(storage) allows voxels to be saved to a project subfolder with the specified name. As a technical note, volumes and chunks are saved as zlib compressed json files. Block types, scheduled updates and block entities are all saved. If a block id changes due to inserting a new block type of removing an existing one, the loaded chunk/volume may change unexpectedly.

coordinates

vec3, the viewing coordinates to stream voxels around (in world coordinates)

visibleRadius

float, the radius (in chunks) to stream around the viewing coordinates

visibleChunks

int, the number of chunks that are loaded and potentially visible in the scene

generatingChunks

int, the number of chunks that are currently being generated

meshingChunks

int, the number of chunks that are currently being meshed (turned into models)

Examples

-- Set the size of the voxel landscape to 10x1x10 chunks -- Each chunk is 16x128x16 blocks in size by default scene.voxels:resize(vec3(10,1,10)) scene.voxels:generate(readProjectTab("Generate"), "generateTerrain")

voxels.resize( sizeInChunks, chunkSize ) top ↑

Syntax

scene.voxels:resize( vec3(100, 1, 100) )
scene.voxels:resize( vec3(100, 1, 100), vec3(16, 128, 16) )                                

Resizes the voxel terrain to a specified size divided into chunks, which can be generated and streamed efficiently.

sizeInChunks

vec3, the total size of the world in chunks (y is limited to 1 at this time)

chunkSize

vec3, the size of each chunk (default is 16x128x16)

voxels.generate( generationCode, generationFunction ) top ↑

Syntax

scene.voxels:generate(generationCode, generationFunction)      
                            

Triggers voxel terrain generation using lua code provided as a string and the number of a function to call. The specified function must exist within generationCode and must take a single parameter which is the chunk that will be generated. See craft.volume for available methods for manipulating chunks.

generationCode

string, the lua code to use for multi-threaded generation

generationFunction

string, the name of the function within generationCode to use

voxels.get( coord, key ) top ↑

Syntax

scene.voxels:get ( key )
scene.voxels:get ( key1, key2, ... keyN )
scene.voxels:get ( keyArray )

Gets data from a block at a particular location using the specified key(s). There are a number that can be used for different block data:

BLOCK_ID - Get this block's id (int) BLOCK_NAME - Get this block's name (string) BLOCK_STATE - Get this block's state (int) COLOR - Get this block's tint color (color), only works for tinted blocks To get custom block properties, use a string with the name of that property. When called with no keys specified a block instance will be returned which has methods which can be called directly.

coord

vec3 or (x,y,z), the coordinate of the block (in world coordinates) to get the data from

key

the key of the data to get for this block

Returns

multiple, the values associated with the block's keys (or nil if it does not exist)

voxels.set( coord, key, value ) top ↑

Syntax

scene.voxels:set ( key, value )
scene.voxels:set ( key1, value1, ... keyN, valueN )
scene.voxels:set ( keyValueTable )

Sets data on a block at a particular location for the specified key(s). There are several that can be used for different block data:

BLOCK_ID - Set this blocks id (int), effectively changing the type of block BLOCK_NAME - Set this blocks name (string), effectively changing the type of block BLOCK_STATE - Set this blocks state (int) COLOR - Set this blocks tint color (color), only works for tinted blocks

If a block changes its own type then it will behave as the new block and will trigger any destroyed() and created() callbacks.

To modify custom block properties, use a string with the name of that property.

coord

vec3 or (x,y,z), the coordinate of the block (in world coordinates) to set the data for

key

the key of the data to set for this block

value

the value to set the data to

voxels.fill( key, value ) top ↑

Syntax

scene.voxels:fill ( key )
scene.voxels:fill ( key1, key2, ... keyN )
scene.voxels:fill ( keyArray )

Sets the current fill block. Takes the same parameters as voxels.set. This is used for basic drawing operations such as sphere, box and line.

key

the key of the data to use for the fill

value

the value of the data to use for the fill

voxels.fillStyle( style ) top ↑

Syntax

scene.voxels:fillStyle ( style )

Sets the current fill style. There are several styles that can be used:

REPLACE - Replace fill style, new blocks will replace any existing ones UNION - Union fill style, new blocks will only replace empty ones UNTERSECT - Intersect style, new blocks will only replace non-existing ones CLEAR - Clear style, new blocks will clear any existing blocks

style

the style to use

voxels.block( coord ) top ↑

Syntax

scene.voxels:block ( coord )

Sets a single block using the current fill() and fillStyle() settings.

coord

vec3 or (x,y,z), the coordinate to place the block

voxels.sphere( coord, radius ) top ↑

Syntax

scene.voxels:sphere ( coord, radius )
scene.voxels:sphere ( x, y, z, radius )

Sets a single block using the current fill() and fillStyle() settings.

coord

vec3 or (x,y,z), the coordinate of the sphere to place

radius

float, the radius of the sphere to place

voxels.box( min, max ) top ↑

Syntax

scene.voxels:box ( min, max )
scene.voxels:box ( x1, y1, z1, x2, y2, z2 )

Sets a box shaped array of blocks using the minimum and maximum coordinates supplied.

min

vec3 or (x,y,z), the coordinate of the minimum corner of the box

max

vec3 or (x,y,z), the coordinate of the maximum corner of the box

voxels.line( start, end ) top ↑

Syntax

scene.voxels:line ( start, end )
scene.voxels:line ( x1, y1, z1, x2, y2, z2 )

Sets a box shaped array of blocks using the minimum and maximum coordinates supplied.

start

vec3 or (x,y,z), the coordinate of the start of the line

end

vec3 or (x,y,z), the coordinate of the end of the line

voxels.updateBlock( coord, ticks ) top ↑

Syntax

scene.voxels:updateBlock ( coord, ticks )
scene.voxels:updateBlock ( x, y, z, ticks )

Schedules a block update for the block at a specified coordinate. The ticks parameter controls how long in the future before the update will occur. Each tick is roughly 1/60th of a second. Using 0 will cause an update to occur next frame.

Block updates call the blockUpdate(ticks) method on scripted blocks. Block updates can be triggered inside a scripted block itself by using self:schedule(ticks).

coord

vec3 or (x,y,z), the coordinate of the block to update

ticks

ticks, the number of ticks to wait for the update

voxels.raycast( origin, direction, distance, callback ) top ↑

Syntax

scene.voxels:raycast( start, direction, distance, callback )
                            

Performs a raycast on the voxel terrain. The callback provided must follow the signature:

function callback(coord, id, face)

The coord parameter (vec3) contains the coordinate of the current voxel encountered.

If coord is nil, this means the raycast has gone outside of the bounds of the voxel terrain (i.e. no voxel found).

The id parameter contains the id of the current voxel encountered.

The face parameter (vec3) contains the direction of the face hit by the raycast (i.e. vec3(0,1,0) would be the top).

At each step the callback function can return true or false. Returning true will terminate the raycast early, false will continue the raycast until the maximum distance is reached.

origin

vec3, the origin of the ray

direction

vec3, the direction of the ray

distance

vec3, the maximum distance the ray can travel

callback

function, a callback that will be called for each voxel encountered

Examples

-- Use the main camera to get the position and direction for the raycast from a screen location origin, dir = craft.camera.main:screenToRay(vec2(WIDTH/2, HEIGHT/2)) scene.voxels:raycast(origin, dir, 100, function(coord, id, face) if coord and id ~= 0 then print('found a block at '..coord..' with id '..id) return true end return false end)

voxels.iterateBounds( min, max, callback ) top ↑

Syntax

scene.voxels:iterateBounds( min, max, callback )    

Iterates through all blocks within the min and max bounds provided sending the information to a callback function. The callback function should take the following form function myCallback(x, y, z, id).

min

vec3 or (x,y,z), the coordinate of the minimum corner of the box

max

vec3 or (x,y,z), the coordinate of the maximum corner of the box

callback

function, the function to callback for each block encountered

voxels.isRegionLoaded( min, max ) top ↑

Syntax

scene.voxels:isRegionLoaded( min, max )    

Checks if all the voxels within the min and max bounds are currently loaded. This is useful for generating more complex structures that make require adjacent areas to be loaded.

min

vec3 or (x,y,z), the coordinate of the minimum corner of the box

max

vec3 or (x,y,z), the coordinate of the maximum corner of the box

voxels.enableStorage( storageName ) top ↑

Syntax

scene.voxels:enableStorage( storageName )    

Enables storage within the voxel system. This causes regions to be saved within the project inside a folder named storageName.

storageName

string, the name of the storage folder to use

voxels.disableStorage() top ↑

Syntax

scene.voxels:disableStorage()    

Disables storage.

voxels.deleteStorage( storageName ) top ↑

Syntax

scene.voxels:deleteStorage( storageName )    

Deletes a particular storage folder (if it exists).

storageName

string, the name of the storage folder to delete

craft.block top ↑

Syntax


                    

This type represents a specific voxel block variant. You can create a block type via scene.voxels.blocks:new( name ).

By default a block type has the appearance of a white cube (1x1x1 units). A block type's appearance can be customised by adding and removing cubes of various sizes, changing their textures or applying tints.

A block type's behaviour can be customised by enabling scriping and adding special methods to it:

blockType:created() - called when the block is created blockType:destroyed() - called when the block is destroyed (removed) blockType:buildModel(model) - called when the block is about to be modeled

Instances of scripted blocks cannot store additional data in their tables unless they are set to dynamic. Non-dynamic blocks have up to 32 bits of state that can be used to store per-block data (see block.state for more information). Dynamic blocks can store additional values in their tables. Dynamic blocks come with their own entity, which can be used to render custom models, or animate them in ways static blocks cannot.

Scripted and dynamic blocks use significantly more resources than standard non-scripted blocks and care must be taken to avoid using too much memory or slowing down the voxel system. A good rule of thumb is to match the complexity of a custom block to how often it is used.

Please note that any properties marked instance only can only be accessed via block instances, i.e. those created by setting voxels and passed into callbacks.

id

int, the id of this block type

name

string, the name of this block type

state

type, the state of this block

geometry

int, the type of geometry to generate, can be EMPTY, SOLID, TRANSPARENT or TRANSLUCENT

renderPass

int, the type of render pass to use, can be OPAQUE or TRANSLUCENT

tinted

bool, whether this block type supports tinting (changing color)

scripted

bool, whether this block type supports scripting

dynamic

bool, whether this block type is dynamic

x

int, the x location of this block (instance only)

y

int, the y location of this block (instance only)

z

int, the z location of this block (instance only)

block.get( key ) top ↑

Syntax

myBlock:get ( key )
myBlock:get ( key1, key2, ... keyN )
myBlock:get ( keyArray )

Gets data from this block for the specified key. There are a number of that can be used for different block data.

BLOCK_ID - Get this block's id (int) BLOCK_NAME - Get this block's name (string) BLOCK_STATE - Get this block's state (int) COLOR - Get this block's tint color (color), only works for tinted blocks To get custom block properties, use a string with the name of that property.

key

the key of the data to set on this block

block.set( key, value ) top ↑

Syntax

myBlock:set ( key, value )
myBlock:set ( key1, value1, ... keyN, valueN )
myBlock:set ( keyValueTable )

Sets data on this block for the specified key. There are a number of that can be used for different block data.

BLOCK_ID - Set this blocks id (int), effectively changing the type of block BLOCK_NAME - Set this blocks name (string), effectively changing the type of block BLOCK_STATE - Set this blocks state (int) COLOR - Set this blocks tint color (color), only works for tinted blocks

If a block changes its own type then it will behave as the new block and will trigger any destroyed() and created() callbacks.

To modify custom block properties, use a string with the name of that property.

key

the key of the data to set on this block

value

the value to set the data to

Examples

local Blinky = scene.voxels.blocks:new("Blinky") function Blinky:created() -- Schedule an update in one second self:schedule(60) end function Blinky:blockUpdate(ticks) -- Create a random color local randomColor = color(random(128,255), random(128,255), random(128,255)) -- set block color and then schedule another update in one second self:set(COLOR, randomColor) self:schedule(60) end

craft.volume top ↑

Syntax

myEntity:add(craft.volume, x, y, z)

This component represents a 3D voxel volume. Voxel volume components store block data as well as handling rendering and physics.

Examples

-- create a new entity entity = scene:entity() entity:add(craft.volume, 10, 10, 10)

volume.size() top ↑

Syntax

sx, sy, sz = myVolume:size()

Returns the size of this volume in voxels as 3 components (x, y, z).

Examples

entity = scene:entity() volume = entity:add(craft.volume, 10, 10, 10) -- outputs: 10 10 10 print(volume:size())

Returns

size of the volume as 3 separate values

volume.get( coord, key ) top ↑

Syntax

myVolume:get ( key )
myVolume:get ( key1, key2, ... keyN )
myVolume:get ( keyArray )

Gets data from a block at a particular location using the specified key(s). There are a number that can be used for different block data:

BLOCK_ID - Get this block's id (int) BLOCK_NAME - Get this block's name (string) BLOCK_STATE - Get this block's state (int) COLOR - Get this block's tint color (color), only works for tinted blocks To get custom block properties, use a string with the name of that property.

coord

vec3 or (x,y,z), the coordinate of the block (in world coordinates) to get the data from

key

the key of the data to get for this block

Returns

multiple, the values associated with the block's keys (or nil if it does not exist)

volume.set( x, y, z, id ) top ↑

Syntax

myVolume:set( x, y, z, id )
myVolume:set( coord, id )
myVolume:set( x, y, z, name )
myVolume:set( coord, name )
myVolume:set( x, y, z, key1, value1, ... keyN, valueN )
myVolume:set( coord, keyValueTable )
myVolume:set( x, y, z, keyValueTable )

Sets a block within this volume at the coordinates given (x, y, z). Coordinates can be supplied as either a vec3, or as a set of 3 numbers.

x

number, the x location of the block to set

y

number, the y location of the block to set

z

number, the z location of the block to set

Examples

entity = scene:entity() volume = entity:add(craft.volume, 10, 10, 10) -- Create a purple block inside the volume volume:set(1, 1, 1, 'name', 'solid', 'color', color(255,0,0))

volume.resize( x, y, z ) top ↑

Syntax

myVolume:resize( x, y, z )    

Resizes the volume to a specific size.

x

float, the width of the volume

y

float, the height of the volume

z

float, the depth of the volume

volume.load( asset ) top ↑

Syntax

myVolume:load( "Documents:My Voxel Model" )    

Loads a saved volume.

asset

string, the name of the asset to load

volume.save( asset ) top ↑

Syntax

myVolume:save( "Documents:My Voxel Model" )    

Saves a volume as a voxel asset.

asset

string, the name of the asset to save

AR

craft.ar top ↑

The Augmented Reality (AR) system. Please note that to use the AR feature your device must possess an A9 or greater processor. To determine if your device supports AR, use craft.ar.isSupported.

To enable AR, use scene.ar:run(). This will use the sky to render the camera feed to the background. If you do not want to display the camera feed, simply disable the sky. To disable AR you can call the pause() function.

The AR system will automatically try to detect and estimate horizontal planes in the scene. To be notified of when this happens you must set the anchor callbacks, such as scene.ar.didAddAnchors. These will be called with an array of anchor objects which contain a position and extent which can be used for positioning objects in the world.

To interact with the AR world, use hitTest(screenPoint, options), and check the array of hitTestResult objects for any intersections.

isSupported

bool [static, readonly], use to determine if your device supports AR

isRunning

bool [readonly], use to determine if AR is currenly active

planeDetection

bool, enable and disable plane detection

trackingState

enum [readonly], the current tracking state - can be AR_NOT_AVAILABLE, AR_LIMITED and AR_NORMAL

trackingStateReason

enum [readonly], the reason for the current tracking state (if AR_LIMITED) - can be AR_NONE, AR_EXCESSIVE_MOTION and AR_INSUFFICIENT_FEATURES

didAddAnchors

function, the function to call when one or more anchors is added to the AR system

didUpdateAnchors

function, the function to call when one or more anchors is updated

didRemoveAnchors

function, the function to call when one or more anchors is removed

ar.run() top ↑

Syntax

scene.ar:run()

Enables AR if possible. This overrides the sky's visuals as well as the main camera's transform and projection matrix.

ar.pause() top ↑

Syntax

scene.ar:pause()

Pauses AR.

ar.hitTest( screenPoint, options ) top ↑

Syntax

scene.ar:hitTest( screenPoint )

Performs a hit test (raycast) against the AR world. Any objects that are hit by the ray are returned as a list of craft.ar.hitTestResult.

The options parameter is a bitmask with the following flags: AR_FEATURE_POINT - Search for feature points AR_ESTIMATED_PLANE - Search for estimated horizontal surfaces AR_EXISTING_PLANE - Search for detected planes AR_EXISTING_PLANE_CLIPPED - Search for detected planes (clipped to edges)

screenPoint

vec2, the screen point to check for hits in the AR world

options

bitmask, the options to use for finding things in the AR world

Returns

array, the hitTestResult objects (if any) resulting from this hit test

craft.ar.anchor top ↑

An anchor in the AR world. These can represent a point (single location) or a plane (flat surface). The identifier property is useful for uniquely identifying anchors that are automatically created by plane detection.

type

int, the type of anchor

identifier

string, the unique identifier for this anchor

position

vec3, the position of this anchor (in the AR world)

extent

vec3, the extent of this anchor (for planes)

craft.ar.hitTestResult top ↑

A hit test result that is returned by the ar:hitTest() function. The type of hittest can be

type

int, the type of hit test

identifier

string, the unique identifier for this anchor

position

vec3, the position of this anchor (in the AR world)

extent

vec3, the extent of this anchor (for planes)

AR_NOT_AVAILABLE top ↑

Syntax

AR_NOT_AVAILABLE

This constant specifies that AR world tracking is not currently available. Returned by ar.trackingState.

Returns

int

AR_LIMITED top ↑

Syntax

AR_LIMITED

This constant specifies that AR world tracking is currently limited. Returned by ar.trackingState, with further details returned by ar.trackingStateReason.

Returns

int

AR_NORMAL top ↑

Syntax

AR_NORMAL

This constant specifies that AR world tracking is currently normal. Returned by ar.trackingState.

Returns

int

AR_NONE top ↑

Syntax

AR_NONE

This constant specifies that AR world tracking is not currently limited. Returned by ar.trackingStateReason.

Returns

int

AR_EXCESSIVE_MOTION top ↑

Syntax

AR_EXCESSIVE_MOTION

This constant specifies that AR world tracking is currently limited due to excessive device motion. Returned by ar.trackingStateReason.

Returns

int

AR_INSUFFICIENT_FEATURES top ↑

Syntax

AR_INSUFFICIENT_FEATURES

This constant specifies that AR world tracking is currently limited due to insufficient feature points. This could be due to a lack of contrasting features on surfaces (such as a white table or mirrored surface). Returned by ar.trackingStateReason.

Returns

int

AR_FEATURE_POINT top ↑

Syntax

AR_FEATURE_POINT

Used by ar:hitTest as a mask for detecting feature points during hit test.

Returns

int

AR_ESTIMATED_PLANE top ↑

Syntax

AR_ESTIMATED_PLANE

Used by ar:hitTest as a mask for detecting estimated planes during hit test.

Returns

int

AR_EXISTING_PLANE top ↑

Syntax

AR_EXISTING_PLANE

Used by ar:hitTest as a mask for detecting existing planes during hit test.

Returns

int

AR_EXISTING_PLANE_CLIPPED top ↑

Syntax

AR_EXISTING_PLANE_CLIPPED

Used by ar:hitTest as a mask for detecting existing planes (clipped to edges) during hit test.

Returns

int

Noise

Noise top ↑

The noise library contains a series of noise modules that can be used to generate a large variety of procedural content. Use getValue(x,y,z) to generate a scalar noise value. Some modules take a number of inputs (set with setSource(input)).

Noise modules fall into the following catagories: Generators - These modules generate values directly and require no inputs Transformers - These modules transform their inputs in some way to create a new effect

Refer to each individual module's documentation to see how they work.

craft.noise.perlin top ↑

Syntax

n = craft.noise.perlin()

A perlin noise generator module. Zero inputs.

octaves

int, the number of octaves, controlling the detail of the noise

frequency

float, the frequency of the first octave

persistence

float, the persistence controls how rough the noise produced is

lacunarity

float, the lucunarity controls the multiplier between successive octaves

seed

int, the seed

Examples

local n = craft.noise.perlin() local value = n:getValue(x,y,z)

craft.noise.rigidMulti top ↑

Syntax

n = craft.noise.rigidMulti()

A rigid multi-fractal noise generator module. Zero inputs.

octaves

int, the number of octaves, controlling the detail of the noise

frequency

float, the frequency of the first octave

lacunarity

float, the lucunarity controls the multiplier between successive octaves

seed

int, the seed

Examples

local n = craft.noise.rigidMulti() local value = n:getValue(x,y,z)

craft.noise.billow top ↑

Syntax

n = craft.noise.billow()

A billow noise generator module. Zero inputs.

octaves

int, the number of octaves, controlling the detail of the noise

frequency

float, the frequency of the first octave

persistence

float, the persistence controls how rough the noise produced is

lacunarity

float, the lucunarity controls the multiplier between successive octaves

seed

int, the seed

Examples

local n = craft.noise.billow() local value = n(x,y,z)

craft.noise.turbulence top ↑

Syntax

n = craft.noise.turbulence()

Transformer module that distorts input using turbulent noise. One input.

frequency

float, the frequency of the turbulence

roughness

float, how rough the turbulence is

power

float, how much distortion to apply

seed

int, the seed

Examples

local n1 = craft.noise.perlin() local n2 = craft.noise.turbulence() n2:setSource(0, n1) local value = n(x,y,z)

craft.noise.cache top ↑

Syntax

n = craft.noise.cache()

Caches the source module value when evaluated at the same coordinates more than once. One input.

craft.noise.const top ↑

Syntax

n = craft.noise.const(value)

Constant noise module. Returns a constant value at any location. Zero inputs.

Examples

local n = craft.noise.const(10) -- Always returns 10 local value = n(x,y,z)

craft.noise.select top ↑

Syntax

n = craft.noise.select()

Selects one of two noise modules based on the output of the control module and the set bounds. Three inputs.

craft.noise.gradient top ↑

Syntax

n = craft.noise.gradient()

Returns a gradient in the y-axis mapped from zero to one. Zero inputs.

craft.noise.min top ↑

Syntax

n = craft.noise.min()

Returns the minimum of two noise modules. Two inputs.

craft.noise.max top ↑

Syntax

n = craft.noise.max()

Returns the maximum of two noise modules. Two inputs.

craft.noise.add top ↑

Syntax

n = craft.noise.add()

Returns the addition of two noise modules. Two inputs.

craft.noise.abs top ↑

Syntax

n = craft.noise.abs()

Returns the absolute version of the source noise module. One input.

craft.noise.merge top ↑

Syntax

n = craft.noise.merge()

Returns the first non-zero value of two noise modules. Two inputs.

craft.noise.scaleOffset top ↑

Syntax

n = craft.noise.scaleOffset()

Scales and offsets the output of a noise module. One input.

craft.noise.displace top ↑

Syntax

n = craft.noise.displace()

Displaces the coordinates of a noise module using three other noise modules. Four inputs.

craft.noise.scale top ↑

Syntax

n = craft.noise.scale()

Scales the coordinates of the input source module. One input.