Skip to main content

3D objects


Image3D​


A plane with an image texture applied.

image3d = ObjectFactory.Image3D(
"../assets/sprites/explosion_a.png", -- file path
Vertex3D.new(10, 10, 10), -- position
150, -- width
200 -- height
)

Animated billboards (Image3DAnimation)​

Animated sprite billboards are exposed to Lua as BillboardAnimation. Besides CreateAnimation and setAnimation, they offer:

MethodParametersDescription
setTowardsCamera()boolWhen true, the quad always faces the camera. Set false for flat sprites lying on the ground (decals, puddles)
setSize()float w, float hResizes the quad at runtime (e.g. a growing puddle effect)
setRenderFB()string fbDraws the billboard into a named framebuffer layer ("scene", "ui"...)

Objects found by name are returned as a plain Object3D. To get the full billboard API, use the typed accessor:

local fx = Brakeza:getImage3DAnimationByName("explosion_01")
if fx then fx:setSize(4, 4) end

Mesh3D​


A 3D model that includes geometry and textures.

ObjectFactory.Mesh3D(
"../assets/models/Capsule.fbx", -- file path
Vertex3D.new(x, y, z) -- position
)

Mesh3D objects provide some advanced features, such as Grid3D and Octrees, which will be covered in the scripting chapter.

Model and textures​

