poly-extrude 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/poly-extrude.js +1983 -10
- package/dist/poly-extrude.js.map +1 -1
- package/dist/poly-extrude.min.js +2 -2
- package/dist/poly-extrude.mjs +1983 -11
- package/index.js +2 -1
- package/package.json +1 -1
- package/readme.md +191 -36
- package/src/math/Curve.js +415 -0
- package/src/math/Interpolations.js +80 -0
- package/src/math/Matrix4.js +914 -0
- package/src/math/QuadraticBezierCurve3.js +76 -0
- package/src/math/Vector3.js +711 -0
- package/src/path/PathPoint.js +41 -0
- package/src/path/PathPointList.js +251 -0
- package/src/path.js +259 -0
- package/src/polyline.js +10 -9
@@ -0,0 +1,41 @@
|
|
1
|
+
/* eslint-disable no-tabs */
|
2
|
+
|
3
|
+
// code copy from https://github.com/shawn0326/three.path/blob/master/src/PathPoint.js
|
4
|
+
|
5
|
+
import { Vector3 } from '../math/Vector3';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* PathPoint
|
9
|
+
*/
|
10
|
+
class PathPoint {
|
11
|
+
constructor() {
|
12
|
+
this.pos = new Vector3();
|
13
|
+
this.dir = new Vector3();
|
14
|
+
this.right = new Vector3();
|
15
|
+
this.up = new Vector3(); // normal
|
16
|
+
this.dist = 0; // distance from start
|
17
|
+
this.widthScale = 1; // for corner
|
18
|
+
this.sharp = false; // marks as sharp corner
|
19
|
+
}
|
20
|
+
|
21
|
+
lerpPathPoints(p1, p2, alpha) {
|
22
|
+
this.pos.lerpVectors(p1.pos, p2.pos, alpha);
|
23
|
+
this.dir.lerpVectors(p1.dir, p2.dir, alpha);
|
24
|
+
this.up.lerpVectors(p1.up, p2.up, alpha);
|
25
|
+
this.right.lerpVectors(p1.right, p2.right, alpha);
|
26
|
+
this.dist = (p2.dist - p1.dist) * alpha + p1.dist;
|
27
|
+
this.widthScale = (p2.widthScale - p1.widthScale) * alpha + p1.widthScale;
|
28
|
+
}
|
29
|
+
|
30
|
+
copy(source) {
|
31
|
+
this.pos.copy(source.pos);
|
32
|
+
this.dir.copy(source.dir);
|
33
|
+
this.up.copy(source.up);
|
34
|
+
this.right.copy(source.right);
|
35
|
+
this.dist = source.dist;
|
36
|
+
this.widthScale = source.widthScale;
|
37
|
+
}
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
export { PathPoint };
|
@@ -0,0 +1,251 @@
|
|
1
|
+
/* eslint-disable no-tabs */
|
2
|
+
// code copy from https://github.com/shawn0326/three.path/blob/master/src/PathPointList.js
|
3
|
+
import { Matrix4 } from '../math/Matrix4.js';
|
4
|
+
import { QuadraticBezierCurve3 } from '../math/QuadraticBezierCurve3.js';
|
5
|
+
import { Vector3 } from '../math/Vector3.js';
|
6
|
+
import { PathPoint } from './PathPoint.js';
|
7
|
+
|
8
|
+
const helpVec3_1 = new Vector3();
|
9
|
+
const helpVec3_2 = new Vector3();
|
10
|
+
const helpVec3_3 = new Vector3();
|
11
|
+
const helpMat4 = new Matrix4();
|
12
|
+
const helpCurve = new QuadraticBezierCurve3();
|
13
|
+
|
14
|
+
function _getCornerBezierCurve(last, current, next, cornerRadius, firstCorner, out) {
|
15
|
+
const lastDir = helpVec3_1.subVectors(current, last);
|
16
|
+
const nextDir = helpVec3_2.subVectors(next, current);
|
17
|
+
|
18
|
+
const lastDirLength = lastDir.length();
|
19
|
+
const nextDirLength = nextDir.length();
|
20
|
+
|
21
|
+
lastDir.normalize();
|
22
|
+
nextDir.normalize();
|
23
|
+
|
24
|
+
// cornerRadius can not bigger then lineDistance / 2, auto fix this
|
25
|
+
const v0Dist = Math.min((firstCorner ? lastDirLength / 2 : lastDirLength) * 0.999999, cornerRadius);
|
26
|
+
out.v0.copy(current).sub(lastDir.multiplyScalar(v0Dist));
|
27
|
+
|
28
|
+
out.v1.copy(current);
|
29
|
+
|
30
|
+
const v2Dist = Math.min(nextDirLength / 2 * 0.999999, cornerRadius);
|
31
|
+
out.v2.copy(current).add(nextDir.multiplyScalar(v2Dist));
|
32
|
+
|
33
|
+
return out;
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* PathPointList
|
38
|
+
* input points to generate a PathPoint list
|
39
|
+
*/
|
40
|
+
class PathPointList {
|
41
|
+
|
42
|
+
constructor() {
|
43
|
+
this.array = []; // path point array
|
44
|
+
this.count = 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Set points
|
49
|
+
* @param {THREE.Vector3[]} points key points array
|
50
|
+
* @param {number} cornerRadius? the corner radius. set 0 to disable round corner. default is 0.1
|
51
|
+
* @param {number} cornerSplit? the corner split. default is 10.
|
52
|
+
* @param {number} up? force up. default is auto up (calculate by tangent).
|
53
|
+
* @param {boolean} close? close path. default is false.
|
54
|
+
*/
|
55
|
+
set(points, cornerRadius = 0.1, cornerSplit = 10, up = null, close = false) {
|
56
|
+
points = points.slice(0);
|
57
|
+
|
58
|
+
if (points.length < 2) {
|
59
|
+
console.warn('PathPointList: points length less than 2.');
|
60
|
+
this.count = 0;
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
// Auto close
|
65
|
+
if (close && !points[0].equals(points[points.length - 1])) {
|
66
|
+
points.push(new Vector3().copy(points[0]));
|
67
|
+
}
|
68
|
+
|
69
|
+
// Generate path point list
|
70
|
+
for (let i = 0, l = points.length; i < l; i++) {
|
71
|
+
if (i === 0) {
|
72
|
+
this._start(points[i], points[i + 1], up);
|
73
|
+
} else if (i === l - 1) {
|
74
|
+
if (close) {
|
75
|
+
// Connect end point and start point
|
76
|
+
this._corner(points[i], points[1], cornerRadius, cornerSplit, up);
|
77
|
+
|
78
|
+
// Fix start point
|
79
|
+
const dist = this.array[0].dist; // should not copy dist
|
80
|
+
this.array[0].copy(this.array[this.count - 1]);
|
81
|
+
this.array[0].dist = dist;
|
82
|
+
} else {
|
83
|
+
this._end(points[i]);
|
84
|
+
}
|
85
|
+
} else {
|
86
|
+
this._corner(points[i], points[i + 1], cornerRadius, cornerSplit, up);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Get distance of this path
|
93
|
+
* @return {number}
|
94
|
+
*/
|
95
|
+
distance() {
|
96
|
+
if (this.count > 0) {
|
97
|
+
return this.array[this.count - 1].dist;
|
98
|
+
}
|
99
|
+
return 0;
|
100
|
+
}
|
101
|
+
|
102
|
+
_getByIndex(index) {
|
103
|
+
if (!this.array[index]) {
|
104
|
+
this.array[index] = new PathPoint();
|
105
|
+
}
|
106
|
+
return this.array[index];
|
107
|
+
}
|
108
|
+
|
109
|
+
_start(current, next, up) {
|
110
|
+
this.count = 0;
|
111
|
+
|
112
|
+
const point = this._getByIndex(this.count);
|
113
|
+
|
114
|
+
point.pos.copy(current);
|
115
|
+
point.dir.subVectors(next, current);
|
116
|
+
|
117
|
+
// init start up dir
|
118
|
+
if (up) {
|
119
|
+
point.up.copy(up);
|
120
|
+
} else {
|
121
|
+
// select an initial normal vector perpendicular to the first tangent vector
|
122
|
+
let min = Number.MAX_VALUE;
|
123
|
+
const tx = Math.abs(point.dir.x);
|
124
|
+
const ty = Math.abs(point.dir.y);
|
125
|
+
const tz = Math.abs(point.dir.z);
|
126
|
+
if (tx < min) {
|
127
|
+
min = tx;
|
128
|
+
point.up.set(1, 0, 0);
|
129
|
+
}
|
130
|
+
if (ty < min) {
|
131
|
+
min = ty;
|
132
|
+
point.up.set(0, 1, 0);
|
133
|
+
}
|
134
|
+
if (tz < min) {
|
135
|
+
point.up.set(0, 0, 1);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
point.right.crossVectors(point.dir, point.up).normalize();
|
140
|
+
point.up.crossVectors(point.right, point.dir).normalize();
|
141
|
+
point.dist = 0;
|
142
|
+
point.widthScale = 1;
|
143
|
+
point.sharp = false;
|
144
|
+
|
145
|
+
point.dir.normalize();
|
146
|
+
|
147
|
+
this.count++;
|
148
|
+
}
|
149
|
+
|
150
|
+
_end(current) {
|
151
|
+
const lastPoint = this.array[this.count - 1];
|
152
|
+
const point = this._getByIndex(this.count);
|
153
|
+
|
154
|
+
point.pos.copy(current);
|
155
|
+
point.dir.subVectors(current, lastPoint.pos);
|
156
|
+
const dist = point.dir.length();
|
157
|
+
point.dir.normalize();
|
158
|
+
|
159
|
+
point.up.copy(lastPoint.up); // copy last up
|
160
|
+
|
161
|
+
const vec = helpVec3_1.crossVectors(lastPoint.dir, point.dir);
|
162
|
+
if (vec.length() > Number.EPSILON) {
|
163
|
+
vec.normalize();
|
164
|
+
const theta = Math.acos(Math.min(Math.max(lastPoint.dir.dot(point.dir), -1), 1)); // clamp for floating pt errors
|
165
|
+
point.up.applyMatrix4(helpMat4.makeRotationAxis(vec, theta));
|
166
|
+
}
|
167
|
+
|
168
|
+
point.right.crossVectors(point.dir, point.up).normalize();
|
169
|
+
|
170
|
+
point.dist = lastPoint.dist + dist;
|
171
|
+
point.widthScale = 1;
|
172
|
+
point.sharp = false;
|
173
|
+
|
174
|
+
this.count++;
|
175
|
+
}
|
176
|
+
|
177
|
+
_corner(current, next, cornerRadius, cornerSplit, up) {
|
178
|
+
if (cornerRadius > 0 && cornerSplit > 0) {
|
179
|
+
const lastPoint = this.array[this.count - 1];
|
180
|
+
const curve = _getCornerBezierCurve(lastPoint.pos, current, next, cornerRadius, (this.count - 1) === 0, helpCurve);
|
181
|
+
const samplerPoints = curve.getPoints(cornerSplit); // TODO optimize
|
182
|
+
|
183
|
+
for (let f = 0; f < cornerSplit; f++) {
|
184
|
+
this._sharpCorner(samplerPoints[f], samplerPoints[f + 1], up, f === 0 ? 1 : 0);
|
185
|
+
}
|
186
|
+
|
187
|
+
if (!samplerPoints[cornerSplit].equals(next)) {
|
188
|
+
this._sharpCorner(samplerPoints[cornerSplit], next, up, 2);
|
189
|
+
}
|
190
|
+
} else {
|
191
|
+
this._sharpCorner(current, next, up, 0, true);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
// dirType: 0 - use middle dir / 1 - use last dir / 2- use next dir
|
196
|
+
_sharpCorner(current, next, up, dirType = 0, sharp = false) {
|
197
|
+
const lastPoint = this.array[this.count - 1];
|
198
|
+
const point = this._getByIndex(this.count);
|
199
|
+
|
200
|
+
const lastDir = helpVec3_1.subVectors(current, lastPoint.pos);
|
201
|
+
const nextDir = helpVec3_2.subVectors(next, current);
|
202
|
+
|
203
|
+
const lastDirLength = lastDir.length();
|
204
|
+
|
205
|
+
lastDir.normalize();
|
206
|
+
nextDir.normalize();
|
207
|
+
|
208
|
+
point.pos.copy(current);
|
209
|
+
|
210
|
+
if (dirType === 1) {
|
211
|
+
point.dir.copy(lastDir);
|
212
|
+
} else if (dirType === 2) {
|
213
|
+
point.dir.copy(nextDir);
|
214
|
+
} else {
|
215
|
+
point.dir.addVectors(lastDir, nextDir);
|
216
|
+
point.dir.normalize();
|
217
|
+
}
|
218
|
+
|
219
|
+
if (up) {
|
220
|
+
if (point.dir.dot(up) === 1) {
|
221
|
+
point.right.crossVectors(nextDir, up).normalize();
|
222
|
+
} else {
|
223
|
+
point.right.crossVectors(point.dir, up).normalize();
|
224
|
+
}
|
225
|
+
|
226
|
+
point.up.crossVectors(point.right, point.dir).normalize();
|
227
|
+
} else {
|
228
|
+
point.up.copy(lastPoint.up);
|
229
|
+
|
230
|
+
const vec = helpVec3_3.crossVectors(lastPoint.dir, point.dir);
|
231
|
+
if (vec.length() > Number.EPSILON) {
|
232
|
+
vec.normalize();
|
233
|
+
const theta = Math.acos(Math.min(Math.max(lastPoint.dir.dot(point.dir), -1), 1)); // clamp for floating pt errors
|
234
|
+
point.up.applyMatrix4(helpMat4.makeRotationAxis(vec, theta));
|
235
|
+
}
|
236
|
+
|
237
|
+
point.right.crossVectors(point.dir, point.up).normalize();
|
238
|
+
}
|
239
|
+
|
240
|
+
point.dist = lastPoint.dist + lastDirLength;
|
241
|
+
|
242
|
+
const _cos = lastDir.dot(nextDir);
|
243
|
+
point.widthScale = Math.min(1 / Math.sqrt((1 + _cos) / 2), 1.415) || 1;
|
244
|
+
point.sharp = (Math.abs(_cos - 1) > 0.05) && sharp;
|
245
|
+
|
246
|
+
this.count++;
|
247
|
+
}
|
248
|
+
|
249
|
+
}
|
250
|
+
|
251
|
+
export { PathPointList };
|
package/src/path.js
ADDED
@@ -0,0 +1,259 @@
|
|
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 expandPaths(lines, options) {
|
8
|
+
options = Object.assign({}, { lineWidth: 1, cornerRadius: 0, cornerSplit: 10 }, 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 = generatePathVertexData(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 generatePathVertexData(pathPointList, options) {
|
32
|
+
const width = options.lineWidth || 0.1;
|
33
|
+
const progress = 1;
|
34
|
+
const side = 'both';
|
35
|
+
|
36
|
+
const halfWidth = width / 2;
|
37
|
+
const sideWidth = (side !== 'both' ? width / 2 : width);
|
38
|
+
const totalDistance = pathPointList.distance();
|
39
|
+
const progressDistance = progress * totalDistance;
|
40
|
+
if (totalDistance === 0) {
|
41
|
+
return null;
|
42
|
+
}
|
43
|
+
|
44
|
+
const sharpUvOffset = halfWidth / sideWidth;
|
45
|
+
// const sharpUvOffset2 = halfWidth / totalDistance;
|
46
|
+
|
47
|
+
let count = 0;
|
48
|
+
|
49
|
+
// modify data
|
50
|
+
const position = [];
|
51
|
+
const normal = [];
|
52
|
+
const uv = [];
|
53
|
+
const indices = [];
|
54
|
+
let verticesCount = 0;
|
55
|
+
|
56
|
+
const right = new Vector3();
|
57
|
+
const left = new Vector3();
|
58
|
+
|
59
|
+
// for sharp corners
|
60
|
+
const leftOffset = new Vector3();
|
61
|
+
const rightOffset = new Vector3();
|
62
|
+
const tempPoint1 = new Vector3();
|
63
|
+
const tempPoint2 = new Vector3();
|
64
|
+
|
65
|
+
function addVertices(pathPoint) {
|
66
|
+
const first = position.length === 0;
|
67
|
+
const sharpCorner = pathPoint.sharp && !first;
|
68
|
+
|
69
|
+
const uvDist = pathPoint.dist / sideWidth;
|
70
|
+
// const uvDist2 = pathPoint.dist / totalDistance;
|
71
|
+
|
72
|
+
const dir = pathPoint.dir;
|
73
|
+
const up = pathPoint.up;
|
74
|
+
const _right = pathPoint.right;
|
75
|
+
|
76
|
+
if (side !== 'left') {
|
77
|
+
right.copy(_right).multiplyScalar(halfWidth * pathPoint.widthScale);
|
78
|
+
} else {
|
79
|
+
right.set(0, 0, 0);
|
80
|
+
}
|
81
|
+
|
82
|
+
if (side !== 'right') {
|
83
|
+
left.copy(_right).multiplyScalar(-halfWidth * pathPoint.widthScale);
|
84
|
+
} else {
|
85
|
+
left.set(0, 0, 0);
|
86
|
+
}
|
87
|
+
|
88
|
+
right.add(pathPoint.pos);
|
89
|
+
left.add(pathPoint.pos);
|
90
|
+
|
91
|
+
if (sharpCorner) {
|
92
|
+
leftOffset.fromArray(position, position.length - 6).sub(left);
|
93
|
+
rightOffset.fromArray(position, position.length - 3).sub(right);
|
94
|
+
|
95
|
+
const leftDist = leftOffset.length();
|
96
|
+
const rightDist = rightOffset.length();
|
97
|
+
|
98
|
+
const sideOffset = leftDist - rightDist;
|
99
|
+
let longerOffset, longEdge;
|
100
|
+
|
101
|
+
if (sideOffset > 0) {
|
102
|
+
longerOffset = leftOffset;
|
103
|
+
longEdge = left;
|
104
|
+
} else {
|
105
|
+
longerOffset = rightOffset;
|
106
|
+
longEdge = right;
|
107
|
+
}
|
108
|
+
|
109
|
+
tempPoint1.copy(longerOffset).setLength(Math.abs(sideOffset)).add(longEdge);
|
110
|
+
|
111
|
+
// eslint-disable-next-line prefer-const
|
112
|
+
let _cos = tempPoint2.copy(longEdge).sub(tempPoint1).normalize().dot(dir);
|
113
|
+
// eslint-disable-next-line prefer-const
|
114
|
+
let _len = tempPoint2.copy(longEdge).sub(tempPoint1).length();
|
115
|
+
// eslint-disable-next-line prefer-const
|
116
|
+
let _dist = _cos * _len * 2;
|
117
|
+
|
118
|
+
tempPoint2.copy(dir).setLength(_dist).add(tempPoint1);
|
119
|
+
|
120
|
+
if (sideOffset > 0) {
|
121
|
+
position.push(
|
122
|
+
tempPoint1.x, tempPoint1.y, tempPoint1.z, // 6
|
123
|
+
right.x, right.y, right.z, // 5
|
124
|
+
left.x, left.y, left.z, // 4
|
125
|
+
right.x, right.y, right.z, // 3
|
126
|
+
tempPoint2.x, tempPoint2.y, tempPoint2.z, // 2
|
127
|
+
right.x, right.y, right.z // 1
|
128
|
+
);
|
129
|
+
|
130
|
+
verticesCount += 6;
|
131
|
+
|
132
|
+
indices.push(
|
133
|
+
verticesCount - 6, verticesCount - 8, verticesCount - 7,
|
134
|
+
verticesCount - 6, verticesCount - 7, verticesCount - 5,
|
135
|
+
|
136
|
+
verticesCount - 4, verticesCount - 6, verticesCount - 5,
|
137
|
+
verticesCount - 2, verticesCount - 4, verticesCount - 1
|
138
|
+
);
|
139
|
+
|
140
|
+
count += 12;
|
141
|
+
} else {
|
142
|
+
position.push(
|
143
|
+
left.x, left.y, left.z, // 6
|
144
|
+
tempPoint1.x, tempPoint1.y, tempPoint1.z, // 5
|
145
|
+
left.x, left.y, left.z, // 4
|
146
|
+
right.x, right.y, right.z, // 3
|
147
|
+
left.x, left.y, left.z, // 2
|
148
|
+
tempPoint2.x, tempPoint2.y, tempPoint2.z // 1
|
149
|
+
);
|
150
|
+
|
151
|
+
verticesCount += 6;
|
152
|
+
|
153
|
+
indices.push(
|
154
|
+
verticesCount - 6, verticesCount - 8, verticesCount - 7,
|
155
|
+
verticesCount - 6, verticesCount - 7, verticesCount - 5,
|
156
|
+
|
157
|
+
verticesCount - 6, verticesCount - 5, verticesCount - 3,
|
158
|
+
verticesCount - 2, verticesCount - 3, verticesCount - 1
|
159
|
+
);
|
160
|
+
|
161
|
+
count += 12;
|
162
|
+
}
|
163
|
+
|
164
|
+
normal.push(
|
165
|
+
up.x, up.y, up.z,
|
166
|
+
up.x, up.y, up.z,
|
167
|
+
up.x, up.y, up.z,
|
168
|
+
up.x, up.y, up.z,
|
169
|
+
up.x, up.y, up.z,
|
170
|
+
up.x, up.y, up.z
|
171
|
+
);
|
172
|
+
|
173
|
+
uv.push(
|
174
|
+
uvDist - sharpUvOffset, 0,
|
175
|
+
uvDist - sharpUvOffset, 1,
|
176
|
+
uvDist, 0,
|
177
|
+
uvDist, 1,
|
178
|
+
uvDist + sharpUvOffset, 0,
|
179
|
+
uvDist + sharpUvOffset, 1
|
180
|
+
);
|
181
|
+
|
182
|
+
// if (generateUv2) {
|
183
|
+
// uv2.push(
|
184
|
+
// uvDist2 - sharpUvOffset2, 0,
|
185
|
+
// uvDist2 - sharpUvOffset2, 1,
|
186
|
+
// uvDist2, 0,
|
187
|
+
// uvDist2, 1,
|
188
|
+
// uvDist2 + sharpUvOffset2, 0,
|
189
|
+
// uvDist2 + sharpUvOffset2, 1
|
190
|
+
// );
|
191
|
+
// }
|
192
|
+
} else {
|
193
|
+
position.push(
|
194
|
+
left.x, left.y, left.z,
|
195
|
+
right.x, right.y, right.z
|
196
|
+
);
|
197
|
+
|
198
|
+
normal.push(
|
199
|
+
up.x, up.y, up.z,
|
200
|
+
up.x, up.y, up.z
|
201
|
+
);
|
202
|
+
|
203
|
+
uv.push(
|
204
|
+
uvDist, 0,
|
205
|
+
uvDist, 1
|
206
|
+
);
|
207
|
+
|
208
|
+
// if (generateUv2) {
|
209
|
+
// uv2.push(
|
210
|
+
// uvDist2, 0,
|
211
|
+
// uvDist2, 1
|
212
|
+
// );
|
213
|
+
// }
|
214
|
+
|
215
|
+
verticesCount += 2;
|
216
|
+
|
217
|
+
if (!first) {
|
218
|
+
indices.push(
|
219
|
+
verticesCount - 2, verticesCount - 4, verticesCount - 3,
|
220
|
+
verticesCount - 2, verticesCount - 3, verticesCount - 1
|
221
|
+
);
|
222
|
+
|
223
|
+
count += 6;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
let lastPoint;
|
229
|
+
|
230
|
+
if (progressDistance > 0) {
|
231
|
+
for (let i = 0; i < pathPointList.count; i++) {
|
232
|
+
const pathPoint = pathPointList.array[i];
|
233
|
+
|
234
|
+
if (pathPoint.dist > progressDistance) {
|
235
|
+
const prevPoint = pathPointList.array[i - 1];
|
236
|
+
lastPoint = new PathPoint();
|
237
|
+
|
238
|
+
// linear lerp for progress
|
239
|
+
const alpha = (progressDistance - prevPoint.dist) / (pathPoint.dist - prevPoint.dist);
|
240
|
+
lastPoint.lerpPathPoints(prevPoint, pathPoint, alpha);
|
241
|
+
|
242
|
+
addVertices(lastPoint);
|
243
|
+
break;
|
244
|
+
} else {
|
245
|
+
addVertices(pathPoint);
|
246
|
+
}
|
247
|
+
}
|
248
|
+
} else {
|
249
|
+
lastPoint = pathPointList.array[0];
|
250
|
+
}
|
251
|
+
|
252
|
+
return {
|
253
|
+
points: position,
|
254
|
+
normal,
|
255
|
+
uvs: uv,
|
256
|
+
index: indices,
|
257
|
+
count
|
258
|
+
};
|
259
|
+
}
|
package/src/polyline.js
CHANGED
@@ -26,29 +26,29 @@ function generateTopAndBottom(result, options) {
|
|
26
26
|
while (i < len) {
|
27
27
|
// top left
|
28
28
|
const idx0 = i * 3;
|
29
|
-
const [x1, y1] = leftPoints[i];
|
29
|
+
const [x1, y1, z1] = leftPoints[i];
|
30
30
|
points[idx0] = x1;
|
31
31
|
points[idx0 + 1] = y1;
|
32
|
-
points[idx0 + 2] = z;
|
32
|
+
points[idx0 + 2] = z + z1;
|
33
33
|
|
34
34
|
// top right
|
35
|
-
const [x2, y2] = rightPoints[i];
|
35
|
+
const [x2, y2, z2] = rightPoints[i];
|
36
36
|
const idx1 = len * 3 + idx0;
|
37
37
|
points[idx1] = x2;
|
38
38
|
points[idx1 + 1] = y2;
|
39
|
-
points[idx1 + 2] = z;
|
39
|
+
points[idx1 + 2] = z + z2;
|
40
40
|
|
41
41
|
// bottom left
|
42
42
|
const idx2 = (len * 2) * 3 + idx0;
|
43
43
|
points[idx2] = x1;
|
44
44
|
points[idx2 + 1] = y1;
|
45
|
-
points[idx2 + 2] =
|
45
|
+
points[idx2 + 2] = z1;
|
46
46
|
|
47
47
|
// bottom right
|
48
48
|
const idx3 = (len * 2) * 3 + len * 3 + idx0;
|
49
49
|
points[idx3] = x2;
|
50
50
|
points[idx3 + 1] = y2;
|
51
|
-
points[idx3 + 2] =
|
51
|
+
points[idx3 + 2] = z2;
|
52
52
|
|
53
53
|
i++;
|
54
54
|
}
|
@@ -88,7 +88,7 @@ function generateSides(result, options) {
|
|
88
88
|
|
89
89
|
function addOneSideIndex(v1, v2) {
|
90
90
|
const idx = points.length / 3;
|
91
|
-
points.push(v1[0], v1[1], z, v2[0], v2[1], z, v1[0], v1[1],
|
91
|
+
points.push(v1[0], v1[1], z + v1[2], v2[0], v2[1], z + v2[2], v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]);
|
92
92
|
const a = idx + 2, b = idx + 3, c = idx, d = idx + 1;
|
93
93
|
index.push(a, c, b, c, d, b);
|
94
94
|
generateSideWallUV(uvs, points, a, b, c, d);
|
@@ -180,11 +180,12 @@ export function expandLine(line, options) {
|
|
180
180
|
|
181
181
|
function calOffsetPoint(rad, radius, p) {
|
182
182
|
const [x, y] = p;
|
183
|
+
const z = p[2] || 0;
|
183
184
|
const x1 = Math.cos(rad) * radius, y1 = Math.sin(rad) * radius;
|
184
|
-
const p1 = [x + x1, y + y1];
|
185
|
+
const p1 = [x + x1, y + y1, z];
|
185
186
|
const rad1 = rad += Math.PI;
|
186
187
|
const x2 = Math.cos(rad1) * radius, y2 = Math.sin(rad1) * radius;
|
187
|
-
const p2 = [x + x2, y + y2];
|
188
|
+
const p2 = [x + x2, y + y2, z];
|
188
189
|
return [p1, p2];
|
189
190
|
}
|
190
191
|
|