poly-extrude 0.13.0 → 0.14.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 (68) hide show
  1. package/dist/cylinder.d.ts +11 -0
  2. package/{src → dist}/cylinder.js +108 -111
  3. package/dist/cylinder.js.map +1 -0
  4. package/dist/index.d.ts +7 -0
  5. package/dist/index.js +8 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/math/Curve.d.ts +41 -0
  8. package/dist/math/Curve.js +142 -0
  9. package/dist/math/Curve.js.map +1 -0
  10. package/dist/math/Interpolations.d.ts +8 -0
  11. package/dist/math/Interpolations.js +48 -0
  12. package/dist/math/Interpolations.js.map +1 -0
  13. package/dist/math/Matrix4.d.ts +8 -0
  14. package/dist/math/Matrix4.js +582 -0
  15. package/dist/math/Matrix4.js.map +1 -0
  16. package/dist/math/QuadraticBezierCurve3.d.ts +10 -0
  17. package/dist/math/QuadraticBezierCurve3.js +22 -0
  18. package/dist/math/QuadraticBezierCurve3.js.map +1 -0
  19. package/dist/math/Quaternion.d.ts +46 -0
  20. package/dist/math/Quaternion.js +415 -0
  21. package/dist/math/Quaternion.js.map +1 -0
  22. package/dist/math/Vector3.d.ts +42 -0
  23. package/dist/math/Vector3.js +403 -0
  24. package/dist/math/Vector3.js.map +1 -0
  25. package/dist/path/PathPoint.d.ts +15 -0
  26. package/dist/path/PathPoint.js +35 -0
  27. package/dist/path/PathPoint.js.map +1 -0
  28. package/dist/path/PathPointList.d.ts +27 -0
  29. package/dist/path/PathPointList.js +212 -0
  30. package/dist/path/PathPointList.js.map +1 -0
  31. package/dist/path.d.ts +11 -0
  32. package/{src → dist}/path.js +334 -360
  33. package/dist/path.js.map +1 -0
  34. package/dist/plane.d.ts +2 -0
  35. package/{src → dist}/plane.js +57 -58
  36. package/dist/plane.js.map +1 -0
  37. package/dist/poly-extrude.js +1286 -1581
  38. package/dist/poly-extrude.js.map +1 -1
  39. package/dist/poly-extrude.min.js +2 -2
  40. package/dist/poly-extrude.mjs +1286 -1581
  41. package/dist/poly-extrude.mjs.map +1 -0
  42. package/dist/polygon.d.ts +9 -0
  43. package/{src → dist}/polygon.js +163 -179
  44. package/dist/polygon.js.map +1 -0
  45. package/dist/polyline.d.ts +24 -0
  46. package/{src → dist}/polyline.js +420 -456
  47. package/dist/polyline.js.map +1 -0
  48. package/dist/tube.d.ts +12 -0
  49. package/{src → dist}/tube.js +124 -142
  50. package/dist/tube.js.map +1 -0
  51. package/dist/type.d.ts +9 -0
  52. package/dist/type.js +2 -0
  53. package/dist/type.js.map +1 -0
  54. package/dist/util.d.ts +20 -0
  55. package/dist/util.js +217 -0
  56. package/dist/util.js.map +1 -0
  57. package/package.json +53 -48
  58. package/readme.md +12 -2
  59. package/src/cylinder.ts +124 -0
  60. package/src/index.ts +7 -0
  61. package/src/path.ts +385 -0
  62. package/src/plane.ts +60 -0
  63. package/src/polygon.ts +189 -0
  64. package/src/polyline.ts +473 -0
  65. package/src/tube.ts +155 -0
  66. package/src/type.ts +9 -0
  67. package/src/{util.js → util.ts} +1 -1
  68. package/index.js +0 -7