MethodDescription
getModelFile()Path of the model file the object was created from. Valid right after creation, before async loading finishes
getMeshCount()Number of sub-meshes (texture slots) in the model
getDiffuseTextureFile(meshIdx)File of the diffuse texture of sub-mesh meshIdx (0-based), or ""
setDiffuseTexture(meshIdx, path)Replaces the diffuse texture of sub-mesh meshIdx
-- Give each spawned car a random paint
local skins = { "../assets/images/car_red.png", "../assets/images/car_blue.png" }
local car = Brakeza:getObjectByName("car_01")
car:setDiffuseTexture(0, skins[math.random(#skins)])

Emission​

Emissive meshes ignore lighting and shadows: the lit color is blended towards the plain texture color, so they stay visible in the dark (neon signs, screens, lamps…). At intensity 1 the mesh shows its texture exactly as it is.

MethodDescription
setEmissionEnabled(bool) / isEmissionEnabled()Turn emission on or off for this object
setEmissionIntensity(value) / getEmissionIntensity()Blend amount from 0 (normal lighting) to 1 (fully unlit)
Shared geometry and instancing

Several Mesh3D / Mesh3DAnimation objects created from the same model file share their GPU geometry, and the deferred renderer draws them with instancing (G-Buffer, shadow and picking passes, animated models included). Spawning many copies of the same model is therefore much cheaper than loading different files.

local sign = Brakeza:getObjectByName("neon_sign")
sign:setEmissionEnabled(true)
sign:setEmissionIntensity(0.8)

Both values can also be set in the editor (Object Properties › Emission) and are saved with the scene.

Emissive objects are rendered in their own pass, so scenes without any emissive object pay no extra cost.

Mesh3DAnimation​


An animated 3D model loaded from an FBX file containing skeletal animations.

man = ObjectFactory.Mesh3DAnimation(
"../assets/animations/walking.fbx", -- file path
Vertex3D.new(0, -10, 40) -- position
)

Objects found by name are returned as a plain Object3D. Use Brakeza:getMesh3DAnimationByName(name) to get the object with the full animation API.

Mesh3DAnimation Methods​

MethodParametersReturnDescription
setIndexCurrentAnimation()int indexvoidChanges the active animation by index
setAnimationByName()string namevoidChanges the active animation by name
setAnimationSpeed()float speedvoidSets playback speed (0.0 - 1.0)
isAnimationEnds()-boolReturns true if the current animation has finished
setLoop()bool loopvoidEnables or disables animation looping
isLoop()-boolReturns whether the animation loops

Change Current Animation​

If the model contains more than one animation, the first one will be selected by default. You can choose a different active animation from the GUI or via LUA scripts:

man:setIndexCurrentAnimation(2)                         -- change animation by index
man:setAnimationByName("Run") -- change animation by name

Change Animation Speed​

To modify the animation playback speed:

man:setAnimationSpeed(0.5)                              -- 50% speed
man:setAnimationSpeed(1.0) -- normal speed

Animation Looping and Completion​

man:setLoop(false)                                      -- disable looping

function onUpdate()
if man:isAnimationEnds() then
print("Animation finished!")
man:setIndexCurrentAnimation(0) -- switch to idle
end
end

Image3DAnimation360​


Image3DAnimation360 (Lua type: BillboardAnimation8Directions) is a billboard sprite that automatically selects one of 8 directional animation strips based on the angle between the camera and the object. It is the standard entity for top-down or isometric units that need to appear to face the camera correctly from any viewing direction (e.g. soldiers, civilians, vehicles).

Each directional strip is a separate sprite sheet stored in a sub-folder. The object picks the correct strip every frame using the horizontal angle between the camera forward vector and the object's facing direction, divided into 8 equal sectors of 45°.

Creating from Lua​

local unit = ObjectFactory.Image3DAnimation360(
"../assets/sprites/soldier/", -- root folder (used by the serializer)
Vertex3D.new(0, 0, 50), -- world position
2.0, -- billboard width (world units)
3.5 -- billboard height (world units)
)
unit:setName("soldier_01")
Brakeza:AddObject3D(unit, "soldier_01")

Adding directional animations​

After creation, register each animation strip with CreateAnimationDirectional2D. The strips are indexed internally in the order they are added:

-- The Lua binding for CreateAnimationDirectional2D is not currently exposed;
-- use the JSON scene format or the editor to configure directional animations.
note

Image3DAnimation360 directional animations are typically configured in the scene JSON rather than at runtime from Lua. The editor (Object Properties window) provides a GUI to add and preview each of the 8 directional strips.

Lua methods​

BillboardAnimation8Directions inherits all standard Object3D methods (position, rotation, scale, enable/disable, collision, etc.). No additional Lua methods are exposed beyond those inherited from Object3D.

Inherited methodDescription
setPosition(Vertex3D)Move the billboard to a world position
setEnabled(bool)Show or hide the object
setRemoved(bool)Mark for deletion
isRemoved()Returns true if the object has been removed
setName(string)Set the object's name
getPosition()Returns the current world position

Scene file format​

{
"name": "soldier_01",
"type": 11,
"position": { "x": 0, "y": 0, "z": 50 },
"width": 2.0,
"height": 3.5,
"animations": [
{ "file": "../assets/sprites/soldier/south.png", "frames": 8, "fps": 12, "zeroDirection": true, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/southwest.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/west.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/northwest.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/north.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/northeast.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/east.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 },
{ "file": "../assets/sprites/soldier/southeast.png", "frames": 8, "fps": 12, "zeroDirection": false, "maxTimes": 0 }
]
}

zeroDirection: true marks the strip that represents the canonical facing direction (angle 0). maxTimes: 0 means the animation loops indefinitely.


Common Object3D Methods​


These methods are available on all 3D objects (Mesh3D, Mesh3DAnimation, Image3D, etc.).

Orientation​

MethodParametersReturnDescription
LookAt()Object3D targetvoidRotates the object to face another object
LookAt()Vertex3D positionvoidRotates the object to face a world position
getModelMatrix()—M3Returns the current 4×4 model matrix
-- Look at another object
this:LookAt(enemy)

-- Look at a fixed position
this:LookAt(Vertex3D.new(0, 0, 100))

Script Variables​

Per-object variables stored in the object's Lua environment. Readable and writable from any script.

MethodParametersReturnDescription
getLocalScriptVar()string nameanyReads a variable from the object's script environment
setLocalScriptVar()string name, any valuevoidWrites a variable into the object's script environment
-- Write from any script
unit:setLocalScriptVar("hp", 50)

-- Read from any script
local hp = tonumber(unit:getLocalScriptVar("hp")) or 0

Selection & Highlight​

MethodParametersReturnDescription
isSelectable()—boolReturns whether the object can be picked by mouse click
setSelectable()bool valuevoidEnables or disables mouse-click selection for this object
setHighlight()float r, g, b, avoidDraws a colored outline around the object
clearHighlight()—voidRemoves the outline
-- Prevent terrain from being selected
terrain:setSelectable(false)

-- Highlight an enemy in red
enemy:setHighlight(1, 0, 0, 1)

-- Remove highlight
enemy:clearHighlight()

Rendering Flags​

MethodParametersReturnDescription
isAlphaEnabled()—boolReturns whether alpha blending is active
setAlphaEnabled()bool valuevoidEnables or disables alpha blending for this object
isEnableLights()—boolReturns whether the object is affected by lights
setEnableLights()bool valuevoidToggles lighting on this object
isVisibleInFrustum()—boolReturns true if the object is currently inside the camera frustum
-- Make an object unlit (e.g. a UI mesh or emissive prop)
prop:setEnableLights(false)

-- Transparent object
ghost:setAlphaEnabled(true)

-- Skip expensive logic for off-screen objects
if not unit:isVisibleInFrustum() then return end

Drawing Lines​


You can draw 3D lines using the Render component.

Components:Render():DrawLine(
this:getPosition(), -- from position
this:getPosition() + this:AxisUp():getScaled(2) -- to position
)