Manual/ Referencia de la API

Vec3

Vectores 3D: operaciones, ángulos, interpolación, suavizado y proyecciones.

Vector de tres componentes para posiciones, direcciones, velocidades, giros en grados, escalas y colores. Las funciones se pueden llamar de dos formas equivalentes: a:distance(b) o Vec3.distance(a, b).

local a = Vec3(1, 2, 3)
local b = Vec3()               -- (0, 0, 0)
local c = a + b * 2 - Vec3.up  -- suma, resta y escala
local d = a * Vec3(1, 0, 1)    -- producto por componentes
print(a.x, a.y, a.z, a)        -- los campos se leen y escriben
print("posicion: " .. a)       -- se concatena con texto: posicion: (1.000, 2.000, 3.000)

local largo = a:length()
local dir   = (b - a):normalized()
local cerca = a:distance(b) < 2
local medio = Vec3.lerp(a, b, 0.5)

Crear y copiar

MiembroDescripción
Vec3(x, y, z), Vec3()Vector nuevo (sin argumentos: cero).
Vec3(x, y)Con z = 0.
Vec3(v), v:copy()Copia independiente de otro vector.
x, y, zComponentes (lectura y escritura).
v:set(x, y, z)Cambia los tres componentes de golpe.
v:unpack()Devuelve x, y, z: local x, y, z = v:unpack().
Vec3.zero, one, up, down, left, right, forward, backConstantes. forward es (0, 0, -1): en Cramion "adelante" es -Z.

Operadores

OperaciónResultado
a + b, a - b, -aSuma, resta y opuesto.
v * 2, 2 * v, v / 2Escala por un número.
a * b, a / bMultiplica o divide por componentes.
a == bIguales exactamente (para "casi iguales" usa approximately).
tostring(v), "texto" .. vTexto (1.000, 2.000, 3.000).

Longitud, distancia y ángulos

FunciónDescripción
v:length(), v:sqrLength()Longitud y longitud al cuadrado (más rápida para comparar).
v:normalized()Mismo sentido, longitud 1 (o cero si v es cero).
v:clampLength(max)Lo acorta si es más largo que max (limitar una velocidad).
Vec3.distance(a, b), Vec3.sqrDistance(a, b)Distancia entre dos puntos (y al cuadrado).
Vec3.dot(a, b)Producto escalar: positivo si miran hacia el mismo lado.
Vec3.cross(a, b)Producto vectorial: perpendicular a los dos.
Vec3.angle(a, b)Ángulo entre dos direcciones, en grados (0 a 180).
Vec3.signedAngle(a, b, eje)Ángulo con signo alrededor de eje (-180 a 180): a qué lado queda b.

Interpolar y mover

FunciónDescripción
Vec3.lerp(a, b, t)Punto entre a y b (t se limita a 0..1).
Vec3.lerpUnclamped(a, b, t)Igual, sin limitar t (extrapola).
Vec3.slerp(a, b, t)Gira la dirección de a hacia b y mezcla su longitud.
Vec3.moveTowards(actual, objetivo, paso)Avanza hacia el objetivo como mucho paso sin pasarse.
Vec3.smoothDamp(actual, objetivo, vel, tiempo, dt [, maxVel])Seguimiento suave, como un muelle sin rebote. Devuelve dos valores: la posición nueva y la velocidad (guárdala para el siguiente frame).

Proyectar y reflejar

FunciónDescripción
Vec3.project(v, sobre)La parte de v en la dirección sobre.
Vec3.projectOnPlane(v, normal)Aplasta v sobre un plano: por ejemplo, moverse por una rampa.
Vec3.reflect(dir, normal)Rebote de una dirección contra una superficie.

Por componentes

FunciónDescripción
Vec3.scale(a, b)Multiplica componente a componente (como a * b).
Vec3.min(a, b), Vec3.max(a, b)El menor o el mayor de cada componente.
v:abs(), v:floor(), v:ceil(), v:round()Valor absoluto y redondeos de cada componente (útil para rejillas).
Vec3.approximately(a, b [, margen])Casi iguales (distancia menor que margen, 0.0001 por defecto).

Ejemplos

Seguir con suavidad (smoothDamp)

local Seguir = { properties = { objetivo = "Jugador", suavidad = 0.25 } }

function Seguir:Start()
    self.meta = Scene.find(self.objetivo)
    self.vel = Vec3.zero:copy()
end

function Seguir:LateUpdate(dt)
    if not self.meta then return end
    local destino = self.meta.position + Vec3(0, 3, 6)
    local pos
    pos, self.vel = Vec3.smoothDamp(self.entity.position, destino, self.vel, self.suavidad, dt)
    self.entity.position = pos
end

return Seguir

¿Está delante de mí? ¿A qué lado?

local haciaEl = (enemigo.position - self.entity.position):normalized()
local delante = Vec3.dot(self.entity.forward, haciaEl) > 0.5          -- dentro de un cono de ~60 grados
local lado = Vec3.signedAngle(self.entity.forward, haciaEl, Vec3.up)  -- > 0: a la izquierda, < 0: a la derecha
Copias: las propiedades de una entidad devuelven una copia, así que self.entity.position.y = 3 no la mueve. Lee, modifica y vuelve a asignar: local p = self.entity.position; p.y = 3; self.entity.position = p. En cambio, local b = a no copia: las dos variables son el mismo vector (como una tabla). Usa a:copy() si vas a modificar uno sin tocar el otro, y no modifiques las constantes como Vec3.zero.

¿Algo no queda claro o falta algo? Pregunta en el Discord.