math 0.0.0 → 0.1.0

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 (201) hide show
  1. package/API.md +1605 -0
  2. package/LICENSE +21 -0
  3. package/README.md +197 -0
  4. package/dist/color/color.js +136 -0
  5. package/dist/color/color.js.map +1 -0
  6. package/dist/color/colorspace.js +43 -0
  7. package/dist/color/colorspace.js.map +1 -0
  8. package/dist/color/hsl.js +123 -0
  9. package/dist/color/hsl.js.map +1 -0
  10. package/dist/color/index.js +7 -0
  11. package/dist/color/index.js.map +1 -0
  12. package/dist/color/parse.js +276 -0
  13. package/dist/color/parse.js.map +1 -0
  14. package/dist/core/angle.js +43 -0
  15. package/dist/core/angle.js.map +1 -0
  16. package/dist/core/euler.js +212 -0
  17. package/dist/core/euler.js.map +1 -0
  18. package/dist/core/mat2.js +385 -0
  19. package/dist/core/mat2.js.map +1 -0
  20. package/dist/core/mat2d.js +422 -0
  21. package/dist/core/mat2d.js.map +1 -0
  22. package/dist/core/mat3.js +749 -0
  23. package/dist/core/mat3.js.map +1 -0
  24. package/dist/core/mat4.js +2197 -0
  25. package/dist/core/mat4.js.map +1 -0
  26. package/dist/core/polar.js +200 -0
  27. package/dist/core/polar.js.map +1 -0
  28. package/dist/core/quat.js +730 -0
  29. package/dist/core/quat.js.map +1 -0
  30. package/dist/core/quat2.js +883 -0
  31. package/dist/core/quat2.js.map +1 -0
  32. package/dist/core/scalar.js +112 -0
  33. package/dist/core/scalar.js.map +1 -0
  34. package/dist/core/spherical.js +248 -0
  35. package/dist/core/spherical.js.map +1 -0
  36. package/dist/core/vec2.js +597 -0
  37. package/dist/core/vec2.js.map +1 -0
  38. package/dist/core/vec3.js +916 -0
  39. package/dist/core/vec3.js.map +1 -0
  40. package/dist/core/vec4.js +573 -0
  41. package/dist/core/vec4.js.map +1 -0
  42. package/dist/geometry/circumcircle.js +39 -0
  43. package/dist/geometry/circumcircle.js.map +1 -0
  44. package/dist/geometry/index.js +6 -0
  45. package/dist/geometry/index.js.map +1 -0
  46. package/dist/geometry/polygon2-decompose.js +411 -0
  47. package/dist/geometry/polygon2-decompose.js.map +1 -0
  48. package/dist/geometry/polygon2-triangulate.js +222 -0
  49. package/dist/geometry/polygon2-triangulate.js.map +1 -0
  50. package/dist/geometry/quickhull2.js +123 -0
  51. package/dist/geometry/quickhull2.js.map +1 -0
  52. package/dist/geometry/quickhull3.js +605 -0
  53. package/dist/geometry/quickhull3.js.map +1 -0
  54. package/dist/ik/fabrik2.js +675 -0
  55. package/dist/ik/fabrik2.js.map +1 -0
  56. package/dist/ik/fabrik3.js +912 -0
  57. package/dist/ik/fabrik3.js.map +1 -0
  58. package/dist/ik/index.js +5 -0
  59. package/dist/ik/index.js.map +1 -0
  60. package/dist/index.js +27 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/noise/fractal.js +185 -0
  63. package/dist/noise/fractal.js.map +1 -0
  64. package/dist/noise/index.js +16 -0
  65. package/dist/noise/index.js.map +1 -0
  66. package/dist/noise/perlin2d.js +50 -0
  67. package/dist/noise/perlin2d.js.map +1 -0
  68. package/dist/noise/perlin3d.js +72 -0
  69. package/dist/noise/perlin3d.js.map +1 -0
  70. package/dist/noise/permutation.js +120 -0
  71. package/dist/noise/permutation.js.map +1 -0
  72. package/dist/noise/simplex2d.js +84 -0
  73. package/dist/noise/simplex2d.js.map +1 -0
  74. package/dist/noise/simplex3d.js +147 -0
  75. package/dist/noise/simplex3d.js.map +1 -0
  76. package/dist/noise/simplex4d.js +149 -0
  77. package/dist/noise/simplex4d.js.map +1 -0
  78. package/dist/noise/worley2d.js +50 -0
  79. package/dist/noise/worley2d.js.map +1 -0
  80. package/dist/noise/worley3d.js +61 -0
  81. package/dist/noise/worley3d.js.map +1 -0
  82. package/dist/random/index.js +9 -0
  83. package/dist/random/index.js.map +1 -0
  84. package/dist/random/isaac32.js +164 -0
  85. package/dist/random/isaac32.js.map +1 -0
  86. package/dist/random/isaac64.js +215 -0
  87. package/dist/random/isaac64.js.map +1 -0
  88. package/dist/random/mulberry32.js +48 -0
  89. package/dist/random/mulberry32.js.map +1 -0
  90. package/dist/random/random.js +120 -0
  91. package/dist/random/random.js.map +1 -0
  92. package/dist/shapes/box2.js +300 -0
  93. package/dist/shapes/box2.js.map +1 -0
  94. package/dist/shapes/box3.js +550 -0
  95. package/dist/shapes/box3.js.map +1 -0
  96. package/dist/shapes/circle.js +6 -0
  97. package/dist/shapes/circle.js.map +1 -0
  98. package/dist/shapes/frustum.js +662 -0
  99. package/dist/shapes/frustum.js.map +1 -0
  100. package/dist/shapes/index.js +25 -0
  101. package/dist/shapes/index.js.map +1 -0
  102. package/dist/shapes/obb3.js +557 -0
  103. package/dist/shapes/obb3.js.map +1 -0
  104. package/dist/shapes/plane3.js +267 -0
  105. package/dist/shapes/plane3.js.map +1 -0
  106. package/dist/shapes/polygon2.js +451 -0
  107. package/dist/shapes/polygon2.js.map +1 -0
  108. package/dist/shapes/raycast3.js +164 -0
  109. package/dist/shapes/raycast3.js.map +1 -0
  110. package/dist/shapes/segment2.js +82 -0
  111. package/dist/shapes/segment2.js.map +1 -0
  112. package/dist/shapes/sphere.js +23 -0
  113. package/dist/shapes/sphere.js.map +1 -0
  114. package/dist/shapes/triangle2.js +79 -0
  115. package/dist/shapes/triangle2.js.map +1 -0
  116. package/dist/shapes/triangle3.js +60 -0
  117. package/dist/shapes/triangle3.js.map +1 -0
  118. package/dist/src/color/color.d.ts +50 -0
  119. package/dist/src/color/colorspace.d.ts +15 -0
  120. package/dist/src/color/hsl.d.ts +28 -0
  121. package/dist/src/color/index.d.ts +5 -0
  122. package/dist/src/color/parse.d.ts +15 -0
  123. package/dist/src/core/angle.d.ts +29 -0
  124. package/dist/src/core/arrays.d.ts +4 -0
  125. package/dist/src/core/euler.d.ts +78 -0
  126. package/dist/src/core/index.d.ts +27 -0
  127. package/dist/src/core/mat2.d.ts +217 -0
  128. package/dist/src/core/mat2d.d.ts +218 -0
  129. package/dist/src/core/mat3.d.ts +295 -0
  130. package/dist/src/core/mat4.d.ts +667 -0
  131. package/dist/src/core/polar.d.ts +151 -0
  132. package/dist/src/core/quat.d.ts +370 -0
  133. package/dist/src/core/quat2.d.ts +344 -0
  134. package/dist/src/core/scalar.d.ts +75 -0
  135. package/dist/src/core/spherical.d.ts +165 -0
  136. package/dist/src/core/vec2.d.ts +403 -0
  137. package/dist/src/core/vec3.d.ts +493 -0
  138. package/dist/src/core/vec4.d.ts +336 -0
  139. package/dist/src/geometry/circumcircle.d.ts +9 -0
  140. package/dist/src/geometry/index.d.ts +5 -0
  141. package/dist/src/geometry/polygon2-decompose.d.ts +25 -0
  142. package/dist/src/geometry/polygon2-triangulate.d.ts +15 -0
  143. package/dist/src/geometry/quickhull2.d.ts +10 -0
  144. package/dist/src/geometry/quickhull3.d.ts +27 -0
  145. package/dist/src/ik/fabrik2.d.ts +314 -0
  146. package/dist/src/ik/fabrik3.d.ts +371 -0
  147. package/dist/src/ik/index.d.ts +2 -0
  148. package/dist/src/index.d.ts +1 -0
  149. package/dist/src/noise/fractal.d.ts +95 -0
  150. package/dist/src/noise/index.d.ts +9 -0
  151. package/dist/src/noise/perlin2d.d.ts +19 -0
  152. package/dist/src/noise/perlin3d.d.ts +20 -0
  153. package/dist/src/noise/permutation.d.ts +22 -0
  154. package/dist/src/noise/simplex2d.d.ts +19 -0
  155. package/dist/src/noise/simplex3d.d.ts +20 -0
  156. package/dist/src/noise/simplex4d.d.ts +24 -0
  157. package/dist/src/noise/worley2d.d.ts +22 -0
  158. package/dist/src/noise/worley3d.d.ts +23 -0
  159. package/dist/src/random/index.d.ts +8 -0
  160. package/dist/src/random/isaac32.d.ts +62 -0
  161. package/dist/src/random/isaac64.d.ts +75 -0
  162. package/dist/src/random/mulberry32.d.ts +43 -0
  163. package/dist/src/random/random.d.ts +67 -0
  164. package/dist/src/shapes/box2.d.ts +174 -0
  165. package/dist/src/shapes/box3.d.ts +213 -0
  166. package/dist/src/shapes/circle.d.ts +7 -0
  167. package/dist/src/shapes/frustum.d.ts +147 -0
  168. package/dist/src/shapes/index.d.ts +20 -0
  169. package/dist/src/shapes/obb3.d.ts +105 -0
  170. package/dist/src/shapes/plane3.d.ts +130 -0
  171. package/dist/src/shapes/polygon2.d.ts +155 -0
  172. package/dist/src/shapes/raycast3.d.ts +42 -0
  173. package/dist/src/shapes/segment2.d.ts +34 -0
  174. package/dist/src/shapes/sphere.d.ts +19 -0
  175. package/dist/src/shapes/triangle2.d.ts +53 -0
  176. package/dist/src/shapes/triangle3.d.ts +29 -0
  177. package/dist/src/time/easing.d.ts +21 -0
  178. package/dist/src/time/index.d.ts +6 -0
  179. package/dist/src/time/spring-core.d.ts +15 -0
  180. package/dist/src/time/spring.d.ts +36 -0
  181. package/dist/src/time/spring2.d.ts +11 -0
  182. package/dist/src/time/spring3.d.ts +11 -0
  183. package/dist/src/time/spring4.d.ts +11 -0
  184. package/dist/time/easing.js +24 -0
  185. package/dist/time/easing.js.map +1 -0
  186. package/dist/time/index.js +11 -0
  187. package/dist/time/index.js.map +1 -0
  188. package/dist/time/spring-core.js +48 -0
  189. package/dist/time/spring-core.js.map +1 -0
  190. package/dist/time/spring.js +62 -0
  191. package/dist/time/spring.js.map +1 -0
  192. package/dist/time/spring2.js +31 -0
  193. package/dist/time/spring2.js.map +1 -0
  194. package/dist/time/spring3.js +32 -0
  195. package/dist/time/spring3.js.map +1 -0
  196. package/dist/time/spring4.js +32 -0
  197. package/dist/time/spring4.js.map +1 -0
  198. package/package.json +90 -12
  199. package/skills/math/SKILL.md +140 -0
  200. package/math.coffee +0 -36
  201. package/math.js +0 -67
