@firecms/neat 0.8.0 → 0.9.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/dist/NeatGradient.d.ts +154 -0
- package/dist/NeatGradient.js +758 -66
- package/dist/NeatGradient.js.map +1 -1
- package/dist/index.es.js +1316 -703
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +389 -403
- package/dist/index.umd.js.map +1 -1
- package/dist/math.d.ts +32 -1
- package/dist/math.js +319 -24
- package/dist/math.js.map +1 -1
- package/dist/shaders.d.ts +2 -2
- package/dist/shaders.js +176 -33
- package/dist/shaders.js.map +1 -1
- package/dist/types.d.ts +25 -0
- package/package.json +1 -1
- package/src/NeatGradient.ts +876 -72
- package/src/math.ts +373 -28
- package/src/shaders.ts +176 -33
- package/src/types.ts +29 -0
package/src/math.ts
CHANGED
|
@@ -30,6 +30,36 @@ export class Matrix4 {
|
|
|
30
30
|
this.elements[11] = c * m43 - s * m42;
|
|
31
31
|
return this;
|
|
32
32
|
}
|
|
33
|
+
rotateY(angle: number) {
|
|
34
|
+
const c = Math.cos(angle);
|
|
35
|
+
const s = Math.sin(angle);
|
|
36
|
+
const m11 = this.elements[0], m21 = this.elements[1], m31 = this.elements[2], m41 = this.elements[3];
|
|
37
|
+
const m13 = this.elements[8], m23 = this.elements[9], m33 = this.elements[10], m43 = this.elements[11];
|
|
38
|
+
this.elements[0] = c * m11 - s * m13;
|
|
39
|
+
this.elements[1] = c * m21 - s * m23;
|
|
40
|
+
this.elements[2] = c * m31 - s * m33;
|
|
41
|
+
this.elements[3] = c * m41 - s * m43;
|
|
42
|
+
this.elements[8] = s * m11 + c * m13;
|
|
43
|
+
this.elements[9] = s * m21 + c * m23;
|
|
44
|
+
this.elements[10] = s * m31 + c * m33;
|
|
45
|
+
this.elements[11] = s * m41 + c * m43;
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
rotateZ(angle: number) {
|
|
49
|
+
const c = Math.cos(angle);
|
|
50
|
+
const s = Math.sin(angle);
|
|
51
|
+
const m11 = this.elements[0], m21 = this.elements[1], m31 = this.elements[2], m41 = this.elements[3];
|
|
52
|
+
const m12 = this.elements[4], m22 = this.elements[5], m32 = this.elements[6], m42 = this.elements[7];
|
|
53
|
+
this.elements[0] = c * m11 + s * m12;
|
|
54
|
+
this.elements[1] = c * m21 + s * m22;
|
|
55
|
+
this.elements[2] = c * m31 + s * m32;
|
|
56
|
+
this.elements[3] = c * m41 + s * m42;
|
|
57
|
+
this.elements[4] = -s * m11 + c * m12;
|
|
58
|
+
this.elements[5] = -s * m21 + c * m22;
|
|
59
|
+
this.elements[6] = -s * m31 + c * m32;
|
|
60
|
+
this.elements[7] = -s * m41 + c * m42;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
33
63
|
}
|
|
34
64
|
|
|
35
65
|
export class OrthographicCamera {
|
|
@@ -41,6 +71,7 @@ export class OrthographicCamera {
|
|
|
41
71
|
far: number;
|
|
42
72
|
position: [number, number, number];
|
|
43
73
|
projectionMatrix: Matrix4;
|
|
74
|
+
zoom: number;
|
|
44
75
|
|
|
45
76
|
constructor(left: number, right: number, top: number, bottom: number, near: number, far: number) {
|
|
46
77
|
this.left = left;
|
|
@@ -50,6 +81,7 @@ export class OrthographicCamera {
|
|
|
50
81
|
this.near = near;
|
|
51
82
|
this.far = far;
|
|
52
83
|
this.position = [0, 0, 0];
|
|
84
|
+
this.zoom = 1.0;
|
|
53
85
|
this.projectionMatrix = new Matrix4();
|
|
54
86
|
this.updateProjectionMatrix();
|
|
55
87
|
}
|
|
@@ -70,35 +102,76 @@ export class OrthographicCamera {
|
|
|
70
102
|
}
|
|
71
103
|
}
|
|
72
104
|
|
|
73
|
-
export function updateCamera(camera: OrthographicCamera, width: number, height: number, planeWidth: number = 50, planeHeight: number = 50) {
|
|
74
|
-
|
|
75
|
-
const areaViewPort = width * height;
|
|
76
|
-
const targetPlaneArea = areaViewPort / viewPortAreaRatio * planeWidth * planeHeight / 1.5;
|
|
77
|
-
|
|
105
|
+
export function updateCamera(camera: OrthographicCamera, width: number, height: number, planeWidth: number = 50, planeHeight: number = 50, shapeType: string = "plane", zoom: number = 1.0) {
|
|
106
|
+
camera.zoom = zoom;
|
|
78
107
|
const ratio = width / height;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
|
|
109
|
+
if (shapeType === "plane") {
|
|
110
|
+
const viewPortAreaRatio = 1000000;
|
|
111
|
+
const areaViewPort = width * height;
|
|
112
|
+
const targetPlaneArea = areaViewPort / viewPortAreaRatio * planeWidth * planeHeight / 1.5;
|
|
113
|
+
|
|
114
|
+
const targetWidth = Math.sqrt(targetPlaneArea * ratio);
|
|
115
|
+
const targetHeight = targetPlaneArea / targetWidth;
|
|
116
|
+
|
|
117
|
+
let left = -planeWidth / 2;
|
|
118
|
+
let right = Math.min((left + targetWidth) / 1.5, planeWidth / 2);
|
|
119
|
+
let top = planeHeight / 4;
|
|
120
|
+
let bottom = Math.max((top - targetHeight) / 2, -planeHeight / 4);
|
|
121
|
+
|
|
122
|
+
if (ratio < 1) {
|
|
123
|
+
const horizontalScale = ratio;
|
|
124
|
+
left = left * horizontalScale;
|
|
125
|
+
right = right * horizontalScale;
|
|
126
|
+
const mobileZoomFactor = 1.05;
|
|
127
|
+
left = left * mobileZoomFactor;
|
|
128
|
+
right = right * mobileZoomFactor;
|
|
129
|
+
top = top * mobileZoomFactor;
|
|
130
|
+
bottom = bottom * mobileZoomFactor;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
camera.left = left;
|
|
134
|
+
camera.right = right;
|
|
135
|
+
camera.top = top;
|
|
136
|
+
camera.bottom = bottom;
|
|
137
|
+
} else {
|
|
138
|
+
// Localized 3D shapes: Sphere, Torus, Cylinder, Ribbon.
|
|
139
|
+
// Use a symmetrical, non-stretching camera frustum.
|
|
140
|
+
let halfSize = 25.0; // Default for Ribbon / others
|
|
141
|
+
if (shapeType === "sphere") {
|
|
142
|
+
halfSize = 30.0;
|
|
143
|
+
} else if (shapeType === "torus") {
|
|
144
|
+
halfSize = 35.0;
|
|
145
|
+
} else if (shapeType === "cylinder") {
|
|
146
|
+
halfSize = 30.0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (ratio >= 1.0) {
|
|
150
|
+
camera.left = -halfSize * ratio;
|
|
151
|
+
camera.right = halfSize * ratio;
|
|
152
|
+
camera.top = halfSize;
|
|
153
|
+
camera.bottom = -halfSize;
|
|
154
|
+
} else {
|
|
155
|
+
camera.left = -halfSize;
|
|
156
|
+
camera.right = halfSize;
|
|
157
|
+
camera.top = halfSize / ratio;
|
|
158
|
+
camera.bottom = -halfSize / ratio;
|
|
159
|
+
|
|
160
|
+
// Zoom out slightly on mobile (1.05 = 5% zoom out)
|
|
161
|
+
const mobileZoomFactor = 1.05;
|
|
162
|
+
camera.left *= mobileZoomFactor;
|
|
163
|
+
camera.right *= mobileZoomFactor;
|
|
164
|
+
camera.top *= mobileZoomFactor;
|
|
165
|
+
camera.bottom *= mobileZoomFactor;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Apply camera zoom to the boundary coordinates
|
|
170
|
+
camera.left /= zoom;
|
|
171
|
+
camera.right /= zoom;
|
|
172
|
+
camera.top /= zoom;
|
|
173
|
+
camera.bottom /= zoom;
|
|
174
|
+
|
|
102
175
|
camera.near = -100;
|
|
103
176
|
camera.far = 1000;
|
|
104
177
|
camera.updateProjectionMatrix();
|
|
@@ -160,3 +233,275 @@ export function generatePlaneGeometry(width: number, height: number, widthSegmen
|
|
|
160
233
|
wireframeIndex: isLarge ? new Uint32Array(wireframeIndices) : new Uint16Array(wireframeIndices)
|
|
161
234
|
};
|
|
162
235
|
}
|
|
236
|
+
|
|
237
|
+
export function generateSphereGeometry(radius: number, widthSegments: number, heightSegments: number) {
|
|
238
|
+
const vertices = [];
|
|
239
|
+
const normals = [];
|
|
240
|
+
const uvs = [];
|
|
241
|
+
const indices = [];
|
|
242
|
+
|
|
243
|
+
const widthSegmentsFloor = Math.floor(widthSegments);
|
|
244
|
+
const heightSegmentsFloor = Math.floor(heightSegments);
|
|
245
|
+
|
|
246
|
+
for (let iy = 0; iy <= heightSegmentsFloor; iy++) {
|
|
247
|
+
const v = iy / heightSegmentsFloor;
|
|
248
|
+
const theta = v * Math.PI;
|
|
249
|
+
|
|
250
|
+
for (let ix = 0; ix <= widthSegmentsFloor; ix++) {
|
|
251
|
+
const u = ix / widthSegmentsFloor;
|
|
252
|
+
const phi = u * Math.PI * 2;
|
|
253
|
+
|
|
254
|
+
const x = -radius * Math.sin(theta) * Math.cos(phi);
|
|
255
|
+
const y = radius * Math.cos(theta);
|
|
256
|
+
const z = radius * Math.sin(theta) * Math.sin(phi);
|
|
257
|
+
|
|
258
|
+
vertices.push(x, y, z);
|
|
259
|
+
|
|
260
|
+
const len = Math.sqrt(x*x + y*y + z*z);
|
|
261
|
+
normals.push(x/len, y/len, z/len);
|
|
262
|
+
|
|
263
|
+
uvs.push(u, 1 - v);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
for (let iy = 0; iy < heightSegmentsFloor; iy++) {
|
|
268
|
+
for (let ix = 0; ix < widthSegmentsFloor; ix++) {
|
|
269
|
+
const a = ix + (widthSegmentsFloor + 1) * iy;
|
|
270
|
+
const b = ix + (widthSegmentsFloor + 1) * (iy + 1);
|
|
271
|
+
const c = (ix + 1) + (widthSegmentsFloor + 1) * (iy + 1);
|
|
272
|
+
const d = (ix + 1) + (widthSegmentsFloor + 1) * iy;
|
|
273
|
+
|
|
274
|
+
indices.push(a, b, d);
|
|
275
|
+
indices.push(b, c, d);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const isLarge = vertices.length / 3 > 65535;
|
|
280
|
+
const wireframeIndices = [];
|
|
281
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
282
|
+
const a = indices[i];
|
|
283
|
+
const b = indices[i + 1];
|
|
284
|
+
const c = indices[i + 2];
|
|
285
|
+
wireframeIndices.push(a, b, b, c, c, a);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
position: new Float32Array(vertices),
|
|
290
|
+
normal: new Float32Array(normals),
|
|
291
|
+
uv: new Float32Array(uvs),
|
|
292
|
+
index: isLarge ? new Uint32Array(indices) : new Uint16Array(indices),
|
|
293
|
+
wireframeIndex: isLarge ? new Uint32Array(wireframeIndices) : new Uint16Array(wireframeIndices)
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export function generateTorusGeometry(radius: number, tube: number, radialSegments: number, tubularSegments: number) {
|
|
298
|
+
const vertices = [];
|
|
299
|
+
const normals = [];
|
|
300
|
+
const uvs = [];
|
|
301
|
+
const indices = [];
|
|
302
|
+
|
|
303
|
+
const radialSegmentsFloor = Math.floor(radialSegments);
|
|
304
|
+
const tubularSegmentsFloor = Math.floor(tubularSegments);
|
|
305
|
+
|
|
306
|
+
for (let j = 0; j <= radialSegmentsFloor; j++) {
|
|
307
|
+
const v = j / radialSegmentsFloor * Math.PI * 2;
|
|
308
|
+
|
|
309
|
+
for (let i = 0; i <= tubularSegmentsFloor; i++) {
|
|
310
|
+
const u = i / tubularSegmentsFloor * Math.PI * 2;
|
|
311
|
+
|
|
312
|
+
const x = (radius + tube * Math.cos(v)) * Math.cos(u);
|
|
313
|
+
const y = (radius + tube * Math.cos(v)) * Math.sin(u);
|
|
314
|
+
const z = tube * Math.sin(v);
|
|
315
|
+
|
|
316
|
+
vertices.push(x, y, z);
|
|
317
|
+
|
|
318
|
+
const cx = radius * Math.cos(u);
|
|
319
|
+
const cy = radius * Math.sin(u);
|
|
320
|
+
const nx = x - cx;
|
|
321
|
+
const ny = y - cy;
|
|
322
|
+
const nz = z;
|
|
323
|
+
const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
|
|
324
|
+
normals.push(nx / len, ny / len, nz / len);
|
|
325
|
+
|
|
326
|
+
uvs.push(i / tubularSegmentsFloor, j / radialSegmentsFloor);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
for (let j = 1; j <= radialSegmentsFloor; j++) {
|
|
331
|
+
for (let i = 1; i <= tubularSegmentsFloor; i++) {
|
|
332
|
+
const a = (tubularSegmentsFloor + 1) * j + i - 1;
|
|
333
|
+
const b = (tubularSegmentsFloor + 1) * (j - 1) + i - 1;
|
|
334
|
+
const c = (tubularSegmentsFloor + 1) * (j - 1) + i;
|
|
335
|
+
const d = (tubularSegmentsFloor + 1) * j + i;
|
|
336
|
+
|
|
337
|
+
indices.push(a, b, d);
|
|
338
|
+
indices.push(b, c, d);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const isLarge = vertices.length / 3 > 65535;
|
|
343
|
+
const wireframeIndices = [];
|
|
344
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
345
|
+
const a = indices[i];
|
|
346
|
+
const b = indices[i + 1];
|
|
347
|
+
const c = indices[i + 2];
|
|
348
|
+
wireframeIndices.push(a, b, b, c, c, a);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return {
|
|
352
|
+
position: new Float32Array(vertices),
|
|
353
|
+
normal: new Float32Array(normals),
|
|
354
|
+
uv: new Float32Array(uvs),
|
|
355
|
+
index: isLarge ? new Uint32Array(indices) : new Uint16Array(indices),
|
|
356
|
+
wireframeIndex: isLarge ? new Uint32Array(wireframeIndices) : new Uint16Array(wireframeIndices)
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function generateCylinderGeometry(radiusTop: number, radiusBottom: number, height: number, radialSegments: number, heightSegments: number) {
|
|
361
|
+
const vertices = [];
|
|
362
|
+
const normals = [];
|
|
363
|
+
const uvs = [];
|
|
364
|
+
const indices = [];
|
|
365
|
+
|
|
366
|
+
const radialSegmentsFloor = Math.floor(radialSegments);
|
|
367
|
+
const heightSegmentsFloor = Math.floor(heightSegments);
|
|
368
|
+
|
|
369
|
+
const halfHeight = height / 2;
|
|
370
|
+
|
|
371
|
+
for (let y = 0; y <= heightSegmentsFloor; y++) {
|
|
372
|
+
const v = y / heightSegmentsFloor;
|
|
373
|
+
const h = v * height - halfHeight;
|
|
374
|
+
const radius = v * (radiusBottom - radiusTop) + radiusTop;
|
|
375
|
+
|
|
376
|
+
for (let x = 0; x <= radialSegmentsFloor; x++) {
|
|
377
|
+
const u = x / radialSegmentsFloor;
|
|
378
|
+
const theta = u * Math.PI * 2;
|
|
379
|
+
|
|
380
|
+
const sinTheta = Math.sin(theta);
|
|
381
|
+
const cosTheta = Math.cos(theta);
|
|
382
|
+
|
|
383
|
+
vertices.push(radius * sinTheta, -h, radius * cosTheta);
|
|
384
|
+
normals.push(sinTheta, 0, cosTheta);
|
|
385
|
+
uvs.push(u, 1 - v);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
for (let y = 0; y < heightSegmentsFloor; y++) {
|
|
390
|
+
for (let x = 0; x < radialSegmentsFloor; x++) {
|
|
391
|
+
const a = x + (radialSegmentsFloor + 1) * y;
|
|
392
|
+
const b = x + (radialSegmentsFloor + 1) * (y + 1);
|
|
393
|
+
const c = (x + 1) + (radialSegmentsFloor + 1) * (y + 1);
|
|
394
|
+
const d = (x + 1) + (radialSegmentsFloor + 1) * y;
|
|
395
|
+
|
|
396
|
+
indices.push(a, b, d);
|
|
397
|
+
indices.push(b, c, d);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const isLarge = vertices.length / 3 > 65535;
|
|
402
|
+
const wireframeIndices = [];
|
|
403
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
404
|
+
const a = indices[i];
|
|
405
|
+
const b = indices[i + 1];
|
|
406
|
+
const c = indices[i + 2];
|
|
407
|
+
wireframeIndices.push(a, b, b, c, c, a);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
position: new Float32Array(vertices),
|
|
412
|
+
normal: new Float32Array(normals),
|
|
413
|
+
uv: new Float32Array(uvs),
|
|
414
|
+
index: isLarge ? new Uint32Array(indices) : new Uint16Array(indices),
|
|
415
|
+
wireframeIndex: isLarge ? new Uint32Array(wireframeIndices) : new Uint16Array(wireframeIndices)
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function generateRibbonGeometry(width: number, height: number, widthSegments: number, heightSegments: number, bend: number, twist: number) {
|
|
420
|
+
const width_half = width / 2;
|
|
421
|
+
const height_half = height / 2;
|
|
422
|
+
const gridX = Math.floor(widthSegments);
|
|
423
|
+
const gridY = Math.floor(heightSegments);
|
|
424
|
+
const gridX1 = gridX + 1;
|
|
425
|
+
const gridY1 = gridY + 1;
|
|
426
|
+
const segment_width = width / gridX;
|
|
427
|
+
const segment_height = height / gridY;
|
|
428
|
+
|
|
429
|
+
const vertices = [];
|
|
430
|
+
const normals = [];
|
|
431
|
+
const uvs = [];
|
|
432
|
+
const indices = [];
|
|
433
|
+
|
|
434
|
+
for (let iy = 0; iy < gridY1; iy++) {
|
|
435
|
+
const y = iy * segment_height - height_half;
|
|
436
|
+
for (let ix = 0; ix < gridX1; ix++) {
|
|
437
|
+
const x = ix * segment_width - width_half;
|
|
438
|
+
|
|
439
|
+
let xp = x;
|
|
440
|
+
let yp = y;
|
|
441
|
+
let zp = 0;
|
|
442
|
+
|
|
443
|
+
let nx = 0;
|
|
444
|
+
let ny = 0;
|
|
445
|
+
let nz = 1;
|
|
446
|
+
|
|
447
|
+
if (Math.abs(bend) > 0.001) {
|
|
448
|
+
const r = width / bend;
|
|
449
|
+
const angle = x / r;
|
|
450
|
+
xp = r * Math.sin(angle);
|
|
451
|
+
zp = r * (1 - Math.cos(angle));
|
|
452
|
+
|
|
453
|
+
nx = Math.sin(angle);
|
|
454
|
+
nz = Math.cos(angle);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (Math.abs(twist) > 0.001) {
|
|
458
|
+
const angle = (y / height) * twist;
|
|
459
|
+
const cosA = Math.cos(angle);
|
|
460
|
+
const sinA = Math.sin(angle);
|
|
461
|
+
|
|
462
|
+
const rx = xp * cosA - zp * sinA;
|
|
463
|
+
const rz = xp * sinA + zp * cosA;
|
|
464
|
+
xp = rx;
|
|
465
|
+
zp = rz;
|
|
466
|
+
|
|
467
|
+
const rnx = nx * cosA - nz * sinA;
|
|
468
|
+
const rnz = nx * sinA + nz * cosA;
|
|
469
|
+
nx = rnx;
|
|
470
|
+
nz = rnz;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
vertices.push(xp, -yp, zp);
|
|
474
|
+
normals.push(nx, ny, nz);
|
|
475
|
+
uvs.push(ix / gridX);
|
|
476
|
+
uvs.push(1 - (iy / gridY));
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
for (let iy = 0; iy < gridY; iy++) {
|
|
481
|
+
for (let ix = 0; ix < gridX; ix++) {
|
|
482
|
+
const a = ix + gridX1 * iy;
|
|
483
|
+
const b = ix + gridX1 * (iy + 1);
|
|
484
|
+
const c = (ix + 1) + gridX1 * (iy + 1);
|
|
485
|
+
const d = (ix + 1) + gridX1 * iy;
|
|
486
|
+
indices.push(a, b, d);
|
|
487
|
+
indices.push(b, c, d);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const isLarge = vertices.length / 3 > 65535;
|
|
492
|
+
const wireframeIndices = [];
|
|
493
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
494
|
+
const a = indices[i];
|
|
495
|
+
const b = indices[i + 1];
|
|
496
|
+
const c = indices[i + 2];
|
|
497
|
+
wireframeIndices.push(a, b, b, c, c, a);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return {
|
|
501
|
+
position: new Float32Array(vertices),
|
|
502
|
+
normal: new Float32Array(normals),
|
|
503
|
+
uv: new Float32Array(uvs),
|
|
504
|
+
index: isLarge ? new Uint32Array(indices) : new Uint16Array(indices),
|
|
505
|
+
wireframeIndex: isLarge ? new Uint32Array(wireframeIndices) : new Uint16Array(wireframeIndices)
|
|
506
|
+
};
|
|
507
|
+
}
|