import type { Mat4, Mat4Like, Quat, QuatLike, Vec3, Vec3Like } from './types'; export type { Mat4, Mat4Like }; /** Create a Mat4 (default all zero; callers usually call identity() right after). */ export declare function create(): Mat4; /** Allocate a new Mat4 copy. */ export declare function clone(a: Mat4Like): Mat4; /** out = 4x4 identity. Returns out. */ export declare function identity(out: Mat4): Mat4; /** Approximate equality: each element differs by ≤ epsilon. NaN inputs always return false. */ export declare function equals(a: Mat4Like, b: Mat4Like, epsilon?: number): boolean; /** * out = a * b (column-major matrix multiply). Returns out. * * Aliasing-safe: out may equal a or b; reads all 32 source elements into locals first. */ export declare function multiply(out: Mat4, a: Mat4Like, b: Mat4Like): Mat4; /** out = transpose(a). Returns out. Aliasing-safe (transpose(m, m) is legal). */ export declare function transpose(out: Mat4, a: Mat4Like): Mat4; /** * out = invert(a). Returns out. * * @degrade a singular (|det| < EPS_DET) → out = identity (D-P1; AC-08: returns out, not null). * @degrade aliasing invert(out, out) where out is singular → reads 16 elements into locals before * falling back; R-P1 pins the behavior so that out is overwritten with identity. * * @example * ```ts * import { mat4 } from '@forgeax/engine-math'; * * const inv = mat4.invert(mat4.create(), m); * // If m is singular, inv === identity (no NaN, no null); callers may keep using it. * // For explicit diagnostics, the caller builds its own guard (the library never console.warns): * // const EPS = 1e-12; * // if (mat4.equals(inv, mat4.identity(mat4.create()))) console.warn('mat4.invert: singular input'); * ``` */ export declare function invert(out: Mat4, a: Mat4Like): Mat4; /** * out = a * Scale(v). Returns out. Aliasing-safe (reads the source diagonal columns into locals first). */ export declare function scale(out: Mat4, a: Mat4Like, v: Vec3Like): Mat4; /** * out = a * Translate(v) (translate by v in a's local coordinates). Returns out. Aliasing-safe. */ export declare function translate(out: Mat4, a: Mat4Like, v: Vec3Like): Mat4; /** * out = a * Rotate(axis, rad) (build the rotation via the Rodrigues formula then right-multiply a). * Returns out. * * @degrade axis is the zero vector (lengthSq < EPS_NORMALIZE) → out = a (no rotation; identity behavior). * * @example * ```ts * mat4.rotate(out, mat4.identity(mat4.create()), [0, 1, 0], Math.PI / 2); * // Guard: if (vec3.lengthSq(axis) < EPS_NORMALIZE) skip; * ``` */ export declare function rotate(out: Mat4, a: Mat4Like, axis: Vec3Like, rad: number): Mat4; /** * out = view matrix lookAt(eye, target, up) (right-handed; camera looks toward -z at target). * Returns out. * * @degrade eye === target (distanceSq < EPS_NORMALIZE) → out = identity (D-P17, same convention as D-P1). * @degrade up collinear with the view direction (cross degenerate) → auto-select an alternative up * (first (0,0,1), then (0,1,0)). * * @example * ```ts * mat4.lookAt(out, [0, 0, 5], [0, 0, 0], [0, 1, 0]); * // Guard: if (vec3.distanceSq(eye, target) < EPS_NORMALIZE) skip; * ``` */ export declare function lookAt(out: Mat4, eye: Vec3Like, target: Vec3Like, up: Vec3Like): Mat4; /** * out = T(translation) * R(rotation) * S(scale) (TRS affine composition). Returns out. */ export declare function compose(out: Mat4, t: Vec3Like, r: QuatLike, s: Vec3Like): Mat4; /** * Decompose m into (translation, rotation quat, scale). * * @degrade m contains shear (non-pure affine) → silent best-effort decomposition (matches * Three.js behavior; does not throw). * * @example * ```ts * const t = vec3.create(); const r = quat.create(); const s = vec3.create(); * mat4.decompose(t, r, s, m); * // Guard: callers should avoid introducing shear matrices at the ECS-design layer. * ``` */ export declare function decompose(out_t: Vec3, out_r: Quat, out_s: Vec3, m: Mat4Like): void; /** out = 4x4 rotation matrix from quaternion (no translation, no scale). Returns out. */ export declare function fromQuat(out: Mat4, q: QuatLike): Mat4; /** out = pure translation matrix (translation added to identity). Returns out. */ export declare function fromTranslation(out: Mat4, v: Vec3Like): Mat4; /** out = pure scaling matrix diag(v.x, v.y, v.z, 1). Returns out. */ export declare function fromScaling(out: Mat4, v: Vec3Like): Mat4; /** * out = pure rotation matrix from axis-angle. Returns out. * * @degrade axis is the zero vector → out = identity (same convention as rotate). * * @example * ```ts * mat4.fromRotation(out, [0, 1, 0], Math.PI / 2); * mat4.fromRotation(out, [0, 0, 0], 1); // → identity (zero-axis degenerate, AC-06 no throw) * ``` */ export declare function fromRotation(out: Mat4, axis: Vec3Like, rad: number): Mat4; /** * out = perspective projection (**WebGPU [0, 1] NDC** short name, D-3). Returns out. * * Right-handed; z_eye negative values lie in the frustum; near → ndc_z=0, far → ndc_z=1. * Naming borrowed from wgpu-matrix (short name for WebGPU), unlike gl-matrix (short name for WebGL). * Supports both finite far and infinite far (far=Infinity, aligned with wgpu-matrix * `m[10]=-1, m[14]=-near`). * * @degrade near >= far or fovy <= 0 or aspect <= 0 → numerically undefined but does not throw * (plan §appendix A #7). * * @example * ```ts * mat4.perspective(out, Math.PI / 4, canvas.width / canvas.height, 0.1, 1000); * mat4.perspective(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite-far trick * // Guard: if (!(near < far && fovy > 0 && aspect > 0)) handleInvalid(); * ``` */ export declare function perspective(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4; /** * out = perspective projection (**WebGL/OpenGL [-1, 1] NDC**; *NO* = Negative-One, borrowed from gl-matrix). * * Right-handed, near → ndc_z=-1, far → ndc_z=+1. * * @degrade Same as perspective. * * @example * ```ts * mat4.perspectiveNO(out, Math.PI / 4, canvas.width / canvas.height, 0.1, 1000); * mat4.perspectiveNO(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite-far * // Guard: if (!(near < far && fovy > 0 && aspect > 0)) handleInvalid(); * ``` */ export declare function perspectiveNO(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4; /** * out = reversed-Z perspective projection (**WebGPU [0, 1] NDC, near→1 far→0**). Returns out. * * Precision gain: matches the float dense region ([0, 0.01]) to the slowly-varying far end of 1/z. * Under the standard test conditions `near=0.1, far=10000`, NVIDIA reports a reversed-Z + float32 * depth error rate of 0% (vs. high error rate for the standard mapping). See * `.forgeax-harness/knowledge-base/wiki/reversed-z-projection.md` §5. * * GPU-side companion switches (5 places must be flipped together): * 1. depthCompare: 'greater' (vs 'less') * 2. depthClearValue: 0.0 (vs 1.0) * 3. depth format: 'depth32float' (mandatory; fixed-point loses most of the gain) * 4. depth bias: inverted (avoid worsening z-fighting) * 5. multiple passes must share the reversed-Z convention * * Supports finite and infinite far (from wiki §3.3 / §4.2 derivations): * - finite: m[10]=near/(far-near), m[14]=near*far/(far-near) * - infinite (far=Infinity): m[10]=0, m[14]=near (lim f→∞ limit values) * * Numeric fixture (AC-05 error ≤ 1e-5): see __tests__/_fixtures.ts. * * @degrade Same as perspective. * * @example * ```ts * mat4.perspectiveReverseZ(out, Math.PI / 4, aspect, 0.1, 100); * mat4.perspectiveReverseZ(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite far * // GPU companion: pipeline.depthCompare = 'greater'; passDesc.depthClearValue = 0.0; * ``` */ export declare function perspectiveReverseZ(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4; /** * out = orthographic projection (**WebGPU [0, 1] NDC** short name, D-3). Returns out. * * @degrade near >= far or left >= right or top <= bottom → numerically undefined but does not throw. * * @example * ```ts * mat4.orthographic(out, -10, 10, 10, -10, 0.1, 100); * // Guard: if (!(left < right && top > bottom && near < far)) handleInvalid(); * ``` */ export declare function orthographic(out: Mat4, left: number, right: number, top: number, bottom: number, near: number, far: number): Mat4; /** out = orthographic projection (**WebGL/OpenGL [-1, 1] NDC**, *NO*). Returns out. */ export declare function orthographicNO(out: Mat4, left: number, right: number, top: number, bottom: number, near: number, far: number): Mat4; /** * out = reversed-Z orthographic projection (**WebGPU [0, 1] NDC, near→1 far→0**; * D-P3 self-extension). * * Pairs with perspectiveReverseZ to form a symmetric three-tier surface; in orthographic * projection the reversed-Z precision gain is small (ortho is linear in z), but it is kept to * avoid LLM single-pass-scan cognitive load (charter proposition 1). * Note: this function is an @forgeax/engine-math self-extension; wgpu-matrix / gl-matrix have no matching * name (see plan-strategy D-P3 + README quick-ref table footnote). */ export declare function orthographicReverseZ(out: Mat4, left: number, right: number, top: number, bottom: number, near: number, far: number): Mat4; /** * out = M * (v.x, v.y, v.z, 1) (with perspective divide by w'). Returns out. * * For affine m this is equivalent to transformPoint (treats v as a "position" that participates * in the transform, including translation). * Aliasing-safe: reads v.xyz into locals before writing out. * * @degrade w' = 0 (perspective divide by zero) → out = (0, 0, 0) (D-4 silent convention; avoids * NaN/Infinity propagation; stricter than the implicit 1/0 = Infinity behavior of * Three.js / gl-matrix). * * @example * ```ts * mat4.transformVec3(out, projViewModel, v); * // Guard: if (out[0] === 0 && out[1] === 0 && out[2] === 0 && wasNonZero(v)) { * // // w'=0 degenerate branch; the caller diagnoses as needed * // } * ``` */ export declare function transformVec3(out: Vec3, m: Mat4Like, v: Vec3Like): Vec3; /** * out = M * (v.x, v.y, v.z, 1) (with perspective divide by w'). Returns out. * * Treats v as a "position", including the translation column (shares the same function body as * transformVec3; OQ-1 / S-1). * Aliasing-safe; reference-equal with transformVec3: `mat4.transformPoint === mat4.transformVec3`. * * @degrade w' = 0 (perspective divide by zero) → out = (0, 0, 0) (D-4 silent convention; * same as transformVec3). * * @example * ```ts * mat4.transformPoint(out, modelMatrix, [1, 2, 3]); * // (1,2,3) → world-space position, including translation * ``` */ export declare const transformPoint: typeof transformVec3; /** * out = normalize(M_3x3 * v) (uses m's upper-left 3×3, no translation column). Returns out. * * Treats v as a "direction" and does **not** apply translation; the result is unit-normalized via * `vec3.normalize` (OQ-2 / S-2). * Aliasing-safe: reads v.xyz into locals before writing out. * * @degrade |out| = 0 (singular m + arbitrary v / m_3x3 maps v to the zero vector) → vec3.normalize * silently falls back to (0, 0, 0) (library-wide D-4 convention). * * @example * ```ts * const worldNormal = vec3.create(); * mat4.transformDirection(worldNormal, modelMatrix, localNormal); * // Normal-vector transform: ignores translation; a unit-length input + orthogonal matrix * // guarantees a unit-length output. * ``` */ export declare function transformDirection(out: Vec3, m: Mat4Like, v: Vec3Like): Vec3; /** * World-space translation = col 3 (m[12], m[13], m[14]). Read verbatim, not * normalized (translation has magnitude). */ export declare function getTranslation(out: Vec3, m: Mat4Like): Vec3; /** * World-space forward = `-normalize(col2)` (RL-4: -Z look convention; matches * `quat.transformVec3(q, [0, 0, -1])`). Degenerate zero column → (0,0,0). */ export declare function getForward(out: Vec3, m: Mat4Like): Vec3; /** World-space up = `normalize(col1)`. Degenerate zero column → (0,0,0). */ export declare function getUp(out: Vec3, m: Mat4Like): Vec3; /** World-space right = `normalize(col0)`. Degenerate zero column → (0,0,0). */ export declare function getRight(out: Vec3, m: Mat4Like): Vec3; /** * Unproject an NDC point to world space. * * `ndcPoint` is in NDC space: x,y ∈ [-1,1], z ∈ [0,1] (WebGPU convention). * `invVP` is the inverse of the view-projection matrix. * * @example * ```ts * const worldPoint = vec3.create(); * mat4.unproject(worldPoint, [0, 0, 0], invVP); // near-plane centre → world * mat4.unproject(worldPoint, [0, 0, 1], invVP); // far-plane centre → world * ``` */ export declare function unproject(out: Vec3, ndcPoint: Vec3Like, invVP: Mat4Like): Vec3; /** * Project a world-space point to NDC space through a view-projection matrix. * * `worldPos` is a position (treated with translation column, not a direction). * `viewProj` is `proj × view` (eye→clip composed with world→eye). * Output NDC is WebGPU convention: x,y ∈ [-1,1], z ∈ [0,1] (near=0 / far=1). * * To map NDC to viewport pixels (DOM y-down): * px = (ndc.x * 0.5 + 0.5) * vpWidth * py = (1 - (ndc.y * 0.5 + 0.5)) * vpHeight * `ndc.z < 0` or `ndc.z > 1` means the point is outside the depth range * (behind near or beyond far); callers typically skip drawing the HUD anchor. * * @degrade w' = 0 (point lies on the camera plane) → out = (0, 0, 0) * (D-4 silent convention; inherited from transformVec3). * * @example * ```ts * const ndc = vec3.create(); * mat4.projectPoint(ndc, worldPos, viewProj); * if (ndc[2] >= 0 && ndc[2] <= 1) { * const px = (ndc[0] * 0.5 + 0.5) * canvas.width; * const py = (1 - (ndc[1] * 0.5 + 0.5)) * canvas.height; * // anchor DOM tooltip at (px, py) * } * ``` */ export declare function projectPoint(out: Vec3, worldPos: Vec3Like, viewProj: Mat4Like): Vec3; /** * Compute a combined view-projection matrix from camera parameters. * * This is a convenience composition of `mat4.perspective * mat4.lookAt`, not a primitive. * All parameters are plain numbers / Vec3Like — no runtime POD types (math zero-dep). * * @param out Mat4 to write the result into. * @param eye Camera position in world space. * @param target Point the camera looks at. * @param up Approximate up direction. * @param fovYRadians Vertical field of view in radians. * @param aspect Aspect ratio (width / height). * @param near Near clip distance (positive). * @param far Far clip distance (positive, or Infinity for infinite-far). * @returns `out` (same Mat4 instance). */ export declare function computeViewProj(out: Mat4, eye: Vec3Like, target: Vec3Like, up: Vec3Like, fovYRadians: number, aspect: number, near: number, far: number): Mat4; //# sourceMappingURL=mat4.d.ts.map