@@ -0,0 +1,662 @@
1
+ import { copy as copy$1, intersect } from './plane3.js';
2
+
3
+ /**
4
+ * Creates a new frustum of zeroed planes.
5
+ * @returns A new frustum
6
+ */
7
+ function create() {
8
+ return [
9
+ { normal: [0, 1, 0], constant: 0 },
10
+ { normal: [0, 1, 0], constant: 0 },
11
+ { normal: [0, 1, 0], constant: 0 },
12
+ { normal: [0, 1, 0], constant: 0 },
13
+ { normal: [0, 1, 0], constant: 0 },
14
+ { normal: [0, 1, 0], constant: 0 },
15
+ ];
16
+ }
17
+ /**
18
+ * Clones a frustum.
19
+ * @param f - The frustum to clone
20
+ * @returns A new frustum
21
+ */
22
+ function clone(f) {
23
+ const p0 = f[0];
24
+ const p1 = f[1];
25
+ const p2 = f[2];
26
+ const p3 = f[3];
27
+ const p4 = f[4];
28
+ const p5 = f[5];
29
+ return [
30
+ { normal: [p0.normal[0], p0.normal[1], p0.normal[2]], constant: p0.constant },
31
+ { normal: [p1.normal[0], p1.normal[1], p1.normal[2]], constant: p1.constant },
32
+ { normal: [p2.normal[0], p2.normal[1], p2.normal[2]], constant: p2.constant },
33
+ { normal: [p3.normal[0], p3.normal[1], p3.normal[2]], constant: p3.constant },
34
+ { normal: [p4.normal[0], p4.normal[1], p4.normal[2]], constant: p4.constant },
35
+ { normal: [p5.normal[0], p5.normal[1], p5.normal[2]], constant: p5.constant },
36
+ ];
37
+ }
38
+ /**
39
+ * Copies one frustum to another.
40
+ * @param out - The output frustum
41
+ * @param f - The source frustum
42
+ * @returns The output frustum
43
+ */
44
+ function copy(out, f) {
45
+ copy$1(out[0], f[0]);
46
+ copy$1(out[1], f[1]);
47
+ copy$1(out[2], f[2]);
48
+ copy$1(out[3], f[3]);
49
+ copy$1(out[4], f[4]);
50
+ copy$1(out[5], f[5]);
51
+ return out;
52
+ }
53
+ /**
54
+ * Extracts the six planes of a view frustum from a projection and view matrix, using the
55
+ * OpenGL / WebGL clip-space depth convention (NDC z in [-1, 1]).
56
+ *
57
+ * Pair this with `mat4.perspectiveNO`, `mat4.frustumNO` or `mat4.orthoNO`.
58
+ *
59
+ * @param out - The output frustum
60
+ * @param proj - The projection matrix
61
+ * @param view - The view matrix
62
+ * @returns The output frustum
63
+ */
64
+ function setFromViewProjectionMatrixNO(out, proj, view) {
65
+ const p0 = proj[0];
66
+ const p1 = proj[1];
67
+ const p2 = proj[2];
68
+ const p3 = proj[3];
69
+ const p4 = proj[4];
70
+ const p5 = proj[5];
71
+ const p6 = proj[6];
72
+ const p7 = proj[7];
73
+ const p8 = proj[8];
74
+ const p9 = proj[9];
75
+ const p10 = proj[10];
76
+ const p11 = proj[11];
77
+ const p12 = proj[12];
78
+ const p13 = proj[13];
79
+ const p14 = proj[14];
80
+ const p15 = proj[15];
81
+ const v0 = view[0];
82
+ const v1 = view[1];
83
+ const v2 = view[2];
84
+ const v3 = view[3];
85
+ const v4 = view[4];
86
+ const v5 = view[5];
87
+ const v6 = view[6];
88
+ const v7 = view[7];
89
+ const v8 = view[8];
90
+ const v9 = view[9];
91
+ const v10 = view[10];
92
+ const v11 = view[11];
93
+ const v12 = view[12];
94
+ const v13 = view[13];
95
+ const v14 = view[14];
96
+ const v15 = view[15];
97
+ // rows of (proj * view), computed directly
98
+ const r00 = p0 * v0 + p4 * v1 + p8 * v2 + p12 * v3;
99
+ const r01 = p0 * v4 + p4 * v5 + p8 * v6 + p12 * v7;
100
+ const r02 = p0 * v8 + p4 * v9 + p8 * v10 + p12 * v11;
101
+ const r03 = p0 * v12 + p4 * v13 + p8 * v14 + p12 * v15;
102
+ const r10 = p1 * v0 + p5 * v1 + p9 * v2 + p13 * v3;
103
+ const r11 = p1 * v4 + p5 * v5 + p9 * v6 + p13 * v7;
104
+ const r12 = p1 * v8 + p5 * v9 + p9 * v10 + p13 * v11;
105
+ const r13 = p1 * v12 + p5 * v13 + p9 * v14 + p13 * v15;
106
+ const r20 = p2 * v0 + p6 * v1 + p10 * v2 + p14 * v3;
107
+ const r21 = p2 * v4 + p6 * v5 + p10 * v6 + p14 * v7;
108
+ const r22 = p2 * v8 + p6 * v9 + p10 * v10 + p14 * v11;
109
+ const r23 = p2 * v12 + p6 * v13 + p10 * v14 + p14 * v15;
110
+ const r30 = p3 * v0 + p7 * v1 + p11 * v2 + p15 * v3;
111
+ const r31 = p3 * v4 + p7 * v5 + p11 * v6 + p15 * v7;
112
+ const r32 = p3 * v8 + p7 * v9 + p11 * v10 + p15 * v11;
113
+ const r33 = p3 * v12 + p7 * v13 + p11 * v14 + p15 * v15;
114
+ // left = row3 + row0
115
+ let nx = r30 + r00;
116
+ let ny = r31 + r01;
117
+ let nz = r32 + r02;
118
+ let c = r33 + r03;
119
+ let inv = nx * nx + ny * ny + nz * nz;
120
+ if (inv > 0)
121
+ inv = 1 / Math.sqrt(inv);
122
+ out[0].normal[0] = nx * inv;
123
+ out[0].normal[1] = ny * inv;
124
+ out[0].normal[2] = nz * inv;
125
+ out[0].constant = c * inv;
126
+ // right = row3 - row0
127
+ nx = r30 - r00;
128
+ ny = r31 - r01;
129
+ nz = r32 - r02;
130
+ c = r33 - r03;
131
+ inv = nx * nx + ny * ny + nz * nz;
132
+ if (inv > 0)
133
+ inv = 1 / Math.sqrt(inv);
134
+ out[1].normal[0] = nx * inv;
135
+ out[1].normal[1] = ny * inv;
136
+ out[1].normal[2] = nz * inv;
137
+ out[1].constant = c * inv;
138
+ // bottom = row3 + row1
139
+ nx = r30 + r10;
140
+ ny = r31 + r11;
141
+ nz = r32 + r12;
142
+ c = r33 + r13;
143
+ inv = nx * nx + ny * ny + nz * nz;
144
+ if (inv > 0)
145
+ inv = 1 / Math.sqrt(inv);
146
+ out[2].normal[0] = nx * inv;
147
+ out[2].normal[1] = ny * inv;
148
+ out[2].normal[2] = nz * inv;
149
+ out[2].constant = c * inv;
150
+ // top = row3 - row1
151
+ nx = r30 - r10;
152
+ ny = r31 - r11;
153
+ nz = r32 - r12;
154
+ c = r33 - r13;
155
+ inv = nx * nx + ny * ny + nz * nz;
156
+ if (inv > 0)
157
+ inv = 1 / Math.sqrt(inv);
158
+ out[3].normal[0] = nx * inv;
159
+ out[3].normal[1] = ny * inv;
160
+ out[3].normal[2] = nz * inv;
161
+ out[3].constant = c * inv;
162
+ // near (NO) = row3 + row2
163
+ nx = r30 + r20;
164
+ ny = r31 + r21;
165
+ nz = r32 + r22;
166
+ c = r33 + r23;
167
+ inv = nx * nx + ny * ny + nz * nz;
168
+ if (inv > 0)
169
+ inv = 1 / Math.sqrt(inv);
170
+ out[4].normal[0] = nx * inv;
171
+ out[4].normal[1] = ny * inv;
172
+ out[4].normal[2] = nz * inv;
173
+ out[4].constant = c * inv;
174
+ // far = row3 - row2
175
+ nx = r30 - r20;
176
+ ny = r31 - r21;
177
+ nz = r32 - r22;
178
+ c = r33 - r23;
179
+ inv = nx * nx + ny * ny + nz * nz;
180
+ if (inv > 0)
181
+ inv = 1 / Math.sqrt(inv);
182
+ out[5].normal[0] = nx * inv;
183
+ out[5].normal[1] = ny * inv;
184
+ out[5].normal[2] = nz * inv;
185
+ out[5].constant = c * inv;
186
+ return out;
187
+ }
188
+ /**
189
+ * Extracts the six planes of a view frustum from a projection and view matrix, using the
190
+ * WebGPU / Vulkan / D3D / Metal clip-space depth convention (NDC z in [0, 1]).
191
+ *
192
+ * Pair this with `mat4.perspectiveZO`, `mat4.frustumZO` or `mat4.orthoZO`.
193
+ *
194
+ * @param out - The output frustum
195
+ * @param proj - The projection matrix
196
+ * @param view - The view matrix
197
+ * @returns The output frustum
198
+ */
199
+ function setFromViewProjectionMatrixZO(out, proj, view) {
200
+ const p0 = proj[0];
201
+ const p1 = proj[1];
202
+ const p2 = proj[2];
203
+ const p3 = proj[3];
204
+ const p4 = proj[4];
205
+ const p5 = proj[5];
206
+ const p6 = proj[6];
207
+ const p7 = proj[7];
208
+ const p8 = proj[8];
209
+ const p9 = proj[9];
210
+ const p10 = proj[10];
211
+ const p11 = proj[11];
212
+ const p12 = proj[12];
213
+ const p13 = proj[13];
214
+ const p14 = proj[14];
215
+ const p15 = proj[15];
216
+ const v0 = view[0];
217
+ const v1 = view[1];
218
+ const v2 = view[2];
219
+ const v3 = view[3];
220
+ const v4 = view[4];
221
+ const v5 = view[5];
222
+ const v6 = view[6];
223
+ const v7 = view[7];
224
+ const v8 = view[8];
225
+ const v9 = view[9];
226
+ const v10 = view[10];
227
+ const v11 = view[11];
228
+ const v12 = view[12];
229
+ const v13 = view[13];
230
+ const v14 = view[14];
231
+ const v15 = view[15];
232
+ // rows of (proj * view), computed directly
233
+ const r00 = p0 * v0 + p4 * v1 + p8 * v2 + p12 * v3;
234
+ const r01 = p0 * v4 + p4 * v5 + p8 * v6 + p12 * v7;
235
+ const r02 = p0 * v8 + p4 * v9 + p8 * v10 + p12 * v11;
236
+ const r03 = p0 * v12 + p4 * v13 + p8 * v14 + p12 * v15;
237
+ const r10 = p1 * v0 + p5 * v1 + p9 * v2 + p13 * v3;
238
+ const r11 = p1 * v4 + p5 * v5 + p9 * v6 + p13 * v7;
239
+ const r12 = p1 * v8 + p5 * v9 + p9 * v10 + p13 * v11;
240
+ const r13 = p1 * v12 + p5 * v13 + p9 * v14 + p13 * v15;
241
+ const r20 = p2 * v0 + p6 * v1 + p10 * v2 + p14 * v3;
242
+ const r21 = p2 * v4 + p6 * v5 + p10 * v6 + p14 * v7;
243
+ const r22 = p2 * v8 + p6 * v9 + p10 * v10 + p14 * v11;
244
+ const r23 = p2 * v12 + p6 * v13 + p10 * v14 + p14 * v15;
245
+ const r30 = p3 * v0 + p7 * v1 + p11 * v2 + p15 * v3;
246
+ const r31 = p3 * v4 + p7 * v5 + p11 * v6 + p15 * v7;
247
+ const r32 = p3 * v8 + p7 * v9 + p11 * v10 + p15 * v11;
248
+ const r33 = p3 * v12 + p7 * v13 + p11 * v14 + p15 * v15;
249
+ // left = row3 + row0
250
+ let nx = r30 + r00;
251
+ let ny = r31 + r01;
252
+ let nz = r32 + r02;
253
+ let c = r33 + r03;
254
+ let inv = nx * nx + ny * ny + nz * nz;
255
+ if (inv > 0)
256
+ inv = 1 / Math.sqrt(inv);
257
+ out[0].normal[0] = nx * inv;
258
+ out[0].normal[1] = ny * inv;
259
+ out[0].normal[2] = nz * inv;
260
+ out[0].constant = c * inv;
261
+ // right = row3 - row0
262
+ nx = r30 - r00;
263
+ ny = r31 - r01;
264
+ nz = r32 - r02;
265
+ c = r33 - r03;
266
+ inv = nx * nx + ny * ny + nz * nz;
267
+ if (inv > 0)
268
+ inv = 1 / Math.sqrt(inv);
269
+ out[1].normal[0] = nx * inv;
270
+ out[1].normal[1] = ny * inv;
271
+ out[1].normal[2] = nz * inv;
272
+ out[1].constant = c * inv;
273
+ // bottom = row3 + row1
274
+ nx = r30 + r10;
275
+ ny = r31 + r11;
276
+ nz = r32 + r12;
277
+ c = r33 + r13;
278
+ inv = nx * nx + ny * ny + nz * nz;
279
+ if (inv > 0)
280
+ inv = 1 / Math.sqrt(inv);
281
+ out[2].normal[0] = nx * inv;
282
+ out[2].normal[1] = ny * inv;
283
+ out[2].normal[2] = nz * inv;
284
+ out[2].constant = c * inv;
285
+ // top = row3 - row1
286
+ nx = r30 - r10;
287
+ ny = r31 - r11;
288
+ nz = r32 - r12;
289
+ c = r33 - r13;
290
+ inv = nx * nx + ny * ny + nz * nz;
291
+ if (inv > 0)
292
+ inv = 1 / Math.sqrt(inv);
293
+ out[3].normal[0] = nx * inv;
294
+ out[3].normal[1] = ny * inv;
295
+ out[3].normal[2] = nz * inv;
296
+ out[3].constant = c * inv;
297
+ // near (ZO) = row2
298
+ nx = r20;
299
+ ny = r21;
300
+ nz = r22;
301
+ c = r23;
302
+ inv = nx * nx + ny * ny + nz * nz;
303
+ if (inv > 0)
304
+ inv = 1 / Math.sqrt(inv);
305
+ out[4].normal[0] = nx * inv;
306
+ out[4].normal[1] = ny * inv;
307
+ out[4].normal[2] = nz * inv;
308
+ out[4].constant = c * inv;
309
+ // far = row3 - row2
310
+ nx = r30 - r20;
311
+ ny = r31 - r21;
312
+ nz = r32 - r22;
313
+ c = r33 - r23;
314
+ inv = nx * nx + ny * ny + nz * nz;
315
+ if (inv > 0)
316
+ inv = 1 / Math.sqrt(inv);
317
+ out[5].normal[0] = nx * inv;
318
+ out[5].normal[1] = ny * inv;
319
+ out[5].normal[2] = nz * inv;
320
+ out[5].constant = c * inv;
321
+ return out;
322
+ }
323
+ /**
324
+ * Extracts only the four lateral planes (left, right, bottom, top) of a view frustum from a
325
+ * projection and view matrix, skipping near and far. This is convention-independent — the
326
+ * NO/ZO split only affects the near plane — so it pairs with any projection matrix.
327
+ *
328
+ * Intended for streaming pipelines that already cull distant content and only need to reject
329
+ * objects outside the camera's sides. Test against the result with `frustum.sidesIntersectsSphere`,
330
+ * `frustum.sidesIntersectsBox3`, `frustum.sidesContainsPoint` or `frustum.sidesIntersectsRay`.
331
+ *
332
+ * @param out - The output frustum; only slots 0-3 are written
333
+ * @param proj - The projection matrix
334
+ * @param view - The view matrix
335
+ * @returns The output frustum
336
+ */
337
+ function setFromViewProjectionMatrixSides(out, proj, view) {
338
+ // row2 (near/far) coefficients are not needed, so skip p2, p6, p10, p14
339
+ const p0 = proj[0];
340
+ const p1 = proj[1];
341
+ const p3 = proj[3];
342
+ const p4 = proj[4];
343
+ const p5 = proj[5];
344
+ const p7 = proj[7];
345
+ const p8 = proj[8];
346
+ const p9 = proj[9];
347
+ const p11 = proj[11];
348
+ const p12 = proj[12];
349
+ const p13 = proj[13];
350
+ const p15 = proj[15];
351
+ const v0 = view[0];
352
+ const v1 = view[1];
353
+ const v2 = view[2];
354
+ const v3 = view[3];
355
+ const v4 = view[4];
356
+ const v5 = view[5];
357
+ const v6 = view[6];
358
+ const v7 = view[7];
359
+ const v8 = view[8];
360
+ const v9 = view[9];
361
+ const v10 = view[10];
362
+ const v11 = view[11];
363
+ const v12 = view[12];
364
+ const v13 = view[13];
365
+ const v14 = view[14];
366
+ const v15 = view[15];
367
+ // rows of (proj * view), computed directly
368
+ const r00 = p0 * v0 + p4 * v1 + p8 * v2 + p12 * v3;
369
+ const r01 = p0 * v4 + p4 * v5 + p8 * v6 + p12 * v7;
370
+ const r02 = p0 * v8 + p4 * v9 + p8 * v10 + p12 * v11;
371
+ const r03 = p0 * v12 + p4 * v13 + p8 * v14 + p12 * v15;
372
+ const r10 = p1 * v0 + p5 * v1 + p9 * v2 + p13 * v3;
373
+ const r11 = p1 * v4 + p5 * v5 + p9 * v6 + p13 * v7;
374
+ const r12 = p1 * v8 + p5 * v9 + p9 * v10 + p13 * v11;
375
+ const r13 = p1 * v12 + p5 * v13 + p9 * v14 + p13 * v15;
376
+ const r30 = p3 * v0 + p7 * v1 + p11 * v2 + p15 * v3;
377
+ const r31 = p3 * v4 + p7 * v5 + p11 * v6 + p15 * v7;
378
+ const r32 = p3 * v8 + p7 * v9 + p11 * v10 + p15 * v11;
379
+ const r33 = p3 * v12 + p7 * v13 + p11 * v14 + p15 * v15;
380
+ // left = row3 + row0
381
+ let nx = r30 + r00;
382
+ let ny = r31 + r01;
383
+ let nz = r32 + r02;
384
+ let c = r33 + r03;
385
+ let inv = nx * nx + ny * ny + nz * nz;
386
+ if (inv > 0)
387
+ inv = 1 / Math.sqrt(inv);
388
+ out[0].normal[0] = nx * inv;
389
+ out[0].normal[1] = ny * inv;
390
+ out[0].normal[2] = nz * inv;
391
+ out[0].constant = c * inv;
392
+ // right = row3 - row0
393
+ nx = r30 - r00;
394
+ ny = r31 - r01;
395
+ nz = r32 - r02;
396
+ c = r33 - r03;
397
+ inv = nx * nx + ny * ny + nz * nz;
398
+ if (inv > 0)
399
+ inv = 1 / Math.sqrt(inv);
400
+ out[1].normal[0] = nx * inv;
401
+ out[1].normal[1] = ny * inv;
402
+ out[1].normal[2] = nz * inv;
403
+ out[1].constant = c * inv;
404
+ // bottom = row3 + row1
405
+ nx = r30 + r10;
406
+ ny = r31 + r11;
407
+ nz = r32 + r12;
408
+ c = r33 + r13;
409
+ inv = nx * nx + ny * ny + nz * nz;
410
+ if (inv > 0)
411
+ inv = 1 / Math.sqrt(inv);
412
+ out[2].normal[0] = nx * inv;
413
+ out[2].normal[1] = ny * inv;
414
+ out[2].normal[2] = nz * inv;
415
+ out[2].constant = c * inv;
416
+ // top = row3 - row1
417
+ nx = r30 - r10;
418
+ ny = r31 - r11;
419
+ nz = r32 - r12;
420
+ c = r33 - r13;
421
+ inv = nx * nx + ny * ny + nz * nz;
422
+ if (inv > 0)
423
+ inv = 1 / Math.sqrt(inv);
424
+ out[3].normal[0] = nx * inv;
425
+ out[3].normal[1] = ny * inv;
426
+ out[3].normal[2] = nz * inv;
427
+ out[3].constant = c * inv;
428
+ return out;
429
+ }
430
+ /**
431
+ * Tests if a sphere intersects the frustum.
432
+ * @param f - The frustum
433
+ * @param s - The sphere
434
+ * @returns True if the sphere intersects or is inside the frustum
435
+ */
436
+ function intersectsSphere(f, s) {
437
+ const cx = s.center[0];
438
+ const cy = s.center[1];
439
+ const cz = s.center[2];
440
+ const r = s.radius;
441
+ for (let i = 0; i < 6; i++) {
442
+ const p = f[i];
443
+ if (p.normal[0] * cx + p.normal[1] * cy + p.normal[2] * cz + p.constant < -r)
444
+ return false;
445
+ }
446
+ return true;
447
+ }
448
+ /**
449
+ * Tests if a sphere intersects the lateral planes of a sides-only frustum, skipping near and far.
450
+ * @param f - The sides-only frustum
451
+ * @param s - The sphere
452
+ * @returns True if the sphere intersects or is inside the frustum's sides
453
+ */
454
+ function sidesIntersectsSphere(f, s) {
455
+ const cx = s.center[0];
456
+ const cy = s.center[1];
457
+ const cz = s.center[2];
458
+ const r = s.radius;
459
+ for (let i = 0; i < 4; i++) {
460
+ const p = f[i];
461
+ if (p.normal[0] * cx + p.normal[1] * cy + p.normal[2] * cz + p.constant < -r)
462
+ return false;
463
+ }
464
+ return true;
465
+ }
466
+ /**
467
+ * Tests if an axis-aligned box intersects the frustum, using the p-vertex test.
468
+ * @param f - The frustum
469
+ * @param box - The box
470
+ * @returns True if the box intersects or is inside the frustum
471
+ */
472
+ function intersectsBox3(f, box) {
473
+ const minX = box[0];
474
+ const minY = box[1];
475
+ const minZ = box[2];
476
+ const maxX = box[3];
477
+ const maxY = box[4];
478
+ const maxZ = box[5];
479
+ for (let i = 0; i < 6; i++) {
480
+ const nx = f[i].normal[0];
481
+ const ny = f[i].normal[1];
482
+ const nz = f[i].normal[2];
483
+ const px = nx >= 0 ? maxX : minX;
484
+ const py = ny >= 0 ? maxY : minY;
485
+ const pz = nz >= 0 ? maxZ : minZ;
486
+ if (nx * px + ny * py + nz * pz + f[i].constant < 0)
487
+ return false;
488
+ }
489
+ return true;
490
+ }
491
+ /**
492
+ * Tests if an axis-aligned box intersects the lateral planes of a sides-only frustum, using the
493
+ * p-vertex test, skipping near and far.
494
+ * @param f - The sides-only frustum
495
+ * @param box - The box
496
+ * @returns True if the box intersects or is inside the frustum's sides
497
+ */
498
+ function sidesIntersectsBox3(f, box) {
499
+ const minX = box[0];
500
+ const minY = box[1];
501
+ const minZ = box[2];
502
+ const maxX = box[3];
503
+ const maxY = box[4];
504
+ const maxZ = box[5];
505
+ for (let i = 0; i < 4; i++) {
506
+ const nx = f[i].normal[0];
507
+ const ny = f[i].normal[1];
508
+ const nz = f[i].normal[2];
509
+ const px = nx >= 0 ? maxX : minX;
510
+ const py = ny >= 0 ? maxY : minY;
511
+ const pz = nz >= 0 ? maxZ : minZ;
512
+ if (nx * px + ny * py + nz * pz + f[i].constant < 0)
513
+ return false;
514
+ }
515
+ return true;
516
+ }
517
+ /**
518
+ * Tests if a point is inside the frustum.
519
+ * @param f - The frustum
520
+ * @param p - The point
521
+ * @returns True if the point is inside or on the boundary of the frustum
522
+ */
523
+ function containsPoint(f, p) {
524
+ const x = p[0];
525
+ const y = p[1];
526
+ const z = p[2];
527
+ for (let i = 0; i < 6; i++) {
528
+ const n = f[i].normal;
529
+ if (n[0] * x + n[1] * y + n[2] * z + f[i].constant < 0)
530
+ return false;
531
+ }
532
+ return true;
533
+ }
534
+ /**
535
+ * Tests if a point is inside the lateral planes of a sides-only frustum, skipping near and far.
536
+ * @param f - The sides-only frustum
537
+ * @param p - The point
538
+ * @returns True if the point is inside or on the boundary of the frustum's sides
539
+ */
540
+ function sidesContainsPoint(f, p) {
541
+ const x = p[0];
542
+ const y = p[1];
543
+ const z = p[2];
544
+ for (let i = 0; i < 4; i++) {
545
+ const n = f[i].normal;
546
+ if (n[0] * x + n[1] * y + n[2] * z + f[i].constant < 0)
547
+ return false;
548
+ }
549
+ return true;
550
+ }
551
+ /**
552
+ * Tests if a ray intersects the frustum, using a slab test over the planes.
553
+ * A ray that starts inside the frustum always intersects.
554
+ * @param f - The frustum
555
+ * @param origin - Ray origin
556
+ * @param direction - Ray direction (need not be normalized)
557
+ * @returns True if the ray intersects the frustum
558
+ */
559
+ function intersectsRay(f, origin, direction) {
560
+ const ox = origin[0];
561
+ const oy = origin[1];
562
+ const oz = origin[2];
563
+ const dx = direction[0];
564
+ const dy = direction[1];
565
+ const dz = direction[2];
566
+ let tmin = 0;
567
+ let tmax = Number.POSITIVE_INFINITY;
568
+ for (let i = 0; i < 6; i++) {
569
+ const nx = f[i].normal[0];
570
+ const ny = f[i].normal[1];
571
+ const nz = f[i].normal[2];
572
+ const s0 = nx * ox + ny * oy + nz * oz + f[i].constant;
573
+ const r = nx * dx + ny * dy + nz * dz;
574
+ if (Math.abs(r) < 1e-10) {
575
+ if (s0 < 0)
576
+ return false;
577
+ }
578
+ else {
579
+ const t = -s0 / r;
580
+ if (r > 0) {
581
+ if (t > tmin)
582
+ tmin = t;
583
+ }
584
+ else {
585
+ if (t < tmax)
586
+ tmax = t;
587
+ }
588
+ }
589
+ if (tmin > tmax)
590
+ return false;
591
+ }
592
+ return true;
593
+ }
594
+ /**
595
+ * Tests if a ray intersects the lateral planes of a sides-only frustum, using a slab test over the
596
+ * planes, skipping near and far. A ray that starts inside the sides always intersects.
597
+ * @param f - The sides-only frustum
598
+ * @param origin - Ray origin
599
+ * @param direction - Ray direction (need not be normalized)
600
+ * @returns True if the ray intersects the frustum's sides
601
+ */
602
+ function sidesIntersectsRay(f, origin, direction) {
603
+ const ox = origin[0];
604
+ const oy = origin[1];
605
+ const oz = origin[2];
606
+ const dx = direction[0];
607
+ const dy = direction[1];
608
+ const dz = direction[2];
609
+ let tmin = 0;
610
+ let tmax = Number.POSITIVE_INFINITY;
611
+ for (let i = 0; i < 4; i++) {
612
+ const nx = f[i].normal[0];
613
+ const ny = f[i].normal[1];
614
+ const nz = f[i].normal[2];
615
+ const s0 = nx * ox + ny * oy + nz * oz + f[i].constant;
616
+ const r = nx * dx + ny * dy + nz * dz;
617
+ if (Math.abs(r) < 1e-10) {
618
+ if (s0 < 0)
619
+ return false;
620
+ }
621
+ else {
622
+ const t = -s0 / r;
623
+ if (r > 0) {
624
+ if (t > tmin)
625
+ tmin = t;
626
+ }
627
+ else {
628
+ if (t < tmax)
629
+ tmax = t;
630
+ }
631
+ }
632
+ if (tmin > tmax)
633
+ return false;
634
+ }
635
+ return true;
636
+ }
637
+ /**
638
+ * Computes the eight corners of the frustum by intersecting three planes each.
639
+ * The frustum must be a full six-plane frustum (near and far present).
640
+ *
641
+ * Output order: near bottom-left, near top-left, near top-right, near bottom-right,
642
+ * far bottom-left, far top-left, far top-right, far bottom-right.
643
+ *
644
+ * @param out - The output corners (8 vec3s)
645
+ * @param f - The frustum
646
+ * @returns The output corners
647
+ */
648
+ function corners(out, f) {
649
+ // near = f[4], far = f[5], left = f[0], right = f[1], bottom = f[2], top = f[3]
650
+ intersect(out[0], f[4], f[0], f[2]);
651
+ intersect(out[1], f[4], f[0], f[3]);
652
+ intersect(out[2], f[4], f[1], f[3]);
653
+ intersect(out[3], f[4], f[1], f[2]);
654
+ intersect(out[4], f[5], f[0], f[2]);
655
+ intersect(out[5], f[5], f[0], f[3]);
656
+ intersect(out[6], f[5], f[1], f[3]);
657
+ intersect(out[7], f[5], f[1], f[2]);
658
+ return out;
659
+ }
660
+
661
+ export { clone, containsPoint, copy, corners, create, intersectsBox3, intersectsRay, intersectsSphere, setFromViewProjectionMatrixNO, setFromViewProjectionMatrixSides, setFromViewProjectionMatrixZO, sidesContainsPoint, sidesIntersectsBox3, sidesIntersectsRay, sidesIntersectsSphere };
662
+ //# sourceMappingURL=frustum.js.map