@forgeax/engine-math 0.0.0-dev.8d955ade1c79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +294 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/_arbs.d.ts +36 -0
  5. package/dist/__tests__/_arbs.d.ts.map +1 -0
  6. package/dist/__tests__/_fixtures.d.ts +61 -0
  7. package/dist/__tests__/_fixtures.d.ts.map +1 -0
  8. package/dist/__tests__/bounds2.test.d.ts +2 -0
  9. package/dist/__tests__/bounds2.test.d.ts.map +1 -0
  10. package/dist/__tests__/box3.test.d.ts +2 -0
  11. package/dist/__tests__/box3.test.d.ts.map +1 -0
  12. package/dist/__tests__/easing.test.d.ts +2 -0
  13. package/dist/__tests__/easing.test.d.ts.map +1 -0
  14. package/dist/__tests__/euler.test-d.d.ts +2 -0
  15. package/dist/__tests__/euler.test-d.d.ts.map +1 -0
  16. package/dist/__tests__/mat3.test-d.d.ts +2 -0
  17. package/dist/__tests__/mat3.test-d.d.ts.map +1 -0
  18. package/dist/__tests__/mat4.property.test.d.ts +2 -0
  19. package/dist/__tests__/mat4.property.test.d.ts.map +1 -0
  20. package/dist/__tests__/mat4.test-d.d.ts +2 -0
  21. package/dist/__tests__/mat4.test-d.d.ts.map +1 -0
  22. package/dist/__tests__/mat4.test.d.ts +2 -0
  23. package/dist/__tests__/mat4.test.d.ts.map +1 -0
  24. package/dist/__tests__/noise.test.d.ts +2 -0
  25. package/dist/__tests__/noise.test.d.ts.map +1 -0
  26. package/dist/__tests__/quat.basis.test.d.ts +2 -0
  27. package/dist/__tests__/quat.basis.test.d.ts.map +1 -0
  28. package/dist/__tests__/quat.interpolation.test.d.ts +2 -0
  29. package/dist/__tests__/quat.interpolation.test.d.ts.map +1 -0
  30. package/dist/__tests__/quat.lookat.test.d.ts +2 -0
  31. package/dist/__tests__/quat.lookat.test.d.ts.map +1 -0
  32. package/dist/__tests__/quat.property.test.d.ts +2 -0
  33. package/dist/__tests__/quat.property.test.d.ts.map +1 -0
  34. package/dist/__tests__/quat.rotateaxis.test.d.ts +2 -0
  35. package/dist/__tests__/quat.rotateaxis.test.d.ts.map +1 -0
  36. package/dist/__tests__/quat.test-d.d.ts +2 -0
  37. package/dist/__tests__/quat.test-d.d.ts.map +1 -0
  38. package/dist/__tests__/ray.property.test.d.ts +2 -0
  39. package/dist/__tests__/ray.property.test.d.ts.map +1 -0
  40. package/dist/__tests__/ray.test.d.ts +2 -0
  41. package/dist/__tests__/ray.test.d.ts.map +1 -0
  42. package/dist/__tests__/types.test-d.d.ts +2 -0
  43. package/dist/__tests__/types.test-d.d.ts.map +1 -0
  44. package/dist/__tests__/vec-catmull-rom.test.d.ts +2 -0
  45. package/dist/__tests__/vec-catmull-rom.test.d.ts.map +1 -0
  46. package/dist/__tests__/vec-smooth-damp.test.d.ts +2 -0
  47. package/dist/__tests__/vec-smooth-damp.test.d.ts.map +1 -0
  48. package/dist/__tests__/vec2.test-d.d.ts +2 -0
  49. package/dist/__tests__/vec2.test-d.d.ts.map +1 -0
  50. package/dist/__tests__/vec3.property.test.d.ts +2 -0
  51. package/dist/__tests__/vec3.property.test.d.ts.map +1 -0
  52. package/dist/__tests__/vec3.test-d.d.ts +2 -0
  53. package/dist/__tests__/vec3.test-d.d.ts.map +1 -0
  54. package/dist/__tests__/vec4.test-d.d.ts +2 -0
  55. package/dist/__tests__/vec4.test-d.d.ts.map +1 -0
  56. package/dist/_internal/epsilon.d.ts +9 -0
  57. package/dist/_internal/epsilon.d.ts.map +1 -0
  58. package/dist/_internal/scalar.d.ts +40 -0
  59. package/dist/_internal/scalar.d.ts.map +1 -0
  60. package/dist/box2.d.ts +35 -0
  61. package/dist/box2.d.ts.map +1 -0
  62. package/dist/box3.d.ts +76 -0
  63. package/dist/box3.d.ts.map +1 -0
  64. package/dist/circle2.d.ts +29 -0
  65. package/dist/circle2.d.ts.map +1 -0
  66. package/dist/color.d.ts +64 -0
  67. package/dist/color.d.ts.map +1 -0
  68. package/dist/easing.d.ts +18 -0
  69. package/dist/easing.d.ts.map +1 -0
  70. package/dist/euler.d.ts +51 -0
  71. package/dist/euler.d.ts.map +1 -0
  72. package/dist/f32-to-f16-bytes.d.ts +10 -0
  73. package/dist/f32-to-f16-bytes.d.ts.map +1 -0
  74. package/dist/frustum.d.ts +49 -0
  75. package/dist/frustum.d.ts.map +1 -0
  76. package/dist/index.d.ts +20 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.mjs +3688 -0
  79. package/dist/index.mjs.map +1 -0
  80. package/dist/mat3.d.ts +70 -0
  81. package/dist/mat3.d.ts.map +1 -0
  82. package/dist/mat4.d.ts +329 -0
  83. package/dist/mat4.d.ts.map +1 -0
  84. package/dist/noise.d.ts +12 -0
  85. package/dist/noise.d.ts.map +1 -0
  86. package/dist/quat.d.ts +312 -0
  87. package/dist/quat.d.ts.map +1 -0
  88. package/dist/ray.d.ts +144 -0
  89. package/dist/ray.d.ts.map +1 -0
  90. package/dist/ray2.d.ts +38 -0
  91. package/dist/ray2.d.ts.map +1 -0
  92. package/dist/sphere.d.ts +41 -0
  93. package/dist/sphere.d.ts.map +1 -0
  94. package/dist/types.d.ts +57 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/vec2.d.ts +76 -0
  97. package/dist/vec2.d.ts.map +1 -0
  98. package/dist/vec3.d.ts +82 -0
  99. package/dist/vec3.d.ts.map +1 -0
  100. package/dist/vec4.d.ts +61 -0
  101. package/dist/vec4.d.ts.map +1 -0
  102. package/package.json +57 -0
  103. package/src/__tests__/_arbs.ts +149 -0
  104. package/src/__tests__/_fixtures.ts +118 -0
  105. package/src/__tests__/bounds2.test.ts +146 -0
  106. package/src/__tests__/box3.test.ts +277 -0
  107. package/src/__tests__/easing.test.ts +109 -0
  108. package/src/__tests__/euler.test-d.ts +63 -0
  109. package/src/__tests__/mat3.test-d.ts +47 -0
  110. package/src/__tests__/mat4.property.test.ts +256 -0
  111. package/src/__tests__/mat4.test-d.ts +130 -0
  112. package/src/__tests__/mat4.test.ts +162 -0
  113. package/src/__tests__/noise.test.ts +75 -0
  114. package/src/__tests__/quat.basis.test.ts +134 -0
  115. package/src/__tests__/quat.interpolation.test.ts +45 -0
  116. package/src/__tests__/quat.lookat.test.ts +103 -0
  117. package/src/__tests__/quat.property.test.ts +150 -0
  118. package/src/__tests__/quat.rotateaxis.test.ts +149 -0
  119. package/src/__tests__/quat.test-d.ts +138 -0
  120. package/src/__tests__/ray.property.test.ts +105 -0
  121. package/src/__tests__/ray.test.ts +539 -0
  122. package/src/__tests__/types.test-d.ts +64 -0
  123. package/src/__tests__/vec-catmull-rom.test.ts +125 -0
  124. package/src/__tests__/vec-smooth-damp.test.ts +167 -0
  125. package/src/__tests__/vec2.test-d.ts +59 -0
  126. package/src/__tests__/vec3.property.test.ts +72 -0
  127. package/src/__tests__/vec3.test-d.ts +65 -0
  128. package/src/__tests__/vec4.test-d.ts +61 -0
  129. package/src/_internal/epsilon.ts +29 -0
  130. package/src/_internal/scalar.ts +90 -0
  131. package/src/box2.ts +168 -0
  132. package/src/box3.ts +372 -0
  133. package/src/circle2.ts +134 -0
  134. package/src/color.ts +177 -0
  135. package/src/easing.ts +49 -0
  136. package/src/euler.ts +239 -0
  137. package/src/f32-to-f16-bytes.ts +71 -0
  138. package/src/frustum.ts +240 -0
  139. package/src/index.ts +65 -0
  140. package/src/mat3.ts +286 -0
  141. package/src/mat4.ts +1334 -0
  142. package/src/noise.ts +78 -0
  143. package/src/quat.ts +847 -0
  144. package/src/ray.ts +575 -0
  145. package/src/ray2.ts +198 -0
  146. package/src/sphere.ts +138 -0
  147. package/src/types.ts +78 -0
  148. package/src/vec2.ts +229 -0
  149. package/src/vec3.ts +294 -0
  150. package/src/vec4.ts +235 -0
