poly-extrude 0.5.0 → 0.7.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/poly-extrude.js +1183 -42
- package/dist/poly-extrude.js.map +1 -1
- package/dist/poly-extrude.min.js +4 -2
- package/dist/poly-extrude.mjs +1183 -43
- package/index.js +2 -1
- package/package.json +1 -1
- package/readme.md +172 -170
- package/src/math/Quaternion.js +688 -0
- package/src/math/Vector3.js +21 -17
- package/src/polyline.js +43 -3
- package/src/tube.js +146 -0
package/src/math/Vector3.js
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
// import * as MathUtils from './MathUtils.js';
|
2
2
|
// code copy from https://github.com/mrdoob/three.js/blob/dev/src/math/Vector3.js
|
3
3
|
|
4
|
+
import { Quaternion } from './Quaternion';
|
5
|
+
|
6
|
+
const _quaternion = new Quaternion();
|
7
|
+
|
4
8
|
class Vector3 {
|
5
9
|
|
6
10
|
constructor(x = 0, y = 0, z = 0) {
|
@@ -206,11 +210,11 @@ class Vector3 {
|
|
206
210
|
|
207
211
|
// }
|
208
212
|
|
209
|
-
|
213
|
+
applyAxisAngle(axis, angle) {
|
210
214
|
|
211
|
-
|
215
|
+
return this.applyQuaternion(_quaternion.setFromAxisAngle(axis, angle));
|
212
216
|
|
213
|
-
|
217
|
+
}
|
214
218
|
|
215
219
|
// applyMatrix3(m) {
|
216
220
|
|
@@ -246,27 +250,27 @@ class Vector3 {
|
|
246
250
|
|
247
251
|
}
|
248
252
|
|
249
|
-
|
253
|
+
applyQuaternion(q) {
|
250
254
|
|
251
|
-
|
252
|
-
|
255
|
+
const x = this.x, y = this.y, z = this.z;
|
256
|
+
const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
253
257
|
|
254
|
-
|
258
|
+
// calculate quat * vector
|
255
259
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
+
const ix = qw * x + qy * z - qz * y;
|
261
|
+
const iy = qw * y + qz * x - qx * z;
|
262
|
+
const iz = qw * z + qx * y - qy * x;
|
263
|
+
const iw = -qx * x - qy * y - qz * z;
|
260
264
|
|
261
|
-
|
265
|
+
// calculate result * inverse quat
|
262
266
|
|
263
|
-
|
264
|
-
|
265
|
-
|
267
|
+
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
268
|
+
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
269
|
+
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
266
270
|
|
267
|
-
|
271
|
+
return this;
|
268
272
|
|
269
|
-
|
273
|
+
}
|
270
274
|
|
271
275
|
// project(camera) {
|
272
276
|
|
package/src/polyline.js
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
import { degToRad, generateNormal, generateSideWallUV, merge, radToDeg } from './util';
|
2
2
|
|
3
|
+
function checkOptions(options) {
|
4
|
+
options.lineWidth = Math.max(0, options.lineWidth);
|
5
|
+
options.depth = Math.max(0, options.depth);
|
6
|
+
options.sideDepth = Math.max(0, options.sideDepth);
|
7
|
+
}
|
8
|
+
|
3
9
|
export function extrudePolylines(lines, options) {
|
4
|
-
options = Object.assign({}, { depth: 2, lineWidth: 1 }, options);
|
10
|
+
options = Object.assign({}, { depth: 2, lineWidth: 1, bottomStickGround: false }, options);
|
11
|
+
checkOptions(options);
|
5
12
|
const results = lines.map(line => {
|
6
13
|
const result = expandLine(line, options);
|
7
14
|
result.line = line;
|
@@ -19,7 +26,8 @@ export function extrudePolylines(lines, options) {
|
|
19
26
|
}
|
20
27
|
|
21
28
|
export function extrudeSlopes(lines, options) {
|
22
|
-
options = Object.assign({}, { depth: 2, lineWidth: 1, side: 'left', sideDepth: 0 }, options);
|
29
|
+
options = Object.assign({}, { depth: 2, lineWidth: 1, side: 'left', sideDepth: 0, bottomStickGround: false }, options);
|
30
|
+
checkOptions(options);
|
23
31
|
const { depth, side, sideDepth } = options;
|
24
32
|
const results = lines.map(line => {
|
25
33
|
const tempResult = expandLine(line, options);
|
@@ -54,6 +62,7 @@ export function extrudeSlopes(lines, options) {
|
|
54
62
|
}
|
55
63
|
|
56
64
|
function generateTopAndBottom(result, options) {
|
65
|
+
const bottomStickGround = options.bottomStickGround;
|
57
66
|
const z = options.depth;
|
58
67
|
const depths = result.depths;
|
59
68
|
let lz = z, rz = z;
|
@@ -84,12 +93,18 @@ function generateTopAndBottom(result, options) {
|
|
84
93
|
points[idx2] = x1;
|
85
94
|
points[idx2 + 1] = y1;
|
86
95
|
points[idx2 + 2] = z1;
|
96
|
+
if (bottomStickGround) {
|
97
|
+
points[idx2 + 2] = 0;
|
98
|
+
}
|
87
99
|
|
88
100
|
// bottom right
|
89
101
|
const idx3 = (len * 2) * 3 + len * 3 + idx0;
|
90
102
|
points[idx3] = x2;
|
91
103
|
points[idx3 + 1] = y2;
|
92
104
|
points[idx3 + 2] = z2;
|
105
|
+
if (bottomStickGround) {
|
106
|
+
points[idx3 + 2] = 0;
|
107
|
+
}
|
93
108
|
|
94
109
|
i++;
|
95
110
|
}
|
@@ -134,12 +149,37 @@ function generateTopAndBottom(result, options) {
|
|
134
149
|
function generateSides(result, options) {
|
135
150
|
const { points, index, leftPoints, rightPoints, uvs } = result;
|
136
151
|
const z = options.depth;
|
152
|
+
const bottomStickGround = options.bottomStickGround;
|
137
153
|
const rings = [leftPoints, rightPoints];
|
138
154
|
const depthsEnable = result.depths;
|
139
155
|
|
140
156
|
function addOneSideIndex(v1, v2) {
|
141
157
|
const idx = points.length / 3;
|
142
|
-
|
158
|
+
let pIndex = points.length - 1;
|
159
|
+
|
160
|
+
// top
|
161
|
+
points[++pIndex] = v1[0];
|
162
|
+
points[++pIndex] = v1[1];
|
163
|
+
points[++pIndex] = (depthsEnable ? v1.depth : z) + v1[2];
|
164
|
+
|
165
|
+
points[++pIndex] = v2[0];
|
166
|
+
points[++pIndex] = v2[1];
|
167
|
+
points[++pIndex] = (depthsEnable ? v2.depth : z) + v2[2];
|
168
|
+
|
169
|
+
// points.push(v1[0], v1[1], (depthsEnable ? v1.depth : z) + v1[2], v2[0], v2[1], (depthsEnable ? v2.depth : z) + v2[2]);
|
170
|
+
|
171
|
+
// bottom
|
172
|
+
|
173
|
+
points[++pIndex] = v1[0];
|
174
|
+
points[++pIndex] = v1[1];
|
175
|
+
points[++pIndex] = bottomStickGround ? 0 : v1[2];
|
176
|
+
|
177
|
+
points[++pIndex] = v2[0];
|
178
|
+
points[++pIndex] = v2[1];
|
179
|
+
points[++pIndex] = bottomStickGround ? 0 : v2[2];
|
180
|
+
|
181
|
+
// points.push(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]);
|
182
|
+
|
143
183
|
const a = idx + 2, b = idx + 3, c = idx, d = idx + 1;
|
144
184
|
index.push(a, c, b, c, d, b);
|
145
185
|
generateSideWallUV(uvs, points, a, b, c, d);
|
package/src/tube.js
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
import { Vector3 } from './math/Vector3';
|
2
|
+
import { PathPoint } from './path/PathPoint';
|
3
|
+
import { PathPointList } from './path/PathPointList';
|
4
|
+
import { merge } from './util';
|
5
|
+
const UP = new Vector3(0, 0, 1);
|
6
|
+
|
7
|
+
export function expandTubes(lines, options) {
|
8
|
+
options = Object.assign({}, { radius: 1, cornerSplit: 0, radialSegments: 8, startRad: -Math.PI / 4 }, options);
|
9
|
+
const results = lines.map(line => {
|
10
|
+
const points = line.map(p => {
|
11
|
+
const [x, y, z] = p;
|
12
|
+
return new Vector3(x, y, z || 0);
|
13
|
+
});
|
14
|
+
const pathPointList = new PathPointList();
|
15
|
+
pathPointList.set(points, options.cornerRadius, options.cornerSplit, UP);
|
16
|
+
const result = generateTubeVertexData(pathPointList, options);
|
17
|
+
result.line = line;
|
18
|
+
result.position = new Float32Array(result.points);
|
19
|
+
result.indices = new Uint32Array(result.index);
|
20
|
+
result.uv = new Float32Array(result.uvs);
|
21
|
+
result.normal = new Float32Array(result.normal);
|
22
|
+
return result;
|
23
|
+
});
|
24
|
+
const result = merge(results);
|
25
|
+
result.lines = lines;
|
26
|
+
return result;
|
27
|
+
}
|
28
|
+
|
29
|
+
// Vertex Data Generate Functions
|
30
|
+
// code copy from https://github.com/shawn0326/three.path/blob/master/src/PathGeometry.js
|
31
|
+
function generateTubeVertexData(pathPointList, options) {
|
32
|
+
const radius = Math.max(options.radius || 1, 0.00000001);
|
33
|
+
const progress = options.progress !== undefined ? options.progress : 1;
|
34
|
+
const radialSegments = Math.max(3, options.radialSegments || 8);
|
35
|
+
const startRad = options.startRad || 0;
|
36
|
+
|
37
|
+
const circum = radius * 2 * Math.PI;
|
38
|
+
const totalDistance = pathPointList.distance();
|
39
|
+
const progressDistance = progress * totalDistance;
|
40
|
+
if (progressDistance === 0) {
|
41
|
+
return null;
|
42
|
+
}
|
43
|
+
|
44
|
+
let count = 0;
|
45
|
+
|
46
|
+
// modify data
|
47
|
+
const points = [];
|
48
|
+
const normal = [];
|
49
|
+
const uvs = [];
|
50
|
+
// const uv2 = [];
|
51
|
+
const index = [];
|
52
|
+
let verticesCount = 0;
|
53
|
+
|
54
|
+
const normalDir = new Vector3();
|
55
|
+
|
56
|
+
let pIndex = -1;
|
57
|
+
let nIndex = -1;
|
58
|
+
let uIndex = -1;
|
59
|
+
let iIndex = -1;
|
60
|
+
function addVertices(pathPoint, radius, radialSegments) {
|
61
|
+
const first = points.length === 0;
|
62
|
+
const uvDist = pathPoint.dist / circum;
|
63
|
+
// const uvDist2 = pathPoint.dist / totalDistance;
|
64
|
+
|
65
|
+
for (let i = 0; i <= radialSegments; i++) {
|
66
|
+
let r = i;
|
67
|
+
if (r === radialSegments) {
|
68
|
+
r = 0;
|
69
|
+
}
|
70
|
+
normalDir.copy(pathPoint.up).applyAxisAngle(pathPoint.dir, startRad + Math.PI * 2 * r / radialSegments).normalize();
|
71
|
+
|
72
|
+
const scale = radius * pathPoint.widthScale;
|
73
|
+
points[++pIndex] = pathPoint.pos.x + normalDir.x * scale;
|
74
|
+
points[++pIndex] = pathPoint.pos.y + normalDir.y * scale;
|
75
|
+
points[++pIndex] = pathPoint.pos.z + normalDir.z * scale;
|
76
|
+
|
77
|
+
normal[++nIndex] = normalDir.x;
|
78
|
+
normal[++nIndex] = normalDir.y;
|
79
|
+
normal[++nIndex] = normalDir.z;
|
80
|
+
|
81
|
+
uvs[++uIndex] = uvDist;
|
82
|
+
uvs[++uIndex] = i / radialSegments;
|
83
|
+
|
84
|
+
// uvs.push(uvDist, r / radialSegments);
|
85
|
+
|
86
|
+
// if (generateUv2) {
|
87
|
+
// uv2.push(uvDist2, r / radialSegments);
|
88
|
+
// }
|
89
|
+
|
90
|
+
verticesCount++;
|
91
|
+
}
|
92
|
+
|
93
|
+
if (!first) {
|
94
|
+
const begin1 = verticesCount - (radialSegments + 1) * 2;
|
95
|
+
const begin2 = verticesCount - (radialSegments + 1);
|
96
|
+
|
97
|
+
for (let i = 0; i < radialSegments; i++) {
|
98
|
+
index[++iIndex] = begin2 + i;
|
99
|
+
index[++iIndex] = begin1 + i;
|
100
|
+
index[++iIndex] = begin1 + i + 1;
|
101
|
+
index[++iIndex] = begin2 + i;
|
102
|
+
index[++iIndex] = begin1 + i + 1;
|
103
|
+
index[++iIndex] = begin2 + i + 1;
|
104
|
+
// index.push(
|
105
|
+
// begin2 + i,
|
106
|
+
// begin1 + i,
|
107
|
+
// begin1 + i + 1,
|
108
|
+
// begin2 + i,
|
109
|
+
// begin1 + i + 1,
|
110
|
+
// begin2 + i + 1
|
111
|
+
// );
|
112
|
+
|
113
|
+
count += 6;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
if (progressDistance > 0) {
|
119
|
+
for (let i = 0; i < pathPointList.count; i++) {
|
120
|
+
const pathPoint = pathPointList.array[i];
|
121
|
+
|
122
|
+
if (pathPoint.dist > progressDistance) {
|
123
|
+
const prevPoint = pathPointList.array[i - 1];
|
124
|
+
const lastPoint = new PathPoint();
|
125
|
+
|
126
|
+
// linear lerp for progress
|
127
|
+
const alpha = (progressDistance - prevPoint.dist) / (pathPoint.dist - prevPoint.dist);
|
128
|
+
lastPoint.lerpPathPoints(prevPoint, pathPoint, alpha);
|
129
|
+
|
130
|
+
addVertices(lastPoint, radius, radialSegments);
|
131
|
+
break;
|
132
|
+
} else {
|
133
|
+
addVertices(pathPoint, radius, radialSegments);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
return {
|
139
|
+
points,
|
140
|
+
normal,
|
141
|
+
uvs,
|
142
|
+
// uv2,
|
143
|
+
index,
|
144
|
+
count
|
145
|
+
};
|
146
|
+
}
|