Math & Utilities¶
Doriax includes a complete set of math and utility types that are shared across rendering, physics, animation, input, and gameplay code. Understanding these types helps you write efficient, readable Doriax scripts.
Vector types¶
| Type | Dimensions | Typical uses |
|---|---|---|
Vector2 |
2D (x, y) | Positions, sizes, velocities, UV coordinates |
Vector3 |
3D (x, y, z) | Positions, directions, scales, normals |
Vector4 |
4D (x, y, z, w) | Colors (RGBA), homogeneous coordinates, packed data |
-- Create vectors
local pos = Vector3(10, 5, 0)
local dir = Vector3(0, 1, 0)
local target = Vector3(0, 5, 0)
-- Arithmetic
local newPos = pos + dir * 3.0 -- 3.0 * dir works too
local dist = pos:length()
local unit = dir:normalized()
local dot = pos:dotProduct(dir)
-- Step toward a point without passing it, or blend toward it
local stepped = pos:moveTowards(target, 4 * Engine.deltatime)
local halfway = pos:lerp(target, 0.5)
All three vector types have moveTowards and lerp. moveTowards moves at a fixed speed
and stops exactly on the target, which suits movement driven by deltatime. lerp covers a
fraction of the remaining distance, so it slows down near the target.
Common static constants¶
| Constant | Value |
|---|---|
Vector3.ZERO |
(0, 0, 0) |
Vector3.UNIT_SCALE |
(1, 1, 1) |
Vector3.UNIT_X |
(1, 0, 0) |
Vector3.UNIT_Y |
(0, 1, 0) |
Vector3.UNIT_Z |
(0, 0, 1) |
Changing one component of a property¶
Properties such as position, scale, rotation, color or linearVelocity return a
copy of the value. Changing a component of that copy does not reach the object, so
self.object.position.y = 2 runs without error but leaves the object where it was.
Assign the whole value instead:
local pos = self.object.position
pos.y = 2 -- only the copy changes
self.object.position = pos -- now the object moves
-- the same, building a new vector
self.object.position = Vector3(pos.x, 2, pos.z)
-- or with a setter that takes the components
self.object:setPosition(pos.x, 2, pos.z)
Not every property has such a setter: setScale takes one uniform factor, and bodies
have none for position or linearVelocity.
The same holds for methods that change a vector in place, such as normalize(), for
values returned by methods like object:getWorldPosition(), and for list properties such
as scene.postProcessPasses: they act on a copy. Code Editor
completion marks properties that return a copy, e.g. Object.position -> Vector3 (copy).
Component fields are the exception: Lua gets the field itself, not a copy, so
image:getUIComponent().color.x = 1 changes the component. Some fields also need their
needUpdate… flag set; see Writing components directly.
Quaternion¶
Quaternion represents 3D rotation. Prefer
quaternions over Euler angles for rotation interpolation and composition.
-- Create from Euler angles (ZYX order; degrees if useDegrees is enabled)
local q = Quaternion(0, 90, 0)
-- Interpolate (interpolation factor comes first)
local result = Quaternion.slerp(0.5, q1, q2)
-- Rotate a direction
local rotated = q * Vector3(1, 0, 0) -- same as q:xAxis()
-- Face a target with the local +Z axis
obj.rotation = Quaternion.lookRotation(target - obj.position)
Matrix types¶
| Type | Use |
|---|---|
Matrix3 |
3×3 transforms, normal matrix |
Matrix4 |
4×4 transforms, projection, view matrix |
Matrices are used internally by the renderer and physics, but you can construct them for custom transforms or pass them to shader uniforms.
Rect¶
Rect stores a 2D rectangle as (x, y, width, height).
Use it for UI bounds, sprite atlas frames, and screen-space regions.
local frame = Rect(64, 0, 32, 32) -- x=64, y=0, w=32, h=32
local contains = frame:contains(Vector2(70, 10))
Bounds and spatial queries¶
| Class | Use |
|---|---|
AABB |
Axis-aligned bounding box — fast broad-phase tests, frustum culling |
OBB |
Oriented bounding box — rotated objects that AABB over-approximates |
Sphere |
Sphere bounds — broad-phase tests, shadow radius, audio range |
Ray |
Ray from origin in a direction — picking, raycasts, line-of-sight |
Plane |
Infinite plane defined by normal and distance — frustum planes, clip tests |
-- Cast a ray through the cursor and test it against the scene's 3D physics bodies
local pos = Input.getMousePosition()
local ray = camera:screenToRay(pos.x, pos.y)
local result = ray:intersects(scene, RayFilter.BODY_3D)
if result.hit then
print("Hit entity:", result.body, "at distance", result.distance)
end
intersects also accepts individual AABB, OBB, Plane, Body2D, and Body3D
targets, and RayFilter.BOUNDS tests every mesh's bounding box without any physics. Pass an entity or a list of entities to skip those bodies so the ray continues
through them (ray:intersects(scene, RayFilter.BODY_3D, self.entity)). The returned
RayReturn carries hit, distance, point, normal, body (the entity), and
shapeIndex.
Angles¶
The Angle utility class provides explicit
degree/radian conversions. The engine can be configured to use degrees everywhere with
Engine::setUseDegrees(true).
-- Convert explicitly regardless of engine setting
local rad = Angle.degToRad(90)
local deg = Angle.radToDeg(math.pi / 2)
Color utilities¶
The static Color class provides sRGB ↔ linear
conversions. Rendering expects linear color space internally.
-- Convert from sRGB to linear for the renderer
local linearRed = Color.sRGBToLinear(Vector3(1, 0, 0))
-- And back for display values
local srgb = Color.linearTosRGB(linearRed)
Logging¶
Log provides formatted console output at different
severity levels.
Use Log::debug for development-only output. Release builds can strip debug logs by
setting the appropriate log level.
Object utility¶
The Object class wraps an entity handle and
provides transform, visibility, parenting, and basic physics convenience APIs. Use it
when you need to access transform data from a script without knowing the specific
object type.
local Mover = {
properties = {
{ name = "speed", displayName = "Speed", type = "float", default = 50.0 }
}
}
function Mover:init()
RegisterEngineEvent(self, "onUpdate")
end
function Mover:onUpdate()
local obj = Object(self.scene, self.entity)
local dt = Engine.deltatime
obj.position = obj.position + Vector3(0, self.speed * dt, 0)
end
return Mover
Base64¶
The Base64 utility class encodes and decodes binary
data as base64 strings. Useful for embedding small binary data in JSON or YAML, or for
network/save serialization. C++ only — encode / decode are not exposed to Lua yet.