@carbonenginejs/core-math 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.
- package/LICENSE +21 -0
- package/NOTICE +24 -0
- package/README.md +110 -0
- package/THIRD-PARTY-NOTICES.md +38 -0
- package/package.json +74 -0
- package/src/box3.js +1329 -0
- package/src/constants.js +16 -0
- package/src/curve.js +390 -0
- package/src/geometry/box.js +132 -0
- package/src/geometry/cylinder.js +234 -0
- package/src/geometry/helpers/LICENSE +15 -0
- package/src/geometry/helpers/earcut.js +766 -0
- package/src/geometry/helpers/misc.js +103 -0
- package/src/geometry/index.js +7 -0
- package/src/geometry/json.js +115 -0
- package/src/geometry/lathe.js +148 -0
- package/src/geometry/octahedron.js +0 -0
- package/src/geometry/plane.js +76 -0
- package/src/geometry/shape.js +95 -0
- package/src/geometry/sphere.js +116 -0
- package/src/geometry/torus.js +88 -0
- package/src/index.js +29 -0
- package/src/lne3.js +488 -0
- package/src/mat3.js +131 -0
- package/src/mat4.js +600 -0
- package/src/mesh.js +298 -0
- package/src/noise.js +225 -0
- package/src/num.js +735 -0
- package/src/pln.js +740 -0
- package/src/pool.js +160 -0
- package/src/quat.js +110 -0
- package/src/ray3.js +1056 -0
- package/src/sph3.js +718 -0
- package/src/tangent.js +256 -0
- package/src/tri3.js +650 -0
- package/src/utils.js +15 -0
- package/src/vec2.js +229 -0
- package/src/vec3.js +1116 -0
- package/src/vec4.js +315 -0
- package/src/vertex.js +109 -0
package/src/constants.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small WebGL numeric constants used by the typed-array pool helpers.
|
|
3
|
+
*
|
|
4
|
+
* These are duplicated here to keep core-math standalone and browser-friendly:
|
|
5
|
+
* importing the old ccpwgl `constant` alias would pull the package back toward
|
|
6
|
+
* an application-specific module graph.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const GL_BYTE = 5120;
|
|
10
|
+
export const GL_UNSIGNED_BYTE = 5121;
|
|
11
|
+
export const GL_SHORT = 5122;
|
|
12
|
+
export const GL_UNSIGNED_SHORT = 5123;
|
|
13
|
+
export const GL_INT = 5124;
|
|
14
|
+
export const GL_UNSIGNED_INT = 5125;
|
|
15
|
+
export const GL_FLOAT = 5126;
|
|
16
|
+
|
package/src/curve.js
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
export const curve = {};
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Evaluates a curve
|
|
5
|
+
*
|
|
6
|
+
* @param {{}|Tw2GeometryCurve} curve
|
|
7
|
+
* @param {Array} curve.knots
|
|
8
|
+
* @param {number} curve.degree
|
|
9
|
+
* @param {Array} curve.controls
|
|
10
|
+
* @param {number} curve.dimension
|
|
11
|
+
* @param {number} time
|
|
12
|
+
* @param {*} value
|
|
13
|
+
* @param {Boolean} cycle
|
|
14
|
+
* @param {number} duration
|
|
15
|
+
*/
|
|
16
|
+
curve.evaluate = function(curve, time, value, cycle, duration)
|
|
17
|
+
{
|
|
18
|
+
let count = curve.knots.length;
|
|
19
|
+
let knot = count - 1;
|
|
20
|
+
let t = 0;
|
|
21
|
+
for (let i = 0; i < curve.knots.length; ++i)
|
|
22
|
+
{
|
|
23
|
+
if (curve.knots[i] > time)
|
|
24
|
+
{
|
|
25
|
+
knot = i;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (curve.degree === 0)
|
|
31
|
+
{
|
|
32
|
+
for (let i = 0; i < curve.dimension; ++i)
|
|
33
|
+
{
|
|
34
|
+
value[i] = curve.controls[knot * curve.dimension + i];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (curve.degree === 1)
|
|
38
|
+
{
|
|
39
|
+
let knot0 = cycle ? (knot + count - 1) % count : knot === 0 ? 0 : knot - 1;
|
|
40
|
+
let dt = curve.knots[knot] - curve.knots[knot0];
|
|
41
|
+
|
|
42
|
+
if (dt < 0)
|
|
43
|
+
{
|
|
44
|
+
dt += duration;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (dt > 0)
|
|
48
|
+
{
|
|
49
|
+
t = (time - curve.knots[curve.knots.length - 1]) / dt;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (let i = 0; i < curve.dimension; ++i)
|
|
53
|
+
{
|
|
54
|
+
value[i] = curve.controls[knot0 * curve.dimension + i] * (1 - t) + curve.controls[knot * curve.dimension + i] * t;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
{
|
|
59
|
+
let k_2 = cycle ? (knot + count - 2) % count : knot === 0 ? 0 : knot - 2;
|
|
60
|
+
let k_1 = cycle ? (knot + count - 1) % count : knot === 0 ? 0 : knot - 1;
|
|
61
|
+
|
|
62
|
+
let p1 = (k_2) * curve.dimension;
|
|
63
|
+
let p2 = (k_1) * curve.dimension;
|
|
64
|
+
let p3 = knot * curve.dimension;
|
|
65
|
+
|
|
66
|
+
let ti_2 = curve.knots[k_2];
|
|
67
|
+
let ti_1 = curve.knots[k_1];
|
|
68
|
+
let ti = curve.knots[knot];
|
|
69
|
+
let ti1 = curve.knots[(knot + 1) % count];
|
|
70
|
+
|
|
71
|
+
if (ti_2 > ti)
|
|
72
|
+
{
|
|
73
|
+
ti += duration;
|
|
74
|
+
ti1 += duration;
|
|
75
|
+
time += duration;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (ti_1 > ti)
|
|
79
|
+
{
|
|
80
|
+
ti += duration;
|
|
81
|
+
ti1 += duration;
|
|
82
|
+
time += duration;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (ti1 < ti)
|
|
86
|
+
{
|
|
87
|
+
ti1 += duration;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let tmti_1 = (time - ti_1);
|
|
91
|
+
let tmti_2 = (time - ti_2);
|
|
92
|
+
let dL0 = ti - ti_1;
|
|
93
|
+
let dL1_1 = ti - ti_2;
|
|
94
|
+
let dL1_2 = ti1 - ti_1;
|
|
95
|
+
|
|
96
|
+
let L0 = tmti_1 / dL0;
|
|
97
|
+
let L1_1 = tmti_2 / dL1_1;
|
|
98
|
+
let L1_2 = tmti_1 / dL1_2;
|
|
99
|
+
|
|
100
|
+
let ci_2 = (L1_1 + L0) - L0 * L1_1;
|
|
101
|
+
let ci = L0 * L1_2;
|
|
102
|
+
let ci_1 = ci_2 - ci;
|
|
103
|
+
ci_2 = 1 - ci_2;
|
|
104
|
+
|
|
105
|
+
for (let i = 0; i < curve.dimension; ++i)
|
|
106
|
+
{
|
|
107
|
+
value[i] = ci_2 * curve.controls[p1 + i] + ci_1 * curve.controls[p2 + i] + ci * curve.controls[p3 + i];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* ag_horner1
|
|
114
|
+
*
|
|
115
|
+
* @param P
|
|
116
|
+
* @param deg
|
|
117
|
+
* @param s
|
|
118
|
+
* @returns {*}
|
|
119
|
+
*/
|
|
120
|
+
curve.ag_horner1 = function(P, deg, s)
|
|
121
|
+
{
|
|
122
|
+
let h = P[deg];
|
|
123
|
+
while (--deg >= 0) h = (s * h) + P[deg];
|
|
124
|
+
return (h);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* ag_zeroin2
|
|
129
|
+
*
|
|
130
|
+
* @param a
|
|
131
|
+
* @param b
|
|
132
|
+
* @param fa
|
|
133
|
+
* @param fb
|
|
134
|
+
* @param tol
|
|
135
|
+
* @param pars
|
|
136
|
+
* @returns {*}
|
|
137
|
+
*/
|
|
138
|
+
curve.ag_zeroin2 = function(a, b, fa, fb, tol, pars)
|
|
139
|
+
{
|
|
140
|
+
let test;
|
|
141
|
+
let c, d, e, fc, del, m, machtol, p, q, r, s;
|
|
142
|
+
|
|
143
|
+
/* initialization */
|
|
144
|
+
machtol = 1.192092896e-07;
|
|
145
|
+
let label1 = true;
|
|
146
|
+
|
|
147
|
+
/* start iteration */
|
|
148
|
+
while (true)
|
|
149
|
+
{
|
|
150
|
+
if (label1)
|
|
151
|
+
{
|
|
152
|
+
c = a;
|
|
153
|
+
fc = fa;
|
|
154
|
+
d = b - a;
|
|
155
|
+
e = d;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (Math.abs(fc) < Math.abs(fb))
|
|
159
|
+
{
|
|
160
|
+
a = b;
|
|
161
|
+
b = c;
|
|
162
|
+
c = a;
|
|
163
|
+
fa = fb;
|
|
164
|
+
fb = fc;
|
|
165
|
+
fc = fa;
|
|
166
|
+
}
|
|
167
|
+
label1 = false;
|
|
168
|
+
|
|
169
|
+
/* convergence test */
|
|
170
|
+
del = 2.0 * machtol * Math.abs(b) + 0.5 * tol;
|
|
171
|
+
m = 0.5 * (c - b);
|
|
172
|
+
test = ((Math.abs(m) > del) && (fb !== 0.0));
|
|
173
|
+
if (test)
|
|
174
|
+
{
|
|
175
|
+
if ((Math.abs(e) < del) || (Math.abs(fa) <= Math.abs(fb)))
|
|
176
|
+
{
|
|
177
|
+
/* bisection */
|
|
178
|
+
d = m;
|
|
179
|
+
e = d;
|
|
180
|
+
}
|
|
181
|
+
else
|
|
182
|
+
{
|
|
183
|
+
s = fb / fa;
|
|
184
|
+
if (a === c)
|
|
185
|
+
{
|
|
186
|
+
/* linear interpolation */
|
|
187
|
+
p = 2.0 * m * s;
|
|
188
|
+
q = 1.0 - s;
|
|
189
|
+
}
|
|
190
|
+
else
|
|
191
|
+
{
|
|
192
|
+
/* inverse quadratic interpolation */
|
|
193
|
+
q = fa / fc;
|
|
194
|
+
r = fb / fc;
|
|
195
|
+
p = s * (2.0 * m * q * (q - r) - (b - a) * (r - 1.0));
|
|
196
|
+
q = (q - 1.0) * (r - 1.0) * (s - 1.0);
|
|
197
|
+
}
|
|
198
|
+
/* adjust the sign */
|
|
199
|
+
if (p > 0.0) q = -q;
|
|
200
|
+
else p = -p;
|
|
201
|
+
/* check if interpolation is acceptable */
|
|
202
|
+
s = e;
|
|
203
|
+
e = d;
|
|
204
|
+
if ((2.0 * p < 3.0 * m * q - Math.abs(del * q)) && (p < Math.abs(0.5 * s * q)))
|
|
205
|
+
{
|
|
206
|
+
d = p / q;
|
|
207
|
+
}
|
|
208
|
+
else
|
|
209
|
+
{
|
|
210
|
+
d = m;
|
|
211
|
+
e = d;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/* complete step */
|
|
215
|
+
a = b;
|
|
216
|
+
fa = fb;
|
|
217
|
+
if (Math.abs(d) > del) b += d;
|
|
218
|
+
else if (m > 0.0) b += del;
|
|
219
|
+
else b -= del;
|
|
220
|
+
fb = curve.ag_horner1(pars.p, pars.deg, b);
|
|
221
|
+
if (fb * (fc / Math.abs(fc)) > 0.0)
|
|
222
|
+
{
|
|
223
|
+
label1 = true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else
|
|
227
|
+
{
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return (b);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* ag_zeroin
|
|
236
|
+
*
|
|
237
|
+
* @param a
|
|
238
|
+
* @param b
|
|
239
|
+
* @param tol
|
|
240
|
+
* @param pars
|
|
241
|
+
* @returns {*}
|
|
242
|
+
*/
|
|
243
|
+
curve.ag_zeroin = function(a, b, tol, pars)
|
|
244
|
+
{
|
|
245
|
+
let fa, fb;
|
|
246
|
+
|
|
247
|
+
fa = curve.ag_horner1(pars.p, pars.deg, a);
|
|
248
|
+
if (Math.abs(fa) < 1.192092896e-07) return (a);
|
|
249
|
+
|
|
250
|
+
fb = curve.ag_horner1(pars.p, pars.deg, b);
|
|
251
|
+
if (Math.abs(fb) < 1.192092896e-07) return (b);
|
|
252
|
+
|
|
253
|
+
return (curve.ag_zeroin2(a, b, fa, fb, tol, pars));
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* polyZeroes
|
|
258
|
+
*
|
|
259
|
+
* @param Poly
|
|
260
|
+
* @param deg
|
|
261
|
+
* @param a
|
|
262
|
+
* @param a_closed
|
|
263
|
+
* @param b
|
|
264
|
+
* @param b_closed
|
|
265
|
+
* @param Roots
|
|
266
|
+
* @returns {*}
|
|
267
|
+
*/
|
|
268
|
+
curve.polyZeroes = function(Poly, deg, a, a_closed, b, b_closed, Roots)
|
|
269
|
+
{
|
|
270
|
+
let i, left_ok, right_ok, nr, ndr, skip;
|
|
271
|
+
|
|
272
|
+
let e, f, s, pe, ps, tol, p, p_x = new Array(22),
|
|
273
|
+
d, d_x = new Array(22),
|
|
274
|
+
dr, dr_x = new Array(22);
|
|
275
|
+
|
|
276
|
+
let ply = {
|
|
277
|
+
p: [],
|
|
278
|
+
deg: 0
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
e = pe = 0.0;
|
|
282
|
+
f = 0.0;
|
|
283
|
+
|
|
284
|
+
for (i = 0; i < deg + 1; ++i)
|
|
285
|
+
{
|
|
286
|
+
f += Math.abs(Poly[i]);
|
|
287
|
+
}
|
|
288
|
+
tol = (Math.abs(a) + Math.abs(b)) * (deg + 1) * 1.192092896e-07;
|
|
289
|
+
|
|
290
|
+
/* Zero polynomial to tolerance? */
|
|
291
|
+
if (f <= tol) return (-1);
|
|
292
|
+
|
|
293
|
+
p = p_x;
|
|
294
|
+
d = d_x;
|
|
295
|
+
dr = dr_x;
|
|
296
|
+
for (i = 0; i < deg + 1; ++i)
|
|
297
|
+
{
|
|
298
|
+
p[i] = 1.0 / f * Poly[i];
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* determine true degree */
|
|
302
|
+
while (Math.abs(p[deg]) < tol) deg--;
|
|
303
|
+
|
|
304
|
+
/* Identically zero poly already caught so constant fn !== 0 */
|
|
305
|
+
nr = 0;
|
|
306
|
+
if (deg === 0) return (nr);
|
|
307
|
+
|
|
308
|
+
/* check for linear case */
|
|
309
|
+
if (deg === 1)
|
|
310
|
+
{
|
|
311
|
+
Roots[0] = -p[0] / p[1];
|
|
312
|
+
left_ok = (a_closed) ? (a < Roots[0] + tol) : (a < Roots[0] - tol);
|
|
313
|
+
right_ok = (b_closed) ? (b > Roots[0] - tol) : (b > Roots[0] + tol);
|
|
314
|
+
nr = (left_ok && right_ok) ? 1 : 0;
|
|
315
|
+
if (nr)
|
|
316
|
+
{
|
|
317
|
+
if (a_closed && Roots[0] < a) Roots[0] = a;
|
|
318
|
+
else if (b_closed && Roots[0] > b) Roots[0] = b;
|
|
319
|
+
}
|
|
320
|
+
return nr;
|
|
321
|
+
}
|
|
322
|
+
/* handle non-linear case */
|
|
323
|
+
else
|
|
324
|
+
{
|
|
325
|
+
ply.p = p;
|
|
326
|
+
ply.deg = deg;
|
|
327
|
+
|
|
328
|
+
/* compute derivative */
|
|
329
|
+
for (i = 1; i <= deg; i++) d[i - 1] = i * p[i];
|
|
330
|
+
|
|
331
|
+
/* find roots of derivative */
|
|
332
|
+
ndr = curve.polyZeroes(d, deg - 1, a, 0, b, 0, dr);
|
|
333
|
+
if (ndr.length === 0) return (0);
|
|
334
|
+
|
|
335
|
+
/* find roots between roots of the derivative */
|
|
336
|
+
for (i = skip = 0; i <= ndr; i++)
|
|
337
|
+
{
|
|
338
|
+
if (nr > deg) return (nr);
|
|
339
|
+
if (i === 0)
|
|
340
|
+
{
|
|
341
|
+
s = a;
|
|
342
|
+
ps = curve.ag_horner1(p, deg, s);
|
|
343
|
+
if (Math.abs(ps) <= tol && a_closed) Roots[nr++] = a;
|
|
344
|
+
}
|
|
345
|
+
else
|
|
346
|
+
{
|
|
347
|
+
s = e;
|
|
348
|
+
ps = pe;
|
|
349
|
+
}
|
|
350
|
+
if (i === ndr)
|
|
351
|
+
{
|
|
352
|
+
e = b;
|
|
353
|
+
skip = 0;
|
|
354
|
+
}
|
|
355
|
+
else e = dr[i];
|
|
356
|
+
pe = curve.ag_horner1(p, deg, e);
|
|
357
|
+
if (skip) skip = 0;
|
|
358
|
+
else
|
|
359
|
+
{
|
|
360
|
+
if (Math.abs(pe) < tol)
|
|
361
|
+
{
|
|
362
|
+
if (i !== ndr || b_closed)
|
|
363
|
+
{
|
|
364
|
+
Roots[nr++] = e;
|
|
365
|
+
skip = 1;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
else if ((ps < 0 && pe > 0) || (ps > 0 && pe < 0))
|
|
369
|
+
{
|
|
370
|
+
Roots[nr++] = curve.ag_zeroin(s, e, 0.0, ply);
|
|
371
|
+
if ((nr > 1) && Roots[nr - 2] >= Roots[nr - 1] - tol)
|
|
372
|
+
{
|
|
373
|
+
Roots[nr - 2] = (Roots[nr - 2] + Roots[nr - 1]) * 0.5;
|
|
374
|
+
nr--;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return (nr);
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
export const {
|
|
385
|
+
evaluate,
|
|
386
|
+
ag_horner1,
|
|
387
|
+
ag_zeroin2,
|
|
388
|
+
ag_zeroin,
|
|
389
|
+
polyZeroes
|
|
390
|
+
} = curve;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { vec3 } from "../vec3.js";
|
|
2
|
+
import { toJSON } from "./json.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a box
|
|
7
|
+
* @author Three.js converted
|
|
8
|
+
* @param {Object} [options={}]
|
|
9
|
+
* @param {Number} [options.width=1]
|
|
10
|
+
* @param {Number} [options.height=1]
|
|
11
|
+
* @param {Number} [options.depth=1]
|
|
12
|
+
* @param {Number} [widthSegments=1]
|
|
13
|
+
* @param {Number} [heightSegments=1]
|
|
14
|
+
* @param {Number} [depthSegments=1]
|
|
15
|
+
* @returns {Object}
|
|
16
|
+
*/
|
|
17
|
+
export function createBox(options = {})
|
|
18
|
+
{
|
|
19
|
+
let {
|
|
20
|
+
width = 1,
|
|
21
|
+
height = 1,
|
|
22
|
+
depth = 1,
|
|
23
|
+
widthSegments = 1,
|
|
24
|
+
heightSegments = 1,
|
|
25
|
+
depthSegments = 1
|
|
26
|
+
} = options;
|
|
27
|
+
|
|
28
|
+
widthSegments = Math.floor(widthSegments);
|
|
29
|
+
heightSegments = Math.floor(heightSegments);
|
|
30
|
+
depthSegments = Math.floor(depthSegments);
|
|
31
|
+
|
|
32
|
+
const
|
|
33
|
+
indices = [],
|
|
34
|
+
positions = [],
|
|
35
|
+
normals = [],
|
|
36
|
+
uvs = [];
|
|
37
|
+
|
|
38
|
+
let numberOfVertices = 0;
|
|
39
|
+
|
|
40
|
+
function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY)
|
|
41
|
+
{
|
|
42
|
+
const
|
|
43
|
+
segmentWidth = width / gridX,
|
|
44
|
+
segmentHeight = height / gridY,
|
|
45
|
+
widthHalf = width / 2,
|
|
46
|
+
heightHalf = height / 2,
|
|
47
|
+
depthHalf = depth / 2,
|
|
48
|
+
gridX1 = gridX + 1,
|
|
49
|
+
gridY1 = gridY + 1;
|
|
50
|
+
|
|
51
|
+
let vertexCounter = 0;
|
|
52
|
+
|
|
53
|
+
const vec3_0 = vec3.alloc();
|
|
54
|
+
|
|
55
|
+
// generate vertices, normals and uvs
|
|
56
|
+
|
|
57
|
+
for (let iy = 0; iy < gridY1; iy++)
|
|
58
|
+
{
|
|
59
|
+
const y = iy * segmentHeight - heightHalf;
|
|
60
|
+
|
|
61
|
+
for (let ix = 0; ix < gridX1; ix++)
|
|
62
|
+
{
|
|
63
|
+
const x = ix * segmentWidth - widthHalf;
|
|
64
|
+
// set values to correct vec3_0 component
|
|
65
|
+
vec3_0[u] = x * udir;
|
|
66
|
+
vec3_0[v] = y * vdir;
|
|
67
|
+
vec3_0[w] = depthHalf;
|
|
68
|
+
// now apply vec3_0 to vertex buffer
|
|
69
|
+
positions.push(vec3_0[0], vec3_0[1], vec3_0[2]);
|
|
70
|
+
// set values to correct vec3_0 component
|
|
71
|
+
vec3_0[u] = 0;
|
|
72
|
+
vec3_0[v] = 0;
|
|
73
|
+
vec3_0[w] = depth > 0 ? 1 : -1;
|
|
74
|
+
// now apply vec3_0 to normal buffer
|
|
75
|
+
normals.push(vec3_0[0], vec3_0[1], vec3_0[2]);
|
|
76
|
+
// uvs
|
|
77
|
+
uvs.push(ix / gridX);
|
|
78
|
+
uvs.push(1 - (iy / gridY));
|
|
79
|
+
// counters
|
|
80
|
+
vertexCounter += 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
vec3.unalloc(vec3_0);
|
|
85
|
+
|
|
86
|
+
// indices
|
|
87
|
+
// 1. you need three indices to draw a single face
|
|
88
|
+
// 2. a single segment consists of two faces
|
|
89
|
+
// 3. so we need to generate six (2*3) indices per segment
|
|
90
|
+
for (let iy = 0; iy < gridY; iy++)
|
|
91
|
+
{
|
|
92
|
+
for (let ix = 0; ix < gridX; ix++)
|
|
93
|
+
{
|
|
94
|
+
const
|
|
95
|
+
a = numberOfVertices + ix + gridX1 * iy,
|
|
96
|
+
b = numberOfVertices + ix + gridX1 * (iy + 1),
|
|
97
|
+
c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1),
|
|
98
|
+
d = numberOfVertices + (ix + 1) + gridX1 * iy;
|
|
99
|
+
// faces
|
|
100
|
+
indices.push(a, b, d);
|
|
101
|
+
indices.push(b, c, d);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// update total number of vertices
|
|
106
|
+
numberOfVertices += vertexCounter;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
buildPlane(2, 1, 0, - 1, - 1, depth, height, width, depthSegments, heightSegments); // px
|
|
110
|
+
buildPlane(2, 1, 0, 1, - 1, depth, height, - width, depthSegments, heightSegments); // nx
|
|
111
|
+
buildPlane(0, 2, 1, 1, 1, width, depth, height, widthSegments, depthSegments); // py
|
|
112
|
+
buildPlane(0, 2, 1, 1, - 1, width, depth, - height, widthSegments, depthSegments); // ny
|
|
113
|
+
buildPlane(0, 1, 2, 1, - 1, width, height, depth, widthSegments, heightSegments); // pz
|
|
114
|
+
buildPlane(0, 1, 2, - 1, - 1, width, height, - depth, widthSegments, heightSegments); // nz
|
|
115
|
+
|
|
116
|
+
// Normalize
|
|
117
|
+
const result = toJSON(indices, positions, uvs, normals);
|
|
118
|
+
result.shape = {
|
|
119
|
+
factory: createBox,
|
|
120
|
+
options: {
|
|
121
|
+
width,
|
|
122
|
+
height,
|
|
123
|
+
depth,
|
|
124
|
+
widthSegments,
|
|
125
|
+
heightSegments,
|
|
126
|
+
depthSegments
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return result;
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|