Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

spline.core

Pure spline math used by the parent spline module — point normalisation, curve evaluation (linear / Catmull-Rom / Bezier), tangent + length estimation, eased traversal, and closest-point / sampling helpers. Side-effect free — no engine calls, no entity spawns — so it stays easy to test and reuse.

Exports

Construction:

  • Core.new(points: {PointInput}, opts: SplineOpts?) -> Spline
  • Core.linear(points, opts?) -> Spline / Core.catmullRom(points, opts?) -> Spline / Core.bezier(points, opts?) -> Spline

Sampling and queries:

  • Core.evaluate(path: Spline, t: number) -> Vec3 / Core.evaluateEased(path, t, easing) -> Vec3
  • Core.tangent(path: Spline, t: number) -> Vec3
  • Core.length(path: Spline, steps?: number) -> number
  • Core.sample(path, count, opts?) -> {Sample} / Core.sampleBySpacing(path, spacing, opts?) -> {Sample}
  • Core.closestProgress(path, point, steps?) -> (number, Vec3)
  • Core.measure(pathOrPoints, opts?) -> Measured: the curve by arc length (a list of points is read as a polyline)
  • Core.atDistance(measured, distance, wrap?) -> (Vec3, Vec3): position and direction a distance along it, the constant-speed read

Easing:

  • Core.resolveEasing(easing: EasingInput) -> EasingFn
  • Core.easingNames() -> { string }

Vector helpers exposed for the placement / drawing siblings:

  • Core.copyPoint(p), Core.add(a, b), Core.sub(a, b), Core.scale(v, s), Core.normalize(v), Core.lengthVec(v).

Types:

  • Vec3 = { x: number, y: number, z: number }
  • PointInput = Vec3 | { number }
  • SplineMode = "linear" | "catmullRom" | "bezier"
  • SplineOpts = { mode: SplineMode?, closed: boolean?, tension: number? }
  • Spline = { points: {Vec3}, mode: SplineMode, closed: boolean, tension: number }
  • Sample = { t: number, position: Vec3, tangent: Vec3 }
  • SampleOpts = { easing: ..?, steps: number? }
  • EasingFn = (number) -> number
  • EasingInput = string | EasingFn | nil
  • Measured = { positions: {Vec3}, distances: {number}, length: number, closed: boolean }

Usage

local Core = require("@builtin::modules.spline.core")

local path = Core.new({
    { x = 0, y = 0, z = 0 },
    { x = 2, y = 1, z = 0 },
    { x = 4, y = 0, z = 0 },
}, { mode = "catmullRom" })

local pos = Core.evaluate(path, 0.5)
local dir = Core.tangent(path, 0.5)
local samples = Core.sampleBySpacing(path, 0.25)

Notes

  • Closed splines wrap the t parameter via t - floor(t); open splines clamp to [0, 1].
  • evaluateEased clamps t before easing — values outside [0, 1] are squashed.
  • tangent uses a small central-difference; on flat / degenerate sections it returns the {x=0, y=0, z=1} fallback.
  • The shared point helpers (add, sub, scale, etc.) are used by the placement and drawing siblings to avoid re-deriving them.