Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit3bb1da2647

README.md

core

Core boid simulation primitives — the spatial grid for O(1) neighbour queries, a struct-of-arrays boid storage container, and the per-boid force / integration math used by the outer boids.module flock loop.

Exports

  • Core.SpatialGrid.new(cellSize: number) -> SpatialGridInstance — construct a grid.
  • SpatialGrid:clear() — wipe every cell.
  • SpatialGrid:insert(index, x, y, z) — drop a boid index into the cell containing (x, y, z).
  • SpatialGrid:query(px, py, pz, radius, positions, results) -> number — fill results with neighbour indices and return the count.
  • Core.BoidData.new(capacity: number) -> BoidDataInstance — construct an empty struct-of-arrays container.
  • BoidData:add(entityId, px, py, pz, vx, vy, vz) -> number — append a boid and return its index.
  • BoidData:remove(index) — mark a boid dead.
  • Core.calculateFlockForces(boidIdx, data, neighbors, neighborCount, sepW, aliW, cohW, sepDist, viewAngleCos) -> (number, number, number) — combined separation + alignment + cohesion force.
  • Core.integrate(data, index, fx, fy, fz, dt, minSpeed, maxSpeed, maxForce) — clamp, integrate, mutate data in place.
  • Core.velocityToQuaternion(vx, vy, vz) -> (number, number, number, number) — yaw/pitch quaternion from velocity direction.
  • Core.v3len, Core.v3dist, Core.v3normalize, Core.v3clampMag — scalar-form vec3 helpers.

Types:

  • Vec3Triple = { number } — vec3 as an { x, y, z } array.
  • SpatialGridInstance — { cellSize, cells, _invCell, clear, insert, query }.
  • BoidDataInstance — { count, positions, velocities, entityIds, alive, add, remove }.

Usage

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

local grid = Core.SpatialGrid.new(5.0)
local data = Core.BoidData.new(50)
local i = data:add(eid, px, py, pz, vx, vy, vz)

grid:clear()
grid:insert(i, px, py, pz)

local neighbors = {}
local n = grid:query(px, py, pz, 5.0, data.positions, neighbors)

local fx, fy, fz = Core.calculateFlockForces(i, data, neighbors, n, 1.5, 1.0, 1.0, 2.0, viewAngleCos)
Core.integrate(data, i, fx, fy, fz, dt, 1.5, 4.0, 8.0)

local qx, qy, qz, qw = Core.velocityToQuaternion(vx, vy, vz)

Notes

  • All math is scalar-form (no allocated vec3 tables in the hot path); intermediate positions and velocities live in pre-allocated { x, y, z } arrays inside the BoidData container.
  • SpatialGrid:query overwrites results starting at index 1 and returns the count, so callers can recycle the same buffer between frames without per-call allocation. Entries beyond the returned count are stale and must not be read.
  • Core.integrate mutates the supplied BoidData entry in place.
  • BoidData:remove does not compact the underlying arrays — dead slots stay in place and are skipped on iteration via alive[i].