@@ -0,0 +1,473 @@
1
+ import { PolylineType, ResultType } from './type';
2
+ import { calLineDistance, degToRad, generateNormal, generateSideWallUV, merge, radToDeg } from './util';
3
+
4
+ function checkOptions(options) {
5
+ options.lineWidth = Math.max(0, options.lineWidth);
6
+ options.depth = Math.max(0, options.depth);
7
+ options.sideDepth = Math.max(0, options.sideDepth);
8
+ }
9
+
10
+ type PolylinesOptions = {
11
+ depth?: number;
12
+ lineWidth?: number;
13
+ bottomStickGround?: boolean;
14
+ pathUV?: boolean;
15
+ }
16
+
17
+ type PolylinesResult = ResultType & {
18
+ lines: Array<PolylineType>;
19
+ }
20
+
21
+ export function extrudePolylines(lines: Array<PolylineType>, options?: PolylinesOptions): PolylinesResult {
22
+ options = Object.assign({}, { depth: 2, lineWidth: 1, bottomStickGround: false, pathUV: false }, options);
23
+ checkOptions(options);
24
+ const results = lines.map(line => {
25
+ const result = expandLine(line, options) as Record<string, any>;
26
+ result.line = line;
27
+ generateTopAndBottom(result, options);
28
+ generateSides(result, options);
29
+ result.position = new Float32Array(result.points);
30
+ result.indices = new Uint32Array(result.indices);
31
+ result.uv = new Float32Array(result.uv);
32
+ result.normal = generateNormal(result.indices, result.position);
33
+ return result;
34
+ });
35
+ const result = merge(results) as PolylinesResult;
36
+ result.lines = lines;
37
+ return result;
38
+ }
39
+
40
+ type SlopesOptions = PolylinesOptions & {
41
+ side?: 'left' | 'right',
42
+ sideDepth?: number
43
+ }
44
+
45
+ export function extrudeSlopes(lines: Array<PolylineType>, options?: SlopesOptions): PolylinesResult {
46
+ options = Object.assign({}, { depth: 2, lineWidth: 1, side: 'left', sideDepth: 0, bottomStickGround: false, pathUV: false, isSlope: true }, options);
47
+ checkOptions(options);
48
+ const { depth, side, sideDepth } = options;
49
+ const results = lines.map(line => {
50
+ const tempResult = expandLine(line, options);
51
+ tempResult.line = line;
52
+ const { leftPoints, rightPoints } = tempResult;
53
+ const result: Record<string, any> = { line };
54
+ let depths;
55
+ for (let i = 0, len = line.length; i < len; i++) {
56
+ line[i][2] = line[i][2] || 0;
57
+ }
58
+ if (side === 'left') {
59
+ result.leftPoints = leftPoints;
60
+ result.rightPoints = line;
61
+ depths = [sideDepth, depth];
62
+ } else {
63
+ result.leftPoints = line;
64
+ result.rightPoints = rightPoints;
65
+ depths = [depth, sideDepth];
66
+ }
67
+ result.depths = depths;
68
+ generateTopAndBottom(result, options);
69
+ generateSides(result, options);
70
+ result.position = new Float32Array(result.points);
71
+ result.indices = new Uint32Array(result.indices);
72
+ result.uv = new Float32Array(result.uv);
73
+ result.normal = generateNormal(result.indices, result.position);
74
+ return result;
75
+ });
76
+ const result = merge(results) as PolylinesResult;
77
+ result.lines = lines;
78
+ return result;
79
+ }
80
+
81
+ function generateTopAndBottom(result, options) {
82
+ const bottomStickGround = options.bottomStickGround;
83
+ const z = options.depth;
84
+ const depths = result.depths;
85
+ let lz = z, rz = z;
86
+ if (depths) {
87
+ lz = depths[0];
88
+ rz = depths[1];
89
+ }
90
+ const { leftPoints, rightPoints } = result;
91
+ const line = result.line;
92
+ const pathUV = options.pathUV;
93
+ if (pathUV) {
94
+ calLineDistance(line);
95
+ for (let i = 0, len = line.length; i < len; i++) {
96
+ leftPoints[i].distance = rightPoints[i].distance = line[i].distance;
97
+ }
98
+ }
99
+ let i = 0, len = leftPoints.length;
100
+ const points: number[] = [], indices: number[] = [], uv: number[] = [];
101
+ while (i < len) {
102
+ // top left
103
+ const idx0 = i * 3;
104
+ const [x1, y1, z1] = leftPoints[i];
105
+ points[idx0] = x1;
106
+ points[idx0 + 1] = y1;
107
+ points[idx0 + 2] = lz + z1;
108
+
109
+ // top right
110
+ const [x2, y2, z2] = rightPoints[i];
111
+ const idx1 = len * 3 + idx0;
112
+ points[idx1] = x2;
113
+ points[idx1 + 1] = y2;
114
+ points[idx1 + 2] = rz + z2;
115
+
116
+ // bottom left
117
+ const idx2 = (len * 2) * 3 + idx0;
118
+ points[idx2] = x1;
119
+ points[idx2 + 1] = y1;
120
+ points[idx2 + 2] = z1;
121
+ if (bottomStickGround) {
122
+ points[idx2 + 2] = 0;
123
+ }
124
+
125
+ // bottom right
126
+ const idx3 = (len * 2) * 3 + len * 3 + idx0;
127
+ points[idx3] = x2;
128
+ points[idx3 + 1] = y2;
129
+ points[idx3 + 2] = z2;
130
+ if (bottomStickGround) {
131
+ points[idx3 + 2] = 0;
132
+ }
133
+
134
+ // generate path uv
135
+ if (pathUV) {
136
+ const p = line[i];
137
+ const uvx = p.distance;
138
+
139
+ const uIndex0 = i * 2;
140
+ uv[uIndex0] = uvx;
141
+ uv[uIndex0 + 1] = 1;
142
+
143
+ const uIndex1 = len * 2 + uIndex0;
144
+ uv[uIndex1] = uvx;
145
+ uv[uIndex1 + 1] = 0;
146
+
147
+ const uIndex2 = (len * 2) * 2 + uIndex0;
148
+ uv[uIndex2] = uvx;
149
+ uv[uIndex2 + 1] = 1;
150
+
151
+ const uIndex3 = (len * 2) * 2 + len * 2 + uIndex0;
152
+ uv[uIndex3] = uvx;
153
+ uv[uIndex3 + 1] = 0;
154
+
155
+ }
156
+ i++;
157
+ }
158
+ if (!pathUV) {
159
+ i = 0;
160
+ len = points.length;
161
+ let uIndex = uv.length - 1;
162
+ while (i < len) {
163
+ const x = points[i], y = points[i + 1];
164
+ uv[++uIndex] = x;
165
+ uv[++uIndex] = y;
166
+ // uvs.push(x, y);
167
+ i += 3;
168
+ }
169
+ }
170
+
171
+ i = 0;
172
+ len = leftPoints.length;
173
+ let iIndex = indices.length - 1;
174
+ while (i < len - 1) {
175
+ // top
176
+ // left1 left2 right1,right2
177
+ const a1 = i, b1 = i + 1, c1 = a1 + len, d1 = b1 + len;
178
+ indices[++iIndex] = a1;
179
+ indices[++iIndex] = c1;
180
+ indices[++iIndex] = b1;
181
+ indices[++iIndex] = c1;
182
+ indices[++iIndex] = d1;
183
+ indices[++iIndex] = b1;
184
+ // index.push(a1, c1, b1);
185
+ // index.push(c1, d1, b1);
186
+
187
+ // bottom
188
+ // left1 left2 right1,right2
189
+ const len2 = len * 2;
190
+ const a2 = i + len2, b2 = a2 + 1, c2 = a2 + len, d2 = b2 + len;
191
+ indices[++iIndex] = a2;
192
+ indices[++iIndex] = c2;
193
+ indices[++iIndex] = b2;
194
+ indices[++iIndex] = c2;
195
+ indices[++iIndex] = d2;
196
+ indices[++iIndex] = b2;
197
+ // index.push(a2, c2, b2);
198
+ // index.push(c2, d2, b2);
199
+ i++;
200
+ }
201
+ result.indices = indices;
202
+ result.points = points;
203
+ result.uv = uv;
204
+ if (depths) {
205
+ len = leftPoints.length;
206
+ i = 0;
207
+ while (i < len) {
208
+ leftPoints[i].depth = lz;
209
+ rightPoints[i].depth = rz;
210
+ i++;
211
+ }
212
+ }
213
+ }
214
+
215
+ function generateSides(result, options) {
216
+ const { points, indices, leftPoints, rightPoints, uv } = result;
217
+ const z = options.depth;
218
+ const bottomStickGround = options.bottomStickGround;
219
+ const rings = [leftPoints, rightPoints];
220
+ const depthsEnable = result.depths;
221
+ const pathUV = options.pathUV;
222
+ const lineWidth = options.lineWidth;
223
+
224
+ let pIndex = points.length - 1;
225
+ let iIndex = indices.length - 1;
226
+ let uIndex = uv.length - 1;
227
+
228
+ function addOneSideIndex(v1, v2) {
229
+ const idx = points.length / 3;
230
+ // let pIndex = points.length - 1;
231
+
232
+ const v1Depth = (depthsEnable ? v1.depth : z);
233
+ const v2Depth = (depthsEnable ? v2.depth : z);
234
+
235
+ // top
236
+ points[++pIndex] = v1[0];
237
+ points[++pIndex] = v1[1];
238
+ points[++pIndex] = v1Depth + v1[2];
239
+
240
+ points[++pIndex] = v2[0];
241
+ points[++pIndex] = v2[1];
242
+ points[++pIndex] = v2Depth + v2[2];
243
+
244
+ // points.push(v1[0], v1[1], (depthsEnable ? v1.depth : z) + v1[2], v2[0], v2[1], (depthsEnable ? v2.depth : z) + v2[2]);
245
+
246
+ // bottom
247
+
248
+ points[++pIndex] = v1[0];
249
+ points[++pIndex] = v1[1];
250
+ points[++pIndex] = bottomStickGround ? 0 : v1[2];
251
+
252
+ points[++pIndex] = v2[0];
253
+ points[++pIndex] = v2[1];
254
+ points[++pIndex] = bottomStickGround ? 0 : v2[2];
255
+
256
+ // points.push(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]);
257
+
258
+ const a = idx + 2, b = idx + 3, c = idx, d = idx + 1;
259
+ indices[++iIndex] = a;
260
+ indices[++iIndex] = c;
261
+ indices[++iIndex] = b;
262
+ indices[++iIndex] = c;
263
+ indices[++iIndex] = d;
264
+ indices[++iIndex] = b;
265
+ // index.push(a, c, b, c, d, b);
266
+ if (!pathUV) {
267
+ generateSideWallUV(uv, points, a, b, c, d);
268
+ } else {
269
+ uv[++uIndex] = v1.distance;
270
+ uv[++uIndex] = v1Depth / lineWidth;
271
+
272
+ uv[++uIndex] = v2.distance;
273
+ uv[++uIndex] = v2Depth / lineWidth;
274
+
275
+ uv[++uIndex] = v1.distance;
276
+ uv[++uIndex] = 0;
277
+
278
+ uv[++uIndex] = v2.distance;
279
+ uv[++uIndex] = 0;
280
+ }
281
+ }
282
+
283
+ for (let i = 0, len = rings.length; i < len; i++) {
284
+ let ring = rings[i];
285
+ if (i > 0) {
286
+ ring = ring.map(p => {
287
+ return p;
288
+ });
289
+ ring = ring.reverse();
290
+ }
291
+ let j = 0;
292
+ const len1 = ring.length - 1;
293
+ while (j < len1) {
294
+ const v1 = ring[j];
295
+ const v2 = ring[j + 1];
296
+ addOneSideIndex(v1, v2);
297
+ j++;
298
+ }
299
+ }
300
+ const len = leftPoints.length;
301
+ const vs = [rightPoints[0], leftPoints[0], leftPoints[len - 1], rightPoints[len - 1]];
302
+ for (let i = 0; i < vs.length; i += 2) {
303
+ const v1 = vs[i], v2 = vs[i + 1];
304
+ addOneSideIndex(v1, v2);
305
+ }
306
+ }
307
+
308
+ const TEMPV1 = { x: 0, y: 0 }, TEMPV2 = { x: 0, y: 0 };
309
+
310
+ export function expandLine(line, options) {
311
+ // let preAngle = 0;
312
+ let radius = options.lineWidth / 2;
313
+ if (options.isSlope) {
314
+ radius *= 2;
315
+ }
316
+ const points: Array<number[]> = [], leftPoints: Array<number[]> = [], rightPoints: Array<number[]> = [];
317
+ const len = line.length;
318
+ let i = 0;
319
+ while (i < len) {
320
+ let p1 = line[i],
321
+ p2 = line[i + 1];
322
+ const currentp = line[i];
323
+ // last vertex
324
+ if (i === len - 1) {
325
+ p1 = line[len - 2];
326
+ p2 = line[len - 1];
327
+ }
328
+ const dy = p2[1] - p1[1],
329
+ dx = p2[0] - p1[0];
330
+ let rAngle = 0;
331
+ const rad = Math.atan(dy / dx);
332
+ const angle = radToDeg(rad);
333
+ // preAngle = angle;
334
+ if (i === 0 || i === len - 1) {
335
+ rAngle = angle;
336
+ rAngle -= 90;
337
+ } else {
338
+ // 至少3个顶点才会触发
339
+ const p0 = line[i - 1];
340
+ TEMPV1.x = p0[0] - p1[0];
341
+ TEMPV1.y = p0[1] - p1[1];
342
+ TEMPV2.x = p2[0] - p1[0];
343
+ TEMPV2.y = p2[1] - p1[1];
344
+ const vAngle = getAngle(TEMPV1, TEMPV2);
345
+ rAngle = angle - vAngle / 2;
346
+ }
347
+ const rRad = degToRad(rAngle);
348
+ const p3 = currentp;
349
+ const x = Math.cos(rRad) + p3[0], y = Math.sin(rRad) + p3[1];
350
+ const p4 = [x, y];
351
+ const [line1, line2] = translateLine(p1, p2, radius);
352
+ let op1 = lineIntersection(line1[0], line1[1], p3, p4);
353
+ let op2 = lineIntersection(line2[0], line2[1], p3, p4);
354
+ // 平行,回头路
355
+ if (!op1 || !op2) {
356
+ const len1 = points.length;
357
+ const point1 = points[len1 - 2];
358
+ const point2 = points[len1 - 1];
359
+ if (!point1 || !point2) {
360
+ continue;
361
+ }
362
+ op1 = [point1[0], point1[1]];
363
+ op2 = [point2[0], point2[1]];
364
+ }
365
+ op1[2] = currentp[2] || 0;
366
+ op2[2] = currentp[2] || 0;
367
+ // const [op1, op2] = calOffsetPoint(rRad, radius, p1);
368
+ points.push(op1, op2);
369
+ if (leftOnLine(op1, p1, p2)) {
370
+ leftPoints.push(op1);
371
+ rightPoints.push(op2);
372
+ } else {
373
+ leftPoints.push(op2);
374
+ rightPoints.push(op1);
375
+ }
376
+ i++;
377
+ }
378
+
379
+ return { offsetPoints: points, leftPoints, rightPoints, line };
380
+ }
381
+
382
+ // eslint-disable-next-line no-unused-vars
383
+ function calOffsetPoint(rad, radius, p) {
384
+ const [x, y] = p;
385
+ const z = p[2] || 0;
386
+ const x1 = Math.cos(rad) * radius, y1 = Math.sin(rad) * radius;
387
+ const p1 = [x + x1, y + y1, z];
388
+ const rad1 = rad += Math.PI;
389
+ const x2 = Math.cos(rad1) * radius, y2 = Math.sin(rad1) * radius;
390
+ const p2 = [x + x2, y + y2, z];
391
+ return [p1, p2];
392
+ }
393
+
394
+ const getAngle = ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
395
+ const dot = x1 * x2 + y1 * y2;
396
+ const det = x1 * y2 - y1 * x2;
397
+ const angle = Math.atan2(det, dot) / Math.PI * 180;
398
+ return (angle + 360) % 360;
399
+ };
400
+
401
+ export function leftOnLine(p, p1, p2) {
402
+ const [x1, y1] = p1;
403
+ const [x2, y2] = p2;
404
+ const [x, y] = p;
405
+ return (y1 - y2) * x + (x2 - x1) * y + x1 * y2 - x2 * y1 > 0;
406
+ }
407
+
408
+ /**
409
+ * 平移线
410
+ * @param {*} p1
411
+ * @param {*} p2
412
+ * @param {*} distance
413
+ * @returns
414
+ */
415
+ function translateLine(p1, p2, distance) {
416
+ const dy = p2[1] - p1[1], dx = p2[0] - p1[0];
417
+ const rad = Math.atan2(dy, dx);
418
+ const rad1 = rad + Math.PI / 2;
419
+ let offsetX = Math.cos(rad1) * distance, offsetY = Math.sin(rad1) * distance;
420
+ const tp1 = [p1[0] + offsetX, p1[1] + offsetY];
421
+ const tp2 = [p2[0] + offsetX, p2[1] + offsetY];
422
+ const rad2 = rad - Math.PI / 2;
423
+ offsetX = Math.cos(rad2) * distance;
424
+ offsetY = Math.sin(rad2) * distance;
425
+ const tp3 = [p1[0] + offsetX, p1[1] + offsetY];
426
+ const tp4 = [p2[0] + offsetX, p2[1] + offsetY];
427
+ return [[tp1, tp2], [tp3, tp4]];
428
+ }
429
+
430
+ /**
431
+ * 直线交点
432
+ * @param {*} p1
433
+ * @param {*} p2
434
+ * @param {*} p3
435
+ * @param {*} p4
436
+ * @returns
437
+ */
438
+ function lineIntersection(p1, p2, p3, p4): Array<number> | null {
439
+ const dx1 = p2[0] - p1[0], dy1 = p2[1] - p1[1];
440
+ const dx2 = p4[0] - p3[0], dy2 = p4[1] - p3[1];
441
+ if (dx1 === 0 && dx2 === 0) {
442
+ return null;
443
+ }
444
+ if (dy1 === 0 && dy2 === 0) {
445
+ return null;
446
+ }
447
+
448
+ const k1 = dy1 / dx1;
449
+ const k2 = dy2 / dx2;
450
+
451
+ const b1 = p1[1] - k1 * p1[0];
452
+ const b2 = p3[1] - k2 * p3[0];
453
+
454
+ let x, y;
455
+
456
+ if (dx1 === 0) {
457
+ x = p1[0];
458
+ y = k2 * x + b2;
459
+ } else if (dx2 === 0) {
460
+ x = p3[0];
461
+ y = k1 * x + b1;
462
+ } else if (dy1 === 0) {
463
+ y = p1[1];
464
+ x = (y - b2) / k2;
465
+ } else if (dy2 === 0) {
466
+ y = p3[1];
467
+ x = (y - b1) / k1;
468
+ } else {
469
+ x = (b2 - b1) / (k1 - k2);
470
+ y = k1 * x + b1;
471
+ }
472
+ return [x, y];
473
+ }
package/src/tube.ts ADDED
@@ -0,0 +1,155 @@
1
+ import { Vector3 } from './math/Vector3';
2
+ import { PathPoint } from './path/PathPoint';
3
+ import { PathPointList } from './path/PathPointList';
4
+ import { PolylineType, ResultType } from './type';
5
+ import { line2Vectors, merge } from './util';
6
+ const UP = new Vector3(0, 0, 1);
7
+ const normalDir = new Vector3();
8
+
9
+ type TubesOptions = {
10
+ radius?: number;
11
+ cornerSplit?: number;
12
+ radialSegments?: number;
13
+ startRad?: number;
14
+ }
15
+
16
+ type TubesResult = ResultType & {
17
+ lines: Array<PolylineType>;
18
+ }
19
+
20
+ export function expandTubes(lines: Array<PolylineType>, options?: TubesOptions) {
21
+ options = Object.assign({}, { radius: 1, cornerSplit: 0, radialSegments: 8, startRad: -Math.PI / 4 }, options);
22
+ const results = lines.map(line => {
23
+ const points = line2Vectors(line);
24
+ const pathPointList = new PathPointList();
25
+ //@ts-ignore
26
+ pathPointList.set(points, 0, options.cornerSplit, UP);
27
+ const result = generateTubeVertexData(pathPointList, options) as Record<string, any>;
28
+ result.line = line;
29
+ result.position = new Float32Array(result.points);
30
+ result.indices = new Uint32Array(result.indices);
31
+ result.uv = new Float32Array(result.uv);
32
+ result.normal = new Float32Array(result.normal);
33
+ return result;
34
+ });
35
+ const result = merge(results) as TubesResult;
36
+ result.lines = lines;
37
+ return result;
38
+ }
39
+
40
+ // Vertex Data Generate Functions
41
+ // code copy from https://github.com/shawn0326/three.path/blob/master/src/PathGeometry.js
42
+ function generateTubeVertexData(pathPointList, options) {
43
+ const radius = Math.max(options.radius || 1, 0.00000001);
44
+ const progress = options.progress !== undefined ? options.progress : 1;
45
+ const radialSegments = Math.max(3, options.radialSegments || 8);
46
+ const startRad = options.startRad || 0;
47
+
48
+ const circum = radius * 2 * Math.PI;
49
+ const totalDistance = pathPointList.distance();
50
+ const progressDistance = progress * totalDistance;
51
+ if (progressDistance === 0) {
52
+ return null;
53
+ }
54
+
55
+ let count = 0;
56
+
57
+ // modify data
58
+ const points: number[] = [];
59
+ const normal: number[] = [];
60
+ const uv: number[] = [];
61
+ // const uv2 = [];
62
+ const indices: number[] = [];
63
+ let verticesCount = 0;
64
+
65
+ let pIndex = -1;
66
+ let nIndex = -1;
67
+ let uIndex = -1;
68
+ let iIndex = -1;
69
+ function addVertices(pathPoint, radius, radialSegments) {
70
+ const first = points.length === 0;
71
+ const uvDist = pathPoint.dist / circum;
72
+ // const uvDist2 = pathPoint.dist / totalDistance;
73
+
74
+ for (let i = 0; i <= radialSegments; i++) {
75
+ let r = i;
76
+ if (r === radialSegments) {
77
+ r = 0;
78
+ }
79
+ normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
80
+
81
+ const scale = radius * pathPoint.widthScale;
82
+ points[++pIndex] = pathPoint.pos.x + normalDir.x * scale;
83
+ points[++pIndex] = pathPoint.pos.y + normalDir.y * scale;
84
+ points[++pIndex] = pathPoint.pos.z + normalDir.z * scale;
85
+
86
+ normal[++nIndex] = normalDir.x;
87
+ normal[++nIndex] = normalDir.y;
88
+ normal[++nIndex] = normalDir.z;
89
+
90
+ uv[++uIndex] = uvDist;
91
+ uv[++uIndex] = i / radialSegments;
92
+
93
+ // uvs.push(uvDist, r / radialSegments);
94
+
95
+ // if (generateUv2) {
96
+ // uv2.push(uvDist2, r / radialSegments);
97
+ // }
98
+
99
+ verticesCount++;
100
+ }
101
+
102
+ if (!first) {
103
+ const begin1 = verticesCount - (radialSegments + 1) * 2;
104
+ const begin2 = verticesCount - (radialSegments + 1);
105
+
106
+ for (let i = 0; i < radialSegments; i++) {
107
+ indices[++iIndex] = begin2 + i;
108
+ indices[++iIndex] = begin1 + i;
109
+ indices[++iIndex] = begin1 + i + 1;
110
+ indices[++iIndex] = begin2 + i;
111
+ indices[++iIndex] = begin1 + i + 1;
112
+ indices[++iIndex] = begin2 + i + 1;
113
+ // index.push(
114
+ // begin2 + i,
115
+ // begin1 + i,
116
+ // begin1 + i + 1,
117
+ // begin2 + i,
118
+ // begin1 + i + 1,
119
+ // begin2 + i + 1
120
+ // );
121
+
122
+ count += 6;
123
+ }
124
+ }
125
+ }
126
+
127
+ if (progressDistance > 0) {
128
+ for (let i = 0; i < pathPointList.count; i++) {
129
+ const pathPoint = pathPointList.array[i];
130
+
131
+ if (pathPoint.dist > progressDistance) {
132
+ const prevPoint = pathPointList.array[i - 1];
133
+ const lastPoint = new PathPoint();
134
+
135
+ // linear lerp for progress
136
+ const alpha = (progressDistance - prevPoint.dist) / (pathPoint.dist - prevPoint.dist);
137
+ lastPoint.lerpPathPoints(prevPoint, pathPoint, alpha);
138
+
139
+ addVertices(lastPoint, radius, radialSegments);
140
+ break;
141
+ } else {
142
+ addVertices(pathPoint, radius, radialSegments);
143
+ }
144
+ }
145
+ }
146
+
147
+ return {
148
+ points,
149
+ normal,
150
+ uv,
151
+ // uv2,
152
+ indices,
153
+ count
154
+ };
155
+ }
package/src/type.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type PolylineType = Array<number[]>;
2
+ export type PolygonType = Array<Array<number[]>>;
3
+ export type ResultType = {
4
+ position: Float32Array;
5
+ normal: Float32Array;
6
+ uv: Float32Array;
7
+ indices: Uint32Array;
8
+ results?: Array<any>;
9
+ }
@@ -212,7 +212,7 @@ export function generateSideWallUV(uvs, vertices, indexA, indexB, indexC, indexD
212
212
  }
213
213
 
214
214
  export function line2Vectors(line) {
215
- const points = [];
215
+ const points: Vector3[] = [];
216
216
  for (let i = 0, len = line.length; i < len; i++) {
217
217
  const p = line[i];
218
218
  const [x, y, z] = p;
package/index.js DELETED
@@ -1,7 +0,0 @@
1
- import { extrudePolygons } from './src/polygon';
2
- import { extrudePolylines, expandLine, leftOnLine, extrudeSlopes } from './src/polyline';
3
- import { cylinder } from './src/cylinder';
4
- import { expandPaths } from './src/path';
5
- import { expandTubes } from './src/tube';
6
- import { plane } from './src/plane';
7
- export { extrudePolygons, extrudePolylines, extrudeSlopes, expandLine, leftOnLine, cylinder, expandPaths, expandTubes, plane };