package/dist/mat3.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import type { Mat3, Mat3Like, Mat4Like, Vec3Like } from './types';
2
+ export type { Mat3, Mat3Like };
3
+ /** Create a Mat3 (default all zero; callers usually call identity() right after). */
4
+ export declare function create(): Mat3;
5
+ /** Allocate a new Mat3 copy. */
6
+ export declare function clone(a: Mat3Like): Mat3;
7
+ /** out = 3x3 identity (column-major [1,0,0, 0,1,0, 0,0,1]). Returns out. */
8
+ export declare function identity(out: Mat3): Mat3;
9
+ /** Approximate equality: each element differs by ≤ epsilon. NaN inputs always return false. */
10
+ export declare function equals(a: Mat3Like, b: Mat3Like, epsilon?: number): boolean;
11
+ /**
12
+ * out = a * b (column-major matrix multiply). Returns out.
13
+ *
14
+ * Aliasing-safe: out may equal a or b; reads all 18 source elements into locals first.
15
+ */
16
+ export declare function multiply(out: Mat3, a: Mat3Like, b: Mat3Like): Mat3;
17
+ /**
18
+ * out = transpose(a). Returns out.
19
+ *
20
+ * Aliasing-safe (transpose(m, m) is legal; reads the 6 off-diagonal elements into locals first).
21
+ */
22
+ export declare function transpose(out: Mat3, a: Mat3Like): Mat3;
23
+ /**
24
+ * out = invert(a). Returns out.
25
+ *
26
+ * @degrade a singular (|det| < EPS_DET) → out = identity (same convention as D-P1; does not return null).
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * // Caller-side guard:
31
+ * const det = mat3DetForGuard(m); // caller computes det to decide whether to invert
32
+ * const inv = mat3.invert(mat3.create(), m);
33
+ * // If m is singular, inv === identity (no NaN; safe to keep using).
34
+ * ```
35
+ */
36
+ export declare function invert(out: Mat3, a: Mat3Like): Mat3;
37
+ /**
38
+ * out = a * Scale(v) (per-column scale). Returns out.
39
+ *
40
+ * v takes the first 3 components (aligned with mat4.scale's vec3 input); mat3's third column is the z scale.
41
+ */
42
+ export declare function scale(out: Mat3, a: Mat3Like, v: Vec3Like): Mat3;
43
+ /**
44
+ * out = mat3 extracted from mat4's upper-left 3x3 (drop the 4th row and 4th column). Returns out.
45
+ *
46
+ * Column-major mapping: mat4 col0 [0..2] / col1 [4..6] / col2 [8..10] → mat3 col0/1/2.
47
+ */
48
+ export declare function fromMat4(out: Mat3, m: Mat4Like): Mat3;
49
+ /**
50
+ * out = transpose(invert(upper-left 3x3 of m)) (the normal-transform matrix). Returns out.
51
+ *
52
+ * Used to transform normals from model space to world / view space; when m has a non-uniform
53
+ * scale, normals must use normalMatrix (the upper-left 3x3 of m alone is incorrect).
54
+ *
55
+ * Per-frame consumer: feat-20260518-pbr-direct-lighting-mvp M3 / w14 wires
56
+ * `render-system-record.ts` to call this helper once per renderable per frame
57
+ * (host-side computation; result lives in mesh SSBO `normalMatrix` slot at
58
+ * byte offset 64 within each PER_ENTITY_STRIDE = 256 B slot, plan-strategy
59
+ * D-5 + AC-08).
60
+ *
61
+ * @degrade upper-left 3x3 singular -> out = identity (same convention as D-P1, via mat3.invert).
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const N = mat3.normalMatrix(mat3.create(), modelViewMat);
66
+ * // vertex shader: normal_view = N * normal_model
67
+ * ```
68
+ */
69
+ export declare function normalMatrix(out: Mat3, m: Mat4Like): Mat3;
70
+ //# sourceMappingURL=mat3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mat3.d.ts","sourceRoot":"","sources":["../src/mat3.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAElE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAE/B,qFAAqF;AACrF,wBAAgB,MAAM,IAAI,IAAI,CAE7B;AAED,gCAAgC;AAChC,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAYvC;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAWxC;AAED,+FAA+F;AAC/F,wBAAgB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,SAAO,GAAG,OAAO,CAQxE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CA6BlE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAiBtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAgCnD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAc/D;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAWrD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAyCzD"}
package/dist/mat4.d.ts ADDED
@@ -0,0 +1,329 @@
1
+ import type { Mat4, Mat4Like, Quat, QuatLike, Vec3, Vec3Like } from './types';
2
+ export type { Mat4, Mat4Like };
3
+ /** Create a Mat4 (default all zero; callers usually call identity() right after). */
4
+ export declare function create(): Mat4;
5
+ /** Allocate a new Mat4 copy. */
6
+ export declare function clone(a: Mat4Like): Mat4;
7
+ /** out = 4x4 identity. Returns out. */
8
+ export declare function identity(out: Mat4): Mat4;
9
+ /** Approximate equality: each element differs by ≤ epsilon. NaN inputs always return false. */
10
+ export declare function equals(a: Mat4Like, b: Mat4Like, epsilon?: number): boolean;
11
+ /**
12
+ * out = a * b (column-major matrix multiply). Returns out.
13
+ *
14
+ * Aliasing-safe: out may equal a or b; reads all 32 source elements into locals first.
15
+ */
16
+ export declare function multiply(out: Mat4, a: Mat4Like, b: Mat4Like): Mat4;
17
+ /** out = transpose(a). Returns out. Aliasing-safe (transpose(m, m) is legal). */
18
+ export declare function transpose(out: Mat4, a: Mat4Like): Mat4;
19
+ /**
20
+ * out = invert(a). Returns out.
21
+ *
22
+ * @degrade a singular (|det| < EPS_DET) → out = identity (D-P1; AC-08: returns out, not null).
23
+ * @degrade aliasing invert(out, out) where out is singular → reads 16 elements into locals before
24
+ * falling back; R-P1 pins the behavior so that out is overwritten with identity.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { mat4 } from '@forgeax/engine-math';
29
+ *
30
+ * const inv = mat4.invert(mat4.create(), m);
31
+ * // If m is singular, inv === identity (no NaN, no null); callers may keep using it.
32
+ * // For explicit diagnostics, the caller builds its own guard (the library never console.warns):
33
+ * // const EPS = 1e-12;
34
+ * // if (mat4.equals(inv, mat4.identity(mat4.create()))) console.warn('mat4.invert: singular input');
35
+ * ```
36
+ */
37
+ export declare function invert(out: Mat4, a: Mat4Like): Mat4;
38
+ /**
39
+ * out = a * Scale(v). Returns out. Aliasing-safe (reads the source diagonal columns into locals first).
40
+ */
41
+ export declare function scale(out: Mat4, a: Mat4Like, v: Vec3Like): Mat4;
42
+ /**
43
+ * out = a * Translate(v) (translate by v in a's local coordinates). Returns out. Aliasing-safe.
44
+ */
45
+ export declare function translate(out: Mat4, a: Mat4Like, v: Vec3Like): Mat4;
46
+ /**
47
+ * out = a * Rotate(axis, rad) (build the rotation via the Rodrigues formula then right-multiply a).
48
+ * Returns out.
49
+ *
50
+ * @degrade axis is the zero vector (lengthSq < EPS_NORMALIZE) → out = a (no rotation; identity behavior).
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * mat4.rotate(out, mat4.identity(mat4.create()), [0, 1, 0], Math.PI / 2);
55
+ * // Guard: if (vec3.lengthSq(axis) < EPS_NORMALIZE) skip;
56
+ * ```
57
+ */
58
+ export declare function rotate(out: Mat4, a: Mat4Like, axis: Vec3Like, rad: number): Mat4;
59
+ /**
60
+ * out = view matrix lookAt(eye, target, up) (right-handed; camera looks toward -z at target).
61
+ * Returns out.
62
+ *
63
+ * @degrade eye === target (distanceSq < EPS_NORMALIZE) → out = identity (D-P17, same convention as D-P1).
64
+ * @degrade up collinear with the view direction (cross degenerate) → auto-select an alternative up
65
+ * (first (0,0,1), then (0,1,0)).
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * mat4.lookAt(out, [0, 0, 5], [0, 0, 0], [0, 1, 0]);
70
+ * // Guard: if (vec3.distanceSq(eye, target) < EPS_NORMALIZE) skip;
71
+ * ```
72
+ */
73
+ export declare function lookAt(out: Mat4, eye: Vec3Like, target: Vec3Like, up: Vec3Like): Mat4;
74
+ /**
75
+ * out = T(translation) * R(rotation) * S(scale) (TRS affine composition). Returns out.
76
+ */
77
+ export declare function compose(out: Mat4, t: Vec3Like, r: QuatLike, s: Vec3Like): Mat4;
78
+ /**
79
+ * Decompose m into (translation, rotation quat, scale).
80
+ *
81
+ * @degrade m contains shear (non-pure affine) → silent best-effort decomposition (matches
82
+ * Three.js behavior; does not throw).
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const t = vec3.create(); const r = quat.create(); const s = vec3.create();
87
+ * mat4.decompose(t, r, s, m);
88
+ * // Guard: callers should avoid introducing shear matrices at the ECS-design layer.
89
+ * ```
90
+ */
91
+ export declare function decompose(out_t: Vec3, out_r: Quat, out_s: Vec3, m: Mat4Like): void;
92
+ /** out = 4x4 rotation matrix from quaternion (no translation, no scale). Returns out. */
93
+ export declare function fromQuat(out: Mat4, q: QuatLike): Mat4;
94
+ /** out = pure translation matrix (translation added to identity). Returns out. */
95
+ export declare function fromTranslation(out: Mat4, v: Vec3Like): Mat4;
96
+ /** out = pure scaling matrix diag(v.x, v.y, v.z, 1). Returns out. */
97
+ export declare function fromScaling(out: Mat4, v: Vec3Like): Mat4;
98
+ /**
99
+ * out = pure rotation matrix from axis-angle. Returns out.
100
+ *
101
+ * @degrade axis is the zero vector → out = identity (same convention as rotate).
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * mat4.fromRotation(out, [0, 1, 0], Math.PI / 2);
106
+ * mat4.fromRotation(out, [0, 0, 0], 1); // → identity (zero-axis degenerate, AC-06 no throw)
107
+ * ```
108
+ */
109
+ export declare function fromRotation(out: Mat4, axis: Vec3Like, rad: number): Mat4;
110
+ /**
111
+ * out = perspective projection (**WebGPU [0, 1] NDC** short name, D-3). Returns out.
112
+ *
113
+ * Right-handed; z_eye negative values lie in the frustum; near → ndc_z=0, far → ndc_z=1.
114
+ * Naming borrowed from wgpu-matrix (short name for WebGPU), unlike gl-matrix (short name for WebGL).
115
+ * Supports both finite far and infinite far (far=Infinity, aligned with wgpu-matrix
116
+ * `m[10]=-1, m[14]=-near`).
117
+ *
118
+ * @degrade near >= far or fovy <= 0 or aspect <= 0 → numerically undefined but does not throw
119
+ * (plan §appendix A #7).
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * mat4.perspective(out, Math.PI / 4, canvas.width / canvas.height, 0.1, 1000);
124
+ * mat4.perspective(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite-far trick
125
+ * // Guard: if (!(near < far && fovy > 0 && aspect > 0)) handleInvalid();
126
+ * ```
127
+ */
128
+ export declare function perspective(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4;
129
+ /**
130
+ * out = perspective projection (**WebGL/OpenGL [-1, 1] NDC**; *NO* = Negative-One, borrowed from gl-matrix).
131
+ *
132
+ * Right-handed, near → ndc_z=-1, far → ndc_z=+1.
133
+ *
134
+ * @degrade Same as perspective.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * mat4.perspectiveNO(out, Math.PI / 4, canvas.width / canvas.height, 0.1, 1000);
139
+ * mat4.perspectiveNO(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite-far
140
+ * // Guard: if (!(near < far && fovy > 0 && aspect > 0)) handleInvalid();
141
+ * ```
142
+ */
143
+ export declare function perspectiveNO(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4;
144
+ /**
145
+ * out = reversed-Z perspective projection (**WebGPU [0, 1] NDC, near→1 far→0**). Returns out.
146
+ *
147
+ * Precision gain: matches the float dense region ([0, 0.01]) to the slowly-varying far end of 1/z.
148
+ * Under the standard test conditions `near=0.1, far=10000`, NVIDIA reports a reversed-Z + float32
149
+ * depth error rate of 0% (vs. high error rate for the standard mapping). See
150
+ * `.forgeax-harness/knowledge-base/wiki/reversed-z-projection.md` §5.
151
+ *
152
+ * GPU-side companion switches (5 places must be flipped together):
153
+ * 1. depthCompare: 'greater' (vs 'less')
154
+ * 2. depthClearValue: 0.0 (vs 1.0)
155
+ * 3. depth format: 'depth32float' (mandatory; fixed-point loses most of the gain)
156
+ * 4. depth bias: inverted (avoid worsening z-fighting)
157
+ * 5. multiple passes must share the reversed-Z convention
158
+ *
159
+ * Supports finite and infinite far (from wiki §3.3 / §4.2 derivations):
160
+ * - finite: m[10]=near/(far-near), m[14]=near*far/(far-near)
161
+ * - infinite (far=Infinity): m[10]=0, m[14]=near (lim f→∞ limit values)
162
+ *
163
+ * Numeric fixture (AC-05 error ≤ 1e-5): see __tests__/_fixtures.ts.
164
+ *
165
+ * @degrade Same as perspective.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * mat4.perspectiveReverseZ(out, Math.PI / 4, aspect, 0.1, 100);
170
+ * mat4.perspectiveReverseZ(out, Math.PI / 4, aspect, 0.1, Infinity); // infinite far
171
+ * // GPU companion: pipeline.depthCompare = 'greater'; passDesc.depthClearValue = 0.0;
172
+ * ```
173
+ */
174
+ export declare function perspectiveReverseZ(out: Mat4, fovYRadians: number, aspect: number, near: number, far: number): Mat4;
175
+ /**
176
+ * out = orthographic projection (**WebGPU [0, 1] NDC** short name, D-3). Returns out.
177
+ *
178
+ * @degrade near >= far or left >= right or bottom >= top → numerically undefined but does not throw.
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * mat4.orthographic(out, -10, 10, -10, 10, 0.1, 100);
183
+ * // Guard: if (!(left < right && bottom < top && near < far)) handleInvalid();
184
+ * ```
185
+ */
186
+ export declare function orthographic(out: Mat4, left: number, right: number, bottom: number, top: number, near: number, far: number): Mat4;
187
+ /** out = orthographic projection (**WebGL/OpenGL [-1, 1] NDC**, *NO*). Returns out. */
188
+ export declare function orthographicNO(out: Mat4, left: number, right: number, bottom: number, top: number, near: number, far: number): Mat4;
189
+ /**
190
+ * out = reversed-Z orthographic projection (**WebGPU [0, 1] NDC, near→1 far→0**;
191
+ * D-P3 self-extension).
192
+ *
193
+ * Pairs with perspectiveReverseZ to form a symmetric three-tier surface; in orthographic
194
+ * projection the reversed-Z precision gain is small (ortho is linear in z), but it is kept to
195
+ * avoid LLM single-pass-scan cognitive load (charter proposition 1).
196
+ * Note: this function is an @forgeax/engine-math self-extension; wgpu-matrix / gl-matrix have no matching
197
+ * name (see plan-strategy D-P3 + README quick-ref table footnote).
198
+ */
199
+ export declare function orthographicReverseZ(out: Mat4, left: number, right: number, bottom: number, top: number, near: number, far: number): Mat4;
200
+ /**
201
+ * out = M * (v.x, v.y, v.z, 1) (with perspective divide by w'). Returns out.
202
+ *
203
+ * For affine m this is equivalent to transformPoint (treats v as a "position" that participates
204
+ * in the transform, including translation).
205
+ * Aliasing-safe: reads v.xyz into locals before writing out.
206
+ *
207
+ * @degrade w' = 0 (perspective divide by zero) → out = (0, 0, 0) (D-4 silent convention; avoids
208
+ * NaN/Infinity propagation; stricter than the implicit 1/0 = Infinity behavior of
209
+ * Three.js / gl-matrix).
210
+ *
211
+ * @example
212
+ * ```ts
213
+ * mat4.transformVec3(out, projViewModel, v);
214
+ * // Guard: if (out[0] === 0 && out[1] === 0 && out[2] === 0 && wasNonZero(v)) {
215
+ * // // w'=0 degenerate branch; the caller diagnoses as needed
216
+ * // }
217
+ * ```
218
+ */
219
+ export declare function transformVec3(out: Vec3, m: Mat4Like, v: Vec3Like): Vec3;
220
+ /**
221
+ * out = M * (v.x, v.y, v.z, 1) (with perspective divide by w'). Returns out.
222
+ *
223
+ * Treats v as a "position", including the translation column (shares the same function body as
224
+ * transformVec3; OQ-1 / S-1).
225
+ * Aliasing-safe; reference-equal with transformVec3: `mat4.transformPoint === mat4.transformVec3`.
226
+ *
227
+ * @degrade w' = 0 (perspective divide by zero) → out = (0, 0, 0) (D-4 silent convention;
228
+ * same as transformVec3).
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * mat4.transformPoint(out, modelMatrix, [1, 2, 3]);
233
+ * // (1,2,3) → world-space position, including translation
234
+ * ```
235
+ */
236
+ export declare const transformPoint: typeof transformVec3;
237
+ /**
238
+ * out = normalize(M_3x3 * v) (uses m's upper-left 3×3, no translation column). Returns out.
239
+ *
240
+ * Treats v as a "direction" and does **not** apply translation; the result is unit-normalized via
241
+ * `vec3.normalize` (OQ-2 / S-2).
242
+ * Aliasing-safe: reads v.xyz into locals before writing out.
243
+ *
244
+ * @degrade |out| = 0 (singular m + arbitrary v / m_3x3 maps v to the zero vector) → vec3.normalize
245
+ * silently falls back to (0, 0, 0) (library-wide D-4 convention).
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * const worldNormal = vec3.create();
250
+ * mat4.transformDirection(worldNormal, modelMatrix, localNormal);
251
+ * // Normal-vector transform: ignores translation; a unit-length input + orthogonal matrix
252
+ * // guarantees a unit-length output.
253
+ * ```
254
+ */
255
+ export declare function transformDirection(out: Vec3, m: Mat4Like, v: Vec3Like): Vec3;
256
+ /**
257
+ * World-space translation = col 3 (m[12], m[13], m[14]). Read verbatim, not
258
+ * normalized (translation has magnitude).
259
+ */
260
+ export declare function getTranslation(out: Vec3, m: Mat4Like): Vec3;
261
+ /**
262
+ * World-space forward = `-normalize(col2)` (RL-4: -Z look convention; matches
263
+ * `quat.transformVec3(q, [0, 0, -1])`). Degenerate zero column → (0,0,0).
264
+ */
265
+ export declare function getForward(out: Vec3, m: Mat4Like): Vec3;
266
+ /** World-space up = `normalize(col1)`. Degenerate zero column → (0,0,0). */
267
+ export declare function getUp(out: Vec3, m: Mat4Like): Vec3;
268
+ /** World-space right = `normalize(col0)`. Degenerate zero column → (0,0,0). */
269
+ export declare function getRight(out: Vec3, m: Mat4Like): Vec3;
270
+ /**
271
+ * Unproject an NDC point to world space.
272
+ *
273
+ * `ndcPoint` is in NDC space: x,y ∈ [-1,1], z ∈ [0,1] (WebGPU convention).
274
+ * `invVP` is the inverse of the view-projection matrix.
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * const worldPoint = vec3.create();
279
+ * mat4.unproject(worldPoint, [0, 0, 0], invVP); // near-plane centre → world
280
+ * mat4.unproject(worldPoint, [0, 0, 1], invVP); // far-plane centre → world
281
+ * ```
282
+ */
283
+ export declare function unproject(out: Vec3, ndcPoint: Vec3Like, invVP: Mat4Like): Vec3;
284
+ /**
285
+ * Project a world-space point to NDC space through a view-projection matrix.
286
+ *
287
+ * `worldPos` is a position (treated with translation column, not a direction).
288
+ * `viewProj` is `proj × view` (eye→clip composed with world→eye).
289
+ * Output NDC is WebGPU convention: x,y ∈ [-1,1], z ∈ [0,1] (near=0 / far=1).
290
+ *
291
+ * To map NDC to viewport pixels (DOM y-down):
292
+ * px = (ndc.x * 0.5 + 0.5) * vpWidth
293
+ * py = (1 - (ndc.y * 0.5 + 0.5)) * vpHeight
294
+ * `ndc.z < 0` or `ndc.z > 1` means the point is outside the depth range
295
+ * (behind near or beyond far); callers typically skip drawing the HUD anchor.
296
+ *
297
+ * @degrade w' = 0 (point lies on the camera plane) → out = (0, 0, 0)
298
+ * (D-4 silent convention; inherited from transformVec3).
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * const ndc = vec3.create();
303
+ * mat4.projectPoint(ndc, worldPos, viewProj);
304
+ * if (ndc[2] >= 0 && ndc[2] <= 1) {
305
+ * const px = (ndc[0] * 0.5 + 0.5) * canvas.width;
306
+ * const py = (1 - (ndc[1] * 0.5 + 0.5)) * canvas.height;
307
+ * // anchor DOM tooltip at (px, py)
308
+ * }
309
+ * ```
310
+ */
311
+ export declare function projectPoint(out: Vec3, worldPos: Vec3Like, viewProj: Mat4Like): Vec3;
312
+ /**
313
+ * Compute a combined view-projection matrix from camera parameters.
314
+ *
315
+ * This is a convenience composition of `mat4.perspective * mat4.lookAt`, not a primitive.
316
+ * All parameters are plain numbers / Vec3Like — no runtime POD types (math zero-dep).
317
+ *
318
+ * @param out Mat4 to write the result into.
319
+ * @param eye Camera position in world space.
320
+ * @param target Point the camera looks at.
321
+ * @param up Approximate up direction.
322
+ * @param fovYRadians Vertical field of view in radians.
323
+ * @param aspect Aspect ratio (width / height).
324
+ * @param near Near clip distance (positive).
325
+ * @param far Far clip distance (positive, or Infinity for infinite-far).
326
+ * @returns `out` (same Mat4 instance).
327
+ */
328
+ export declare function computeViewProj(out: Mat4, eye: Vec3Like, target: Vec3Like, up: Vec3Like, fovYRadians: number, aspect: number, near: number, far: number): Mat4;
329
+ //# sourceMappingURL=mat4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mat4.d.ts","sourceRoot":"","sources":["../src/mat4.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 1D Perlin noise. Returns a value in [-1, 1] that varies smoothly with the input `x` —
3
+ * small changes in `x` produce small changes in output (no wild jumps). Three separate calls
4
+ * with different `x` offsets (e.g. `perlin1d(t)`, `perlin1d(t + 100)`, `perlin1d(t + 200)`)
5
+ * produce three independent but individually smooth noise channels.
6
+ *
7
+ * This is the canonical Perlin noise algorithm with the 256-entry permutation table from
8
+ * Bevy's `2d_screen_shake` example. Use for camera shake, procedural terrain, organic
9
+ * motion, and any effect that needs smooth pseudo-random variation.
10
+ */
11
+ export declare function perlin1d(x: number): number;
12
+ //# sourceMappingURL=noise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../src/noise.ts"],"names":[],"mappings":"AAgDA;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAmB1C"}