zincjs 3.0.0 → 3.0.2
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/README.md +27 -22
- package/build/zinc.js +2 -2
- package/build/zinc.js.map +1 -1
- package/package.json +4 -1
- package/src/controls.js +1332 -1241
- package/src/geometryCSG.js +111 -115
- package/src/glyphsetCSG.js +51 -55
- package/src/loaders/GLTFToZincJSLoader.js +31 -33
- package/src/loaders/JSONLoader.js +339 -449
- package/src/loaders/OBJLoader.js +654 -851
- package/src/loaders/STLLoader.js +271 -329
- package/src/loaders/niftiReader.js +90 -59
- package/src/loaders/primitivesLoader.js +55 -52
- package/src/minimap.js +63 -43
- package/src/primitives/geometry.js +40 -44
- package/src/primitives/glyph.js +16 -19
- package/src/primitives/glyphset.js +229 -185
- package/src/primitives/label.js +29 -31
- package/src/primitives/lines.js +20 -20
- package/src/primitives/lines2.js +33 -39
- package/src/primitives/lod.js +43 -43
- package/src/primitives/marker.js +31 -32
- package/src/primitives/markerCluster.js +32 -35
- package/src/primitives/pointset.js +86 -83
- package/src/primitives/texturePrimitive.js +9 -10
- package/src/primitives/textureSlides.js +84 -97
- package/src/primitives/textureVolume.js +46 -49
- package/src/primitives/tubeLines.js +108 -108
- package/src/primitives/zincObject.js +176 -184
- package/src/region.js +145 -155
- package/src/renderRequests.js +3 -3
- package/src/renderer.js +649 -629
- package/src/scene.js +502 -430
- package/src/sceneExporter.js +22 -17
- package/src/sceneLoader.js +542 -296
- package/src/shaders/rgbVolumeRender.js +11 -18
- package/src/shaders/textureArray.js +5 -12
- package/src/shaders/textureSlide.js +10 -17
- package/src/shaders/volumeRender.js +11 -18
- package/src/shaders/volumeRender_old.js +11 -18
- package/src/shaders/volumeTexture.js +7 -14
- package/src/textSprite.js +23 -19
- package/src/texture/texture.js +14 -15
- package/src/texture/textureArray.js +14 -16
- package/src/three/InstancedPoints.js +2 -9
- package/src/three/Loader.js +334 -315
- package/src/three/line/Line.js +165 -215
- package/src/three/line/LineSegments.js +40 -55
- package/src/three/line/LineSegments2.js +322 -366
- package/src/three/line/LineSegmentsGeometry.js +239 -280
- package/src/three-js-csg.js +260 -252
- package/src/tsl/glyphRenderMaterial.js +12 -3
- package/src/tsl/glyphTransform.js +51 -29
- package/src/tsl/textureSlides.js +23 -24
- package/src/utilities.js +309 -371
- package/src/videoHandler.js +76 -83
- package/src/workers/geometryCSG.worker.js +33 -36
- package/src/workers/geometryCSGInternal.js +39 -44
- package/src/zinc.js +4 -7
- package/vite.config.js +7 -7
package/src/three-js-csg.js
CHANGED
|
@@ -5,385 +5,398 @@ var ThreeBSP,
|
|
|
5
5
|
BACK = 2,
|
|
6
6
|
SPANNING = 3;
|
|
7
7
|
|
|
8
|
-
const ThreeBSPWrapper = function(
|
|
9
|
-
var ThreeBSP = function(
|
|
8
|
+
const ThreeBSPWrapper = function (THREE) {
|
|
9
|
+
var ThreeBSP = function (geometry) {
|
|
10
10
|
// Convert THREE.Geometry to ThreeBSP
|
|
11
|
-
var i,
|
|
12
|
-
|
|
11
|
+
var i,
|
|
12
|
+
_length_i,
|
|
13
|
+
face,
|
|
14
|
+
vertex,
|
|
15
|
+
faceVertexUvs,
|
|
16
|
+
uvs,
|
|
13
17
|
polygon,
|
|
14
18
|
polygons = [],
|
|
15
19
|
tree;
|
|
16
20
|
|
|
17
|
-
if (geometry.isBufferGeometry)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} else if ( geometry.isMesh ) {
|
|
21
|
+
if (geometry.isBufferGeometry) geometry = new THREE.Geometry().fromBufferGeometry(geometry);
|
|
22
|
+
if (geometry instanceof THREE.Geometry) {
|
|
23
|
+
this.matrix = new THREE.Matrix4();
|
|
24
|
+
} else if (geometry.isMesh) {
|
|
22
25
|
// #todo: add hierarchy support
|
|
23
26
|
geometry.updateMatrix();
|
|
24
27
|
this.matrix = geometry.matrix.clone();
|
|
25
28
|
geometry = geometry.geometry;
|
|
26
|
-
if (geometry.isBufferGeometry)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} else if ( geometry instanceof ThreeBSP.Node ) {
|
|
29
|
+
if (geometry.isBufferGeometry) geometry = new THREE.Geometry().fromBufferGeometry(geometry);
|
|
30
|
+
geometry.mergeVertices();
|
|
31
|
+
geometry.computeVertexNormals(false);
|
|
32
|
+
} else if (geometry instanceof ThreeBSP.Node) {
|
|
31
33
|
this.tree = geometry;
|
|
32
|
-
this.matrix = new THREE.Matrix4;
|
|
34
|
+
this.matrix = new THREE.Matrix4();
|
|
33
35
|
return this;
|
|
34
36
|
} else {
|
|
35
37
|
throw 'ThreeBSP: Given geometry is unsupported';
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
for (
|
|
40
|
+
for (i = 0, _length_i = geometry.faces.length; i < _length_i; i++) {
|
|
39
41
|
face = geometry.faces[i];
|
|
40
42
|
faceVertexUvs = geometry.faceVertexUvs[0][i];
|
|
41
|
-
polygon = new ThreeBSP.Polygon;
|
|
43
|
+
polygon = new ThreeBSP.Polygon();
|
|
42
44
|
|
|
43
|
-
if (
|
|
44
|
-
vertex = geometry.vertices[
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
if (face instanceof THREE.Face3) {
|
|
46
|
+
vertex = geometry.vertices[face.a];
|
|
47
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null;
|
|
48
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs);
|
|
47
49
|
vertex.applyMatrix4(this.matrix);
|
|
48
|
-
polygon.vertices.push(
|
|
50
|
+
polygon.vertices.push(vertex);
|
|
49
51
|
|
|
50
|
-
vertex = geometry.vertices[
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
vertex = geometry.vertices[face.b];
|
|
53
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null;
|
|
54
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
|
|
53
55
|
vertex.applyMatrix4(this.matrix);
|
|
54
|
-
polygon.vertices.push(
|
|
56
|
+
polygon.vertices.push(vertex);
|
|
55
57
|
|
|
56
|
-
vertex = geometry.vertices[
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
vertex = geometry.vertices[face.c];
|
|
59
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null;
|
|
60
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
|
|
59
61
|
vertex.applyMatrix4(this.matrix);
|
|
60
|
-
polygon.vertices.push(
|
|
61
|
-
} else if (
|
|
62
|
-
vertex = geometry.vertices[
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
polygon.vertices.push(vertex);
|
|
63
|
+
} else if (typeof THREE.Face4) {
|
|
64
|
+
vertex = geometry.vertices[face.a];
|
|
65
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null;
|
|
66
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs);
|
|
65
67
|
vertex.applyMatrix4(this.matrix);
|
|
66
|
-
polygon.vertices.push(
|
|
68
|
+
polygon.vertices.push(vertex);
|
|
67
69
|
|
|
68
|
-
vertex = geometry.vertices[
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
vertex = geometry.vertices[face.b];
|
|
71
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null;
|
|
72
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs);
|
|
71
73
|
vertex.applyMatrix4(this.matrix);
|
|
72
|
-
polygon.vertices.push(
|
|
74
|
+
polygon.vertices.push(vertex);
|
|
73
75
|
|
|
74
|
-
vertex = geometry.vertices[
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
vertex = geometry.vertices[face.c];
|
|
77
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null;
|
|
78
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs);
|
|
77
79
|
vertex.applyMatrix4(this.matrix);
|
|
78
|
-
polygon.vertices.push(
|
|
80
|
+
polygon.vertices.push(vertex);
|
|
79
81
|
|
|
80
|
-
vertex = geometry.vertices[
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
vertex = geometry.vertices[face.d];
|
|
83
|
+
uvs = faceVertexUvs ? new THREE.Vector2(faceVertexUvs[3].x, faceVertexUvs[3].y) : null;
|
|
84
|
+
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs);
|
|
83
85
|
vertex.applyMatrix4(this.matrix);
|
|
84
|
-
polygon.vertices.push(
|
|
86
|
+
polygon.vertices.push(vertex);
|
|
85
87
|
} else {
|
|
86
88
|
throw 'Invalid face type at index ' + i;
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
polygon.calculateProperties();
|
|
90
|
-
polygons.push(
|
|
91
|
-
}
|
|
92
|
+
polygons.push(polygon);
|
|
93
|
+
}
|
|
92
94
|
|
|
93
|
-
this.tree = new ThreeBSP.Node(
|
|
95
|
+
this.tree = new ThreeBSP.Node(polygons);
|
|
94
96
|
};
|
|
95
|
-
ThreeBSP.prototype.subtract = function(
|
|
97
|
+
ThreeBSP.prototype.subtract = function (other_tree) {
|
|
96
98
|
var a = this.tree.clone(),
|
|
97
99
|
b = other_tree.tree.clone();
|
|
98
100
|
|
|
99
101
|
a.invert();
|
|
100
|
-
a.clipTo(
|
|
101
|
-
b.clipTo(
|
|
102
|
+
a.clipTo(b);
|
|
103
|
+
b.clipTo(a);
|
|
102
104
|
b.invert();
|
|
103
|
-
b.clipTo(
|
|
105
|
+
b.clipTo(a);
|
|
104
106
|
b.invert();
|
|
105
|
-
a.build(
|
|
107
|
+
a.build(b.allPolygons());
|
|
106
108
|
a.invert();
|
|
107
|
-
a = new ThreeBSP(
|
|
109
|
+
a = new ThreeBSP(a);
|
|
108
110
|
a.matrix = this.matrix;
|
|
109
111
|
return a;
|
|
110
112
|
};
|
|
111
|
-
ThreeBSP.prototype.union = function(
|
|
113
|
+
ThreeBSP.prototype.union = function (other_tree) {
|
|
112
114
|
var a = this.tree.clone(),
|
|
113
115
|
b = other_tree.tree.clone();
|
|
114
116
|
|
|
115
|
-
a.clipTo(
|
|
116
|
-
b.clipTo(
|
|
117
|
+
a.clipTo(b);
|
|
118
|
+
b.clipTo(a);
|
|
117
119
|
b.invert();
|
|
118
|
-
b.clipTo(
|
|
120
|
+
b.clipTo(a);
|
|
119
121
|
b.invert();
|
|
120
|
-
a.build(
|
|
121
|
-
a = new ThreeBSP(
|
|
122
|
+
a.build(b.allPolygons());
|
|
123
|
+
a = new ThreeBSP(a);
|
|
122
124
|
a.matrix = this.matrix;
|
|
123
125
|
return a;
|
|
124
126
|
};
|
|
125
|
-
ThreeBSP.prototype.intersect = function(
|
|
127
|
+
ThreeBSP.prototype.intersect = function (other_tree) {
|
|
126
128
|
var a = this.tree.clone(),
|
|
127
129
|
b = other_tree.tree.clone();
|
|
128
130
|
|
|
129
131
|
a.invert();
|
|
130
|
-
b.clipTo(
|
|
132
|
+
b.clipTo(a);
|
|
131
133
|
b.invert();
|
|
132
|
-
a.clipTo(
|
|
133
|
-
b.clipTo(
|
|
134
|
-
a.build(
|
|
134
|
+
a.clipTo(b);
|
|
135
|
+
b.clipTo(a);
|
|
136
|
+
a.build(b.allPolygons());
|
|
135
137
|
a.invert();
|
|
136
|
-
a = new ThreeBSP(
|
|
138
|
+
a = new ThreeBSP(a);
|
|
137
139
|
a.matrix = this.matrix;
|
|
138
140
|
return a;
|
|
139
141
|
};
|
|
140
|
-
ThreeBSP.prototype.toGeometry = function() {
|
|
141
|
-
var i,
|
|
142
|
-
|
|
142
|
+
ThreeBSP.prototype.toGeometry = function () {
|
|
143
|
+
var i,
|
|
144
|
+
j,
|
|
145
|
+
matrix = new THREE.Matrix4().getInverse(this.matrix),
|
|
143
146
|
geometry = new THREE.Geometry(),
|
|
144
147
|
polygons = this.tree.allPolygons(),
|
|
145
148
|
polygon_count = polygons.length,
|
|
146
|
-
polygon,
|
|
149
|
+
polygon,
|
|
150
|
+
polygon_vertice_count,
|
|
147
151
|
vertice_dict = {},
|
|
148
|
-
vertex_idx_a,
|
|
149
|
-
|
|
152
|
+
vertex_idx_a,
|
|
153
|
+
vertex_idx_b,
|
|
154
|
+
vertex_idx_c,
|
|
155
|
+
vertex,
|
|
156
|
+
face,
|
|
150
157
|
verticeUvs;
|
|
151
158
|
|
|
152
|
-
for (
|
|
159
|
+
for (i = 0; i < polygon_count; i++) {
|
|
153
160
|
polygon = polygons[i];
|
|
154
161
|
polygon_vertice_count = polygon.vertices.length;
|
|
155
162
|
|
|
156
|
-
for (
|
|
163
|
+
for (j = 2; j < polygon_vertice_count; j++) {
|
|
157
164
|
verticeUvs = [];
|
|
158
165
|
|
|
159
166
|
vertex = polygon.vertices[0];
|
|
160
|
-
verticeUvs.push(
|
|
161
|
-
vertex = new THREE.Vector3(
|
|
167
|
+
verticeUvs.push(new THREE.Vector2(vertex.uv.x, vertex.uv.y));
|
|
168
|
+
vertex = new THREE.Vector3(vertex.x, vertex.y, vertex.z);
|
|
162
169
|
vertex.applyMatrix4(matrix);
|
|
163
170
|
|
|
164
|
-
if (
|
|
165
|
-
vertex_idx_a = vertice_dict[
|
|
171
|
+
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') {
|
|
172
|
+
vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
|
|
166
173
|
} else {
|
|
167
|
-
geometry.vertices.push(
|
|
168
|
-
vertex_idx_a = vertice_dict[
|
|
174
|
+
geometry.vertices.push(vertex);
|
|
175
|
+
vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] =
|
|
176
|
+
geometry.vertices.length - 1;
|
|
169
177
|
}
|
|
170
178
|
|
|
171
|
-
vertex = polygon.vertices[j-1];
|
|
172
|
-
verticeUvs.push(
|
|
173
|
-
vertex = new THREE.Vector3(
|
|
179
|
+
vertex = polygon.vertices[j - 1];
|
|
180
|
+
verticeUvs.push(new THREE.Vector2(vertex.uv.x, vertex.uv.y));
|
|
181
|
+
vertex = new THREE.Vector3(vertex.x, vertex.y, vertex.z);
|
|
174
182
|
vertex.applyMatrix4(matrix);
|
|
175
|
-
if (
|
|
176
|
-
vertex_idx_b = vertice_dict[
|
|
183
|
+
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') {
|
|
184
|
+
vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
|
|
177
185
|
} else {
|
|
178
|
-
geometry.vertices.push(
|
|
179
|
-
vertex_idx_b = vertice_dict[
|
|
186
|
+
geometry.vertices.push(vertex);
|
|
187
|
+
vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] =
|
|
188
|
+
geometry.vertices.length - 1;
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
vertex = polygon.vertices[j];
|
|
183
|
-
verticeUvs.push(
|
|
184
|
-
vertex = new THREE.Vector3(
|
|
192
|
+
verticeUvs.push(new THREE.Vector2(vertex.uv.x, vertex.uv.y));
|
|
193
|
+
vertex = new THREE.Vector3(vertex.x, vertex.y, vertex.z);
|
|
185
194
|
vertex.applyMatrix4(matrix);
|
|
186
|
-
if (
|
|
187
|
-
vertex_idx_c = vertice_dict[
|
|
195
|
+
if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') {
|
|
196
|
+
vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
|
|
188
197
|
} else {
|
|
189
|
-
geometry.vertices.push(
|
|
190
|
-
vertex_idx_c = vertice_dict[
|
|
198
|
+
geometry.vertices.push(vertex);
|
|
199
|
+
vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] =
|
|
200
|
+
geometry.vertices.length - 1;
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
face = new THREE.Face3(
|
|
194
204
|
vertex_idx_a,
|
|
195
205
|
vertex_idx_b,
|
|
196
206
|
vertex_idx_c,
|
|
197
|
-
new THREE.Vector3(
|
|
207
|
+
new THREE.Vector3(polygon.normal.x, polygon.normal.y, polygon.normal.z),
|
|
198
208
|
);
|
|
199
209
|
|
|
200
|
-
geometry.faces.push(
|
|
201
|
-
geometry.faceVertexUvs[0].push(
|
|
210
|
+
geometry.faces.push(face);
|
|
211
|
+
geometry.faceVertexUvs[0].push(verticeUvs);
|
|
202
212
|
}
|
|
203
|
-
|
|
204
213
|
}
|
|
205
214
|
return geometry;
|
|
206
215
|
};
|
|
207
|
-
ThreeBSP.prototype.toBufferGeometry = function(
|
|
216
|
+
ThreeBSP.prototype.toBufferGeometry = function () {
|
|
208
217
|
var geometry = this.toGeometry();
|
|
209
218
|
var bufferGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
|
|
210
219
|
|
|
211
220
|
return bufferGeometry;
|
|
212
221
|
};
|
|
213
|
-
ThreeBSP.prototype.toMesh = function(
|
|
222
|
+
ThreeBSP.prototype.toMesh = function (material) {
|
|
214
223
|
var geometry = this.toBufferGeometry(),
|
|
215
|
-
mesh = new THREE.Mesh(
|
|
224
|
+
mesh = new THREE.Mesh(geometry, material);
|
|
216
225
|
|
|
217
|
-
mesh.position.setFromMatrixPosition(
|
|
218
|
-
mesh.rotation.setFromRotationMatrix(
|
|
226
|
+
mesh.position.setFromMatrixPosition(this.matrix);
|
|
227
|
+
mesh.rotation.setFromRotationMatrix(this.matrix);
|
|
219
228
|
|
|
220
229
|
return mesh;
|
|
221
230
|
};
|
|
222
231
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if ( !( vertices instanceof Array ) ) {
|
|
232
|
+
ThreeBSP.Polygon = function (vertices, normal, w) {
|
|
233
|
+
if (!(vertices instanceof Array)) {
|
|
226
234
|
vertices = [];
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
this.vertices = vertices;
|
|
230
|
-
if (
|
|
238
|
+
if (vertices.length > 0) {
|
|
231
239
|
this.calculateProperties();
|
|
232
240
|
} else {
|
|
233
241
|
this.normal = this.w = undefined;
|
|
234
242
|
}
|
|
235
243
|
};
|
|
236
|
-
ThreeBSP.Polygon.prototype.calculateProperties = function() {
|
|
244
|
+
ThreeBSP.Polygon.prototype.calculateProperties = function () {
|
|
237
245
|
var a = this.vertices[0],
|
|
238
246
|
b = this.vertices[1],
|
|
239
247
|
c = this.vertices[2];
|
|
240
248
|
|
|
241
|
-
this.normal = b.clone().subtract(
|
|
242
|
-
c.clone().subtract( a )
|
|
243
|
-
).normalize();
|
|
249
|
+
this.normal = b.clone().subtract(a).cross(c.clone().subtract(a)).normalize();
|
|
244
250
|
|
|
245
|
-
this.w = this.normal.clone().dot(
|
|
251
|
+
this.w = this.normal.clone().dot(a);
|
|
246
252
|
|
|
247
253
|
return this;
|
|
248
254
|
};
|
|
249
|
-
ThreeBSP.Polygon.prototype.clone = function() {
|
|
250
|
-
var i,
|
|
251
|
-
|
|
255
|
+
ThreeBSP.Polygon.prototype.clone = function () {
|
|
256
|
+
var i,
|
|
257
|
+
vertice_count,
|
|
258
|
+
polygon = new ThreeBSP.Polygon();
|
|
252
259
|
|
|
253
|
-
for (
|
|
254
|
-
polygon.vertices.push(
|
|
255
|
-
}
|
|
260
|
+
for (i = 0, vertice_count = this.vertices.length; i < vertice_count; i++) {
|
|
261
|
+
polygon.vertices.push(this.vertices[i].clone());
|
|
262
|
+
}
|
|
256
263
|
polygon.calculateProperties();
|
|
257
264
|
|
|
258
265
|
return polygon;
|
|
259
266
|
};
|
|
260
267
|
|
|
261
|
-
ThreeBSP.Polygon.prototype.flip = function() {
|
|
262
|
-
var i,
|
|
268
|
+
ThreeBSP.Polygon.prototype.flip = function () {
|
|
269
|
+
var i,
|
|
270
|
+
vertices = [];
|
|
263
271
|
|
|
264
|
-
this.normal.multiplyScalar(
|
|
272
|
+
this.normal.multiplyScalar(-1);
|
|
265
273
|
this.w *= -1;
|
|
266
274
|
|
|
267
|
-
for (
|
|
268
|
-
vertices.push(
|
|
269
|
-
}
|
|
275
|
+
for (i = this.vertices.length - 1; i >= 0; i--) {
|
|
276
|
+
vertices.push(this.vertices[i]);
|
|
277
|
+
}
|
|
270
278
|
this.vertices = vertices;
|
|
271
279
|
|
|
272
280
|
return this;
|
|
273
281
|
};
|
|
274
|
-
ThreeBSP.Polygon.prototype.classifyVertex = function(
|
|
275
|
-
var side_value = this.normal.dot(
|
|
282
|
+
ThreeBSP.Polygon.prototype.classifyVertex = function (vertex) {
|
|
283
|
+
var side_value = this.normal.dot(vertex) - this.w;
|
|
276
284
|
|
|
277
|
-
if (
|
|
285
|
+
if (side_value < -EPSILON) {
|
|
278
286
|
return BACK;
|
|
279
|
-
} else if (
|
|
287
|
+
} else if (side_value > EPSILON) {
|
|
280
288
|
return FRONT;
|
|
281
289
|
} else {
|
|
282
290
|
return COPLANAR;
|
|
283
291
|
}
|
|
284
292
|
};
|
|
285
|
-
ThreeBSP.Polygon.prototype.classifySide = function(
|
|
286
|
-
var i,
|
|
293
|
+
ThreeBSP.Polygon.prototype.classifySide = function (polygon) {
|
|
294
|
+
var i,
|
|
295
|
+
vertex,
|
|
296
|
+
classification,
|
|
287
297
|
num_positive = 0,
|
|
288
298
|
num_negative = 0,
|
|
289
299
|
vertice_count = polygon.vertices.length;
|
|
290
300
|
|
|
291
|
-
for (
|
|
301
|
+
for (i = 0; i < vertice_count; i++) {
|
|
292
302
|
vertex = polygon.vertices[i];
|
|
293
|
-
classification = this.classifyVertex(
|
|
294
|
-
if (
|
|
303
|
+
classification = this.classifyVertex(vertex);
|
|
304
|
+
if (classification === FRONT) {
|
|
295
305
|
num_positive++;
|
|
296
|
-
} else if (
|
|
306
|
+
} else if (classification === BACK) {
|
|
297
307
|
num_negative++;
|
|
298
308
|
}
|
|
299
309
|
}
|
|
300
310
|
|
|
301
|
-
if (
|
|
311
|
+
if (num_positive > 0 && num_negative === 0) {
|
|
302
312
|
return FRONT;
|
|
303
|
-
} else if (
|
|
313
|
+
} else if (num_positive === 0 && num_negative > 0) {
|
|
304
314
|
return BACK;
|
|
305
|
-
} else if (
|
|
315
|
+
} else if (num_positive === 0 && num_negative === 0) {
|
|
306
316
|
return COPLANAR;
|
|
307
317
|
} else {
|
|
308
318
|
return SPANNING;
|
|
309
319
|
}
|
|
310
320
|
};
|
|
311
|
-
ThreeBSP.Polygon.prototype.splitPolygon = function(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
} else if (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
ThreeBSP.Polygon.prototype.splitPolygon = function (
|
|
322
|
+
polygon,
|
|
323
|
+
coplanar_front,
|
|
324
|
+
coplanar_back,
|
|
325
|
+
front,
|
|
326
|
+
back,
|
|
327
|
+
) {
|
|
328
|
+
var classification = this.classifySide(polygon);
|
|
329
|
+
|
|
330
|
+
if (classification === COPLANAR) {
|
|
331
|
+
(this.normal.dot(polygon.normal) > 0 ? coplanar_front : coplanar_back).push(polygon);
|
|
332
|
+
} else if (classification === FRONT) {
|
|
333
|
+
front.push(polygon);
|
|
334
|
+
} else if (classification === BACK) {
|
|
335
|
+
back.push(polygon);
|
|
326
336
|
} else {
|
|
327
|
-
|
|
328
337
|
var vertice_count,
|
|
329
|
-
i,
|
|
330
|
-
|
|
338
|
+
i,
|
|
339
|
+
j,
|
|
340
|
+
ti,
|
|
341
|
+
tj,
|
|
342
|
+
vi,
|
|
343
|
+
vj,
|
|
344
|
+
t,
|
|
345
|
+
v,
|
|
331
346
|
f = [],
|
|
332
347
|
b = [];
|
|
333
348
|
|
|
334
|
-
for (
|
|
335
|
-
|
|
349
|
+
for (i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++) {
|
|
336
350
|
j = (i + 1) % vertice_count;
|
|
337
351
|
vi = polygon.vertices[i];
|
|
338
352
|
vj = polygon.vertices[j];
|
|
339
|
-
ti = this.classifyVertex(
|
|
340
|
-
tj = this.classifyVertex(
|
|
341
|
-
|
|
342
|
-
if (
|
|
343
|
-
if (
|
|
344
|
-
if (
|
|
345
|
-
t = (
|
|
346
|
-
v = vi.interpolate(
|
|
347
|
-
f.push(
|
|
348
|
-
b.push(
|
|
353
|
+
ti = this.classifyVertex(vi);
|
|
354
|
+
tj = this.classifyVertex(vj);
|
|
355
|
+
|
|
356
|
+
if (ti != BACK) f.push(vi);
|
|
357
|
+
if (ti != FRONT) b.push(vi);
|
|
358
|
+
if ((ti | tj) === SPANNING) {
|
|
359
|
+
t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().subtract(vi));
|
|
360
|
+
v = vi.interpolate(vj, t);
|
|
361
|
+
f.push(v);
|
|
362
|
+
b.push(v);
|
|
349
363
|
}
|
|
350
364
|
}
|
|
351
365
|
|
|
352
|
-
|
|
353
|
-
if (
|
|
354
|
-
if ( b.length >= 3 ) back.push( new ThreeBSP.Polygon( b ).calculateProperties() );
|
|
366
|
+
if (f.length >= 3) front.push(new ThreeBSP.Polygon(f).calculateProperties());
|
|
367
|
+
if (b.length >= 3) back.push(new ThreeBSP.Polygon(b).calculateProperties());
|
|
355
368
|
}
|
|
356
369
|
};
|
|
357
370
|
|
|
358
|
-
ThreeBSP.Vertex = function(
|
|
371
|
+
ThreeBSP.Vertex = function (x, y, z, normal, uv) {
|
|
359
372
|
this.x = x;
|
|
360
373
|
this.y = y;
|
|
361
374
|
this.z = z;
|
|
362
|
-
this.normal = normal || new THREE.Vector3;
|
|
363
|
-
this.uv = uv || new THREE.Vector2;
|
|
375
|
+
this.normal = normal || new THREE.Vector3();
|
|
376
|
+
this.uv = uv || new THREE.Vector2();
|
|
364
377
|
};
|
|
365
|
-
ThreeBSP.Vertex.prototype.clone = function() {
|
|
366
|
-
return new ThreeBSP.Vertex(
|
|
378
|
+
ThreeBSP.Vertex.prototype.clone = function () {
|
|
379
|
+
return new ThreeBSP.Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone());
|
|
367
380
|
};
|
|
368
|
-
ThreeBSP.Vertex.prototype.add = function(
|
|
381
|
+
ThreeBSP.Vertex.prototype.add = function (vertex) {
|
|
369
382
|
this.x += vertex.x;
|
|
370
383
|
this.y += vertex.y;
|
|
371
384
|
this.z += vertex.z;
|
|
372
385
|
return this;
|
|
373
386
|
};
|
|
374
|
-
ThreeBSP.Vertex.prototype.subtract = function(
|
|
387
|
+
ThreeBSP.Vertex.prototype.subtract = function (vertex) {
|
|
375
388
|
this.x -= vertex.x;
|
|
376
389
|
this.y -= vertex.y;
|
|
377
390
|
this.z -= vertex.z;
|
|
378
391
|
return this;
|
|
379
392
|
};
|
|
380
|
-
ThreeBSP.Vertex.prototype.multiplyScalar = function(
|
|
393
|
+
ThreeBSP.Vertex.prototype.multiplyScalar = function (scalar) {
|
|
381
394
|
this.x *= scalar;
|
|
382
395
|
this.y *= scalar;
|
|
383
396
|
this.z *= scalar;
|
|
384
397
|
return this;
|
|
385
398
|
};
|
|
386
|
-
ThreeBSP.Vertex.prototype.cross = function(
|
|
399
|
+
ThreeBSP.Vertex.prototype.cross = function (vertex) {
|
|
387
400
|
var x = this.x,
|
|
388
401
|
y = this.y,
|
|
389
402
|
z = this.z;
|
|
@@ -394,8 +407,8 @@ const ThreeBSPWrapper = function( THREE ) {
|
|
|
394
407
|
|
|
395
408
|
return this;
|
|
396
409
|
};
|
|
397
|
-
ThreeBSP.Vertex.prototype.normalize = function() {
|
|
398
|
-
var length = Math.sqrt(
|
|
410
|
+
ThreeBSP.Vertex.prototype.normalize = function () {
|
|
411
|
+
var length = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
|
399
412
|
|
|
400
413
|
this.x /= length;
|
|
401
414
|
this.y /= length;
|
|
@@ -403,128 +416,125 @@ const ThreeBSPWrapper = function( THREE ) {
|
|
|
403
416
|
|
|
404
417
|
return this;
|
|
405
418
|
};
|
|
406
|
-
ThreeBSP.Vertex.prototype.dot = function(
|
|
419
|
+
ThreeBSP.Vertex.prototype.dot = function (vertex) {
|
|
407
420
|
return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z;
|
|
408
421
|
};
|
|
409
|
-
ThreeBSP.Vertex.prototype.lerp = function(
|
|
410
|
-
this.add(
|
|
411
|
-
a.clone().subtract( this ).multiplyScalar( t )
|
|
412
|
-
);
|
|
422
|
+
ThreeBSP.Vertex.prototype.lerp = function (a, t) {
|
|
423
|
+
this.add(a.clone().subtract(this).multiplyScalar(t));
|
|
413
424
|
|
|
414
|
-
this.normal.add(
|
|
415
|
-
a.normal.clone().sub( this.normal ).multiplyScalar( t )
|
|
416
|
-
);
|
|
425
|
+
this.normal.add(a.normal.clone().sub(this.normal).multiplyScalar(t));
|
|
417
426
|
|
|
418
|
-
this.uv.add(
|
|
419
|
-
a.uv.clone().sub( this.uv ).multiplyScalar( t )
|
|
420
|
-
);
|
|
427
|
+
this.uv.add(a.uv.clone().sub(this.uv).multiplyScalar(t));
|
|
421
428
|
|
|
422
429
|
return this;
|
|
423
430
|
};
|
|
424
|
-
ThreeBSP.Vertex.prototype.interpolate = function(
|
|
425
|
-
return this.clone().lerp(
|
|
431
|
+
ThreeBSP.Vertex.prototype.interpolate = function (other, t) {
|
|
432
|
+
return this.clone().lerp(other, t);
|
|
426
433
|
};
|
|
427
|
-
ThreeBSP.Vertex.prototype.applyMatrix4 = function (
|
|
428
|
-
|
|
434
|
+
ThreeBSP.Vertex.prototype.applyMatrix4 = function (m) {
|
|
429
435
|
// input: THREE.Matrix4 affine matrix
|
|
430
436
|
|
|
431
|
-
var x = this.x,
|
|
437
|
+
var x = this.x,
|
|
438
|
+
y = this.y,
|
|
439
|
+
z = this.z;
|
|
432
440
|
|
|
433
441
|
var e = m.elements;
|
|
434
442
|
|
|
435
|
-
this.x = e[0] * x + e[4] * y + e[8]
|
|
436
|
-
this.y = e[1] * x + e[5] * y + e[9]
|
|
443
|
+
this.x = e[0] * x + e[4] * y + e[8] * z + e[12];
|
|
444
|
+
this.y = e[1] * x + e[5] * y + e[9] * z + e[13];
|
|
437
445
|
this.z = e[2] * x + e[6] * y + e[10] * z + e[14];
|
|
438
446
|
|
|
439
447
|
return this;
|
|
440
|
-
|
|
441
448
|
};
|
|
442
449
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
450
|
+
ThreeBSP.Node = function (polygons) {
|
|
451
|
+
var i,
|
|
452
|
+
polygon_count,
|
|
446
453
|
front = [],
|
|
447
454
|
back = [];
|
|
448
455
|
|
|
449
456
|
this.polygons = [];
|
|
450
457
|
this.front = this.back = undefined;
|
|
451
458
|
|
|
452
|
-
if (
|
|
459
|
+
if (!(polygons instanceof Array) || polygons.length === 0) return;
|
|
453
460
|
|
|
454
461
|
this.divider = polygons[0].clone();
|
|
455
462
|
|
|
456
|
-
for (
|
|
457
|
-
this.divider.splitPolygon(
|
|
463
|
+
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) {
|
|
464
|
+
this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
|
|
458
465
|
}
|
|
459
466
|
|
|
460
|
-
if (
|
|
461
|
-
this.front = new ThreeBSP.Node(
|
|
467
|
+
if (front.length > 0) {
|
|
468
|
+
this.front = new ThreeBSP.Node(front);
|
|
462
469
|
}
|
|
463
470
|
|
|
464
|
-
if (
|
|
465
|
-
this.back = new ThreeBSP.Node(
|
|
471
|
+
if (back.length > 0) {
|
|
472
|
+
this.back = new ThreeBSP.Node(back);
|
|
466
473
|
}
|
|
467
474
|
};
|
|
468
|
-
ThreeBSP.Node.isConvex = function(
|
|
475
|
+
ThreeBSP.Node.isConvex = function (polygons) {
|
|
469
476
|
var i, j;
|
|
470
|
-
for (
|
|
471
|
-
for (
|
|
472
|
-
if (
|
|
477
|
+
for (i = 0; i < polygons.length; i++) {
|
|
478
|
+
for (j = 0; j < polygons.length; j++) {
|
|
479
|
+
if (i !== j && polygons[i].classifySide(polygons[j]) !== BACK) {
|
|
473
480
|
return false;
|
|
474
481
|
}
|
|
475
482
|
}
|
|
476
483
|
}
|
|
477
484
|
return true;
|
|
478
485
|
};
|
|
479
|
-
ThreeBSP.Node.prototype.build = function(
|
|
480
|
-
var i,
|
|
486
|
+
ThreeBSP.Node.prototype.build = function (polygons) {
|
|
487
|
+
var i,
|
|
488
|
+
polygon_count,
|
|
481
489
|
front = [],
|
|
482
490
|
back = [];
|
|
483
491
|
|
|
484
|
-
if (
|
|
492
|
+
if (!this.divider) {
|
|
485
493
|
this.divider = polygons[0].clone();
|
|
486
494
|
}
|
|
487
495
|
|
|
488
|
-
for (
|
|
489
|
-
this.divider.splitPolygon(
|
|
496
|
+
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) {
|
|
497
|
+
this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
|
|
490
498
|
}
|
|
491
499
|
|
|
492
|
-
if (
|
|
493
|
-
if (
|
|
494
|
-
this.front.build(
|
|
500
|
+
if (front.length > 0) {
|
|
501
|
+
if (!this.front) this.front = new ThreeBSP.Node();
|
|
502
|
+
this.front.build(front);
|
|
495
503
|
}
|
|
496
504
|
|
|
497
|
-
if (
|
|
498
|
-
if (
|
|
499
|
-
this.back.build(
|
|
505
|
+
if (back.length > 0) {
|
|
506
|
+
if (!this.back) this.back = new ThreeBSP.Node();
|
|
507
|
+
this.back.build(back);
|
|
500
508
|
}
|
|
501
509
|
};
|
|
502
|
-
ThreeBSP.Node.prototype.allPolygons = function() {
|
|
510
|
+
ThreeBSP.Node.prototype.allPolygons = function () {
|
|
503
511
|
var polygons = this.polygons.slice();
|
|
504
|
-
if (
|
|
505
|
-
if (
|
|
512
|
+
if (this.front) polygons = polygons.concat(this.front.allPolygons());
|
|
513
|
+
if (this.back) polygons = polygons.concat(this.back.allPolygons());
|
|
506
514
|
return polygons;
|
|
507
515
|
};
|
|
508
|
-
ThreeBSP.Node.prototype.clone = function() {
|
|
516
|
+
ThreeBSP.Node.prototype.clone = function () {
|
|
509
517
|
var node = new ThreeBSP.Node();
|
|
510
518
|
|
|
511
519
|
node.divider = this.divider.clone();
|
|
512
|
-
node.polygons = this.polygons.map(
|
|
520
|
+
node.polygons = this.polygons.map(function (polygon) {
|
|
521
|
+
return polygon.clone();
|
|
522
|
+
});
|
|
513
523
|
node.front = this.front && this.front.clone();
|
|
514
524
|
node.back = this.back && this.back.clone();
|
|
515
525
|
|
|
516
526
|
return node;
|
|
517
527
|
};
|
|
518
|
-
ThreeBSP.Node.prototype.invert = function() {
|
|
528
|
+
ThreeBSP.Node.prototype.invert = function () {
|
|
519
529
|
var i, polygon_count, temp;
|
|
520
530
|
|
|
521
|
-
for (
|
|
531
|
+
for (i = 0, polygon_count = this.polygons.length; i < polygon_count; i++) {
|
|
522
532
|
this.polygons[i].flip();
|
|
523
533
|
}
|
|
524
534
|
|
|
525
535
|
this.divider.flip();
|
|
526
|
-
if (
|
|
527
|
-
if (
|
|
536
|
+
if (this.front) this.front.invert();
|
|
537
|
+
if (this.back) this.back.invert();
|
|
528
538
|
|
|
529
539
|
temp = this.front;
|
|
530
540
|
this.front = this.back;
|
|
@@ -532,33 +542,31 @@ const ThreeBSPWrapper = function( THREE ) {
|
|
|
532
542
|
|
|
533
543
|
return this;
|
|
534
544
|
};
|
|
535
|
-
ThreeBSP.Node.prototype.clipPolygons = function(
|
|
536
|
-
var i, polygon_count,
|
|
537
|
-
front, back;
|
|
545
|
+
ThreeBSP.Node.prototype.clipPolygons = function (polygons) {
|
|
546
|
+
var i, polygon_count, front, back;
|
|
538
547
|
|
|
539
|
-
if (
|
|
548
|
+
if (!this.divider) return polygons.slice();
|
|
540
549
|
|
|
541
|
-
front = [], back = [];
|
|
550
|
+
((front = []), (back = []));
|
|
542
551
|
|
|
543
|
-
for (
|
|
544
|
-
this.divider.splitPolygon(
|
|
552
|
+
for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) {
|
|
553
|
+
this.divider.splitPolygon(polygons[i], front, back, front, back);
|
|
545
554
|
}
|
|
546
555
|
|
|
547
|
-
if (
|
|
548
|
-
if (
|
|
556
|
+
if (this.front) front = this.front.clipPolygons(front);
|
|
557
|
+
if (this.back) back = this.back.clipPolygons(back);
|
|
549
558
|
else back = [];
|
|
550
559
|
|
|
551
|
-
return front.concat(
|
|
560
|
+
return front.concat(back);
|
|
552
561
|
};
|
|
553
562
|
|
|
554
|
-
ThreeBSP.Node.prototype.clipTo = function(
|
|
555
|
-
this.polygons = node.clipPolygons(
|
|
556
|
-
if (
|
|
557
|
-
if (
|
|
563
|
+
ThreeBSP.Node.prototype.clipTo = function (node) {
|
|
564
|
+
this.polygons = node.clipPolygons(this.polygons);
|
|
565
|
+
if (this.front) this.front.clipTo(node);
|
|
566
|
+
if (this.back) this.back.clipTo(node);
|
|
558
567
|
};
|
|
559
568
|
|
|
560
|
-
|
|
561
569
|
return ThreeBSP;
|
|
562
|
-
}
|
|
570
|
+
};
|
|
563
571
|
|
|
564
|
-
|
|
572
|
+
export { ThreeBSPWrapper };
|