zincjs 1.2.0 → 1.4.0-beta.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/CHANGELOG.md +12 -1
- package/build/zinc.frontend.js +2 -2
- package/build/zinc.js +335 -241
- package/build/zinc.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/mapMarker.svg +1 -1
- package/src/geometryCSG.js +14 -14
- package/src/glyphsetCSG.js +2 -2
- package/src/loaders/GLTFToZincJSLoader.js +3 -2
- package/src/loaders/primitivesLoader.js +3 -1
- package/src/primitives/geometry.js +70 -54
- package/src/primitives/glyphset.js +6 -6
- package/src/primitives/lines.js +2 -1
- package/src/primitives/lod.js +378 -0
- package/src/primitives/marker.js +4 -2
- package/src/primitives/pointset.js +2 -1
- package/src/primitives/textureSlides.js +126 -46
- package/src/primitives/zincObject.js +132 -197
- package/src/region.js +10 -8
- package/src/scene.js +2 -2
- package/src/sceneExporter.js +1 -1
- package/src/sceneLoader.js +27 -36
- package/src/shaders/textureSlide.js +6 -4
- package/src/utilities.js +226 -145
- package/src/workers/geometryCSG.worker.js +4 -4
package/src/sceneLoader.js
CHANGED
|
@@ -160,7 +160,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
160
160
|
if (morphColour != undefined && morphColour[i] != undefined)
|
|
161
161
|
localMorphColour = morphColour[i] ? true : false;
|
|
162
162
|
primitivesLoader.load(resolveURL(filename), meshloader(region, colour, opacity, localTimeEnabled, localMorphColour, undefined, undefined,
|
|
163
|
-
undefined, finishCallback), this.onProgress(i), this.onError(finishCallback));
|
|
163
|
+
undefined, undefined, finishCallback), this.onProgress(i), this.onError(finishCallback));
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -340,7 +340,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
340
340
|
const loader = new STLLoader();
|
|
341
341
|
loader.crossOrigin = "Anonymous";
|
|
342
342
|
loader.load(resolveURL(url), meshloader(region, colour, opacity, false,
|
|
343
|
-
false, groupName, undefined, undefined, finishCallback));
|
|
343
|
+
false, groupName, undefined, undefined, undefined, finishCallback));
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
/**
|
|
@@ -359,33 +359,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
359
359
|
const loader = new OBJLoader();
|
|
360
360
|
loader.crossOrigin = "Anonymous";
|
|
361
361
|
loader.load(resolveURL(url), meshloader(region, colour, opacity, false,
|
|
362
|
-
false, groupName, undefined, undefined,finishCallback));
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
//Loader for the OBJ format,
|
|
366
|
-
const objloader = (
|
|
367
|
-
region,
|
|
368
|
-
colour,
|
|
369
|
-
opacity,
|
|
370
|
-
localTimeEnabled,
|
|
371
|
-
localMorphColour,
|
|
372
|
-
groupName,
|
|
373
|
-
finishCallback
|
|
374
|
-
) => {
|
|
375
|
-
return object => {
|
|
376
|
-
this.toBeDownloaded--;
|
|
377
|
-
object.traverse(child => {
|
|
378
|
-
if (child instanceof THREE.Mesh) {
|
|
379
|
-
const zincGeometry = addMeshToZincGeometry(child, localTimeEnabled, localMorphColour);
|
|
380
|
-
region.addZincObject(zincGeometry);
|
|
381
|
-
if (zincGeometry.morph)
|
|
382
|
-
zincGeometry.morph.name = groupName;
|
|
383
|
-
zincGeometry.groupName = groupName;
|
|
384
|
-
if (finishCallback != undefined && (typeof finishCallback == 'function'))
|
|
385
|
-
finishCallback(zincGeometry);
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
};
|
|
362
|
+
false, groupName, undefined, undefined, undefined, finishCallback));
|
|
389
363
|
}
|
|
390
364
|
|
|
391
365
|
/**
|
|
@@ -422,19 +396,19 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
422
396
|
} else if (fileFormat == "OBJ") {
|
|
423
397
|
loader = new OBJLoader();
|
|
424
398
|
loader.crossOrigin = "Anonymous";
|
|
425
|
-
loader.load(url,
|
|
426
|
-
localMorphColour, groupName, anatomicalId, finishCallback), this.onProgress(i), this.onError);
|
|
399
|
+
loader.load(url, meshloader(region, colour, opacity, localTimeEnabled,
|
|
400
|
+
localMorphColour, groupName, anatomicalId, renderOrder, options, finishCallback), this.onProgress(i), this.onError);
|
|
427
401
|
return;
|
|
428
402
|
}
|
|
429
403
|
}
|
|
430
404
|
if (isInline) {
|
|
431
405
|
const object = primitivesLoader.parse( url );
|
|
432
406
|
(meshloader(region, colour, opacity, localTimeEnabled,
|
|
433
|
-
localMorphColour, groupName, anatomicalId, renderOrder, finishCallback))( object.geometry, object.materials );
|
|
407
|
+
localMorphColour, groupName, anatomicalId, renderOrder, options, finishCallback))( object.geometry, object.materials );
|
|
434
408
|
} else {
|
|
435
409
|
loader.crossOrigin = "Anonymous";
|
|
436
410
|
primitivesLoader.load(url, meshloader(region, colour, opacity, localTimeEnabled,
|
|
437
|
-
localMorphColour, groupName, anatomicalId, renderOrder, finishCallback), this.onProgress(i), this.onError(finishCallback));
|
|
411
|
+
localMorphColour, groupName, anatomicalId, renderOrder, options, finishCallback), this.onProgress(i), this.onError(finishCallback));
|
|
438
412
|
}
|
|
439
413
|
};
|
|
440
414
|
|
|
@@ -529,7 +503,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
529
503
|
*
|
|
530
504
|
* @returns {Zinc.Geometry}
|
|
531
505
|
*/
|
|
532
|
-
|
|
506
|
+
createZincGeometry = (
|
|
533
507
|
region,
|
|
534
508
|
geometryIn,
|
|
535
509
|
colour,
|
|
@@ -547,7 +521,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
547
521
|
options.localMorphColour = localMorphColour
|
|
548
522
|
const newGeometry = new (require('./primitives/geometry').Geometry)();
|
|
549
523
|
newGeometry.createMesh(geometryIn, materialIn, options);
|
|
550
|
-
if (newGeometry.
|
|
524
|
+
if (newGeometry.getMorph()) {
|
|
551
525
|
newGeometry.setName(groupName);
|
|
552
526
|
if (region) region.addZincObject(newGeometry);
|
|
553
527
|
newGeometry.setDuration(scene.getDuration());
|
|
@@ -570,6 +544,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
570
544
|
groupName,
|
|
571
545
|
anatomicalId,
|
|
572
546
|
renderOrder,
|
|
547
|
+
options,
|
|
573
548
|
finishCallback
|
|
574
549
|
) => {
|
|
575
550
|
return (geometry, materials) => {
|
|
@@ -577,10 +552,16 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
577
552
|
if (materials && materials[0]) {
|
|
578
553
|
material = materials[0];
|
|
579
554
|
}
|
|
580
|
-
const zincGeometry =
|
|
555
|
+
const zincGeometry = createZincGeometry(region, geometry, colour, opacity,
|
|
581
556
|
localTimeEnabled, localMorphColour, undefined, material, groupName, renderOrder);
|
|
582
557
|
zincGeometry.anatomicalId = anatomicalId;
|
|
583
558
|
zincGeometry.setRenderOrder(renderOrder);
|
|
559
|
+
console.log(options)
|
|
560
|
+
if (options.lod && options.lod.levels) {
|
|
561
|
+
for (const [key, value] of Object.entries(options.lod.levels)) {
|
|
562
|
+
zincGeometry.addLOD(primitivesLoader, key, value.URL, options.lod.preload);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
584
565
|
--this.toBeDownloaded;
|
|
585
566
|
geometry.dispose();
|
|
586
567
|
if (finishCallback != undefined && (typeof finishCallback == 'function'))
|
|
@@ -632,6 +613,15 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
632
613
|
newURL = item.Inline.URL;
|
|
633
614
|
isInline = true;
|
|
634
615
|
}
|
|
616
|
+
const lod = {};
|
|
617
|
+
if (item.LOD && item.LOD.Levels) {
|
|
618
|
+
lod.preload = item.LOD.Preload ? true : false;
|
|
619
|
+
lod.levels = {};
|
|
620
|
+
for (const [key, value] of Object.entries(item.LOD.Levels)) {
|
|
621
|
+
lod.levels[key] = {};
|
|
622
|
+
lod.levels[key]["URL"] = createNewURL(value.URL, referenceURL);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
635
625
|
let groupName = item.GroupName;
|
|
636
626
|
if (groupName === undefined || groupName === "") {
|
|
637
627
|
groupName = "_Unnamed";
|
|
@@ -642,6 +632,7 @@ exports.SceneLoader = function (sceneIn) {
|
|
|
642
632
|
fileFormat: item.FileFormat,
|
|
643
633
|
anatomicalId: item.AnatomicalId,
|
|
644
634
|
compression: item.compression,
|
|
635
|
+
lod: lod,
|
|
645
636
|
renderOrder: order
|
|
646
637
|
};
|
|
647
638
|
|
|
@@ -28,16 +28,17 @@ const vs =
|
|
|
28
28
|
out vec3 vUw;
|
|
29
29
|
uniform float depth;
|
|
30
30
|
uniform vec3 slide;
|
|
31
|
+
uniform int direction;
|
|
31
32
|
|
|
32
33
|
void main() {
|
|
33
34
|
|
|
34
35
|
vec3 slidePos = position.xyz;
|
|
35
36
|
|
|
36
|
-
if (
|
|
37
|
+
if (direction == 1)
|
|
37
38
|
slidePos = vec3(slide.x, position.x, position.y);
|
|
38
|
-
if (
|
|
39
|
+
if (direction == 2)
|
|
39
40
|
slidePos = vec3(position.x, slide.y, position.y);
|
|
40
|
-
if (
|
|
41
|
+
if (direction == 3)
|
|
41
42
|
slidePos = vec3(position.x, position.y, slide.z);
|
|
42
43
|
|
|
43
44
|
gl_Position = projectionMatrix * modelViewMatrix * vec4( slidePos, 1.0 );
|
|
@@ -51,7 +52,8 @@ const getUniforms = function() {
|
|
|
51
52
|
return {
|
|
52
53
|
diffuse: { value: undefined },
|
|
53
54
|
depth: { value: 1 },
|
|
54
|
-
slide: { value: new THREE.Vector3( 0, 0, 1 ) }
|
|
55
|
+
slide: { value: new THREE.Vector3( 0, 0, 1 ) },
|
|
56
|
+
direction: {value: 1},
|
|
55
57
|
};
|
|
56
58
|
}
|
|
57
59
|
|
package/src/utilities.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const THREE = require('three');
|
|
2
|
+
const THREEGeometry = require('./three/Geometry').Geometry;
|
|
2
3
|
|
|
3
4
|
function resolveURL(url) {
|
|
4
5
|
let actualURL = url;
|
|
@@ -16,6 +17,40 @@ function resolveURL(url) {
|
|
|
16
17
|
return actualURL;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
/*
|
|
21
|
+
* Calculate the bounding box of a mesh, values will be
|
|
22
|
+
* set for cachedBox, b1, v1 and v2 and they need to be
|
|
23
|
+
* defined.
|
|
24
|
+
*/
|
|
25
|
+
function getBoundingBox(mesh, cachedBox, b1, v1, v2) {
|
|
26
|
+
let influences = mesh.morphTargetInfluences;
|
|
27
|
+
let attributes = undefined;
|
|
28
|
+
if (mesh.geometry)
|
|
29
|
+
attributes = mesh.geometry.morphAttributes;
|
|
30
|
+
let found = false;
|
|
31
|
+
if (influences && attributes && attributes.position) {
|
|
32
|
+
v1.set(0.0, 0.0, 0.0);
|
|
33
|
+
v2.set(0.0, 0.0, 0.0);
|
|
34
|
+
for (let i = 0; i < influences.length; i++) {
|
|
35
|
+
if (influences[i] > 0) {
|
|
36
|
+
found = true;
|
|
37
|
+
b1.setFromArray(attributes.position[i].array);
|
|
38
|
+
v1.add(b1.min.multiplyScalar(influences[i]));
|
|
39
|
+
v2.add(b1.max.multiplyScalar(influences[i]));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (found)
|
|
43
|
+
cachedBox.set(v1, v2);
|
|
44
|
+
}
|
|
45
|
+
if (!found) {
|
|
46
|
+
cachedBox.setFromBufferAttribute(
|
|
47
|
+
mesh.geometry.attributes.position);
|
|
48
|
+
}
|
|
49
|
+
mesh.updateWorldMatrix();
|
|
50
|
+
cachedBox.applyMatrix4(mesh.matrixWorld);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
19
54
|
//Convenient function
|
|
20
55
|
function loadExternalFile(url, data, callback, errorCallback) {
|
|
21
56
|
// Set up an asynchronous request
|
|
@@ -81,218 +116,264 @@ exports.getColorsRGB = (colors, index) => {
|
|
|
81
116
|
return [mycolor.r, mycolor.g, mycolor.b];
|
|
82
117
|
}
|
|
83
118
|
|
|
119
|
+
exports.updateMorphColorAttribute = function(targetGeometry, morph) {
|
|
120
|
+
if (morph && targetGeometry && targetGeometry.morphAttributes &&
|
|
121
|
+
targetGeometry.morphAttributes[ "color" ]) {
|
|
122
|
+
const morphColors = targetGeometry.morphAttributes[ "color" ];
|
|
123
|
+
const influences = morph.morphTargetInfluences;
|
|
124
|
+
const length = influences.length;
|
|
125
|
+
targetGeometry.deleteAttribute( 'morphColor0' );
|
|
126
|
+
targetGeometry.deleteAttribute( 'morphColor1' );
|
|
127
|
+
let bound = 0;
|
|
128
|
+
let morphArray = [];
|
|
129
|
+
for (let i = 0; (1 > bound) || (i < length); i++) {
|
|
130
|
+
if (influences[i] > 0) {
|
|
131
|
+
bound++;
|
|
132
|
+
morphArray.push([i, influences[i]]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (morphArray.length == 2) {
|
|
136
|
+
targetGeometry.setAttribute('morphColor0', morphColors[ morphArray[0][0] ] );
|
|
137
|
+
targetGeometry.setAttribute('morphColor1', morphColors[ morphArray[1][0] ] );
|
|
138
|
+
} else if (morphArray.length == 1) {
|
|
139
|
+
targetGeometry.setAttribute('morphColor0', morphColors[ morphArray[0][0] ] );
|
|
140
|
+
targetGeometry.setAttribute('morphColor1', morphColors[ morphArray[0][0] ] );
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
exports.toBufferGeometry = (geometryIn, options) => {
|
|
147
|
+
let geometry = undefined;
|
|
148
|
+
if (geometryIn instanceof THREEGeometry) {
|
|
149
|
+
if (options.localTimeEnabled && !geometryIn.morphNormalsReady &&
|
|
150
|
+
(geometryIn.morphNormals == undefined || geometryIn.morphNormals.length == 0))
|
|
151
|
+
geometryIn.computeMorphNormals();
|
|
152
|
+
geometry = geometryIn.toIndexedBufferGeometry();
|
|
153
|
+
if (options.localMorphColour) {
|
|
154
|
+
copyMorphColorsToIndexedBufferGeometry(geometryIn, geometry);
|
|
155
|
+
}
|
|
156
|
+
} else if (geometryIn instanceof THREE.BufferGeometry) {
|
|
157
|
+
geometry = geometryIn.clone();
|
|
158
|
+
}
|
|
159
|
+
geometry.colorsNeedUpdate = true;
|
|
160
|
+
geometry.computeBoundingBox();
|
|
161
|
+
geometry.computeBoundingSphere();
|
|
162
|
+
if (geometryIn._video)
|
|
163
|
+
geometry._video = geometryIn._video;
|
|
164
|
+
return geometry;
|
|
165
|
+
}
|
|
84
166
|
|
|
85
167
|
exports.copyMorphColorsToBufferGeometry = (geometry, bufferGeometry) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
var attribute = new THREE.Float32BufferAttribute( geometry.faces.length * 3 * 3, 3 );
|
|
103
|
-
attribute.name = morphColor.name;
|
|
104
|
-
array.push( attribute.copyArray( colorArray ) );
|
|
168
|
+
if (geometry && geometry.morphColors && geometry.morphColors.length > 0 ) {
|
|
169
|
+
let array = [];
|
|
170
|
+
let morphColors = geometry.morphColors;
|
|
171
|
+
const getColorsRGB = require("./utilities").getColorsRGB;
|
|
172
|
+
for ( var i = 0, l = morphColors.length; i < l; i ++ ) {
|
|
173
|
+
let morphColor = morphColors[ i ];
|
|
174
|
+
let colorArray = [];
|
|
175
|
+
for ( var j = 0; j < geometry.faces.length; j ++ ) {
|
|
176
|
+
let face = geometry.faces[j];
|
|
177
|
+
let color = getColorsRGB(morphColor.colors, face.a);
|
|
178
|
+
colorArray.push(color[0], color[1], color[2]);
|
|
179
|
+
color = getColorsRGB(morphColor.colors, face.b);
|
|
180
|
+
colorArray.push(color[0], color[1], color[2]);
|
|
181
|
+
color = getColorsRGB(morphColor.colors, face.c);
|
|
182
|
+
colorArray.push(color[0], color[1], color[2]);
|
|
105
183
|
}
|
|
106
|
-
|
|
184
|
+
var attribute = new THREE.Float32BufferAttribute( geometry.faces.length * 3 * 3, 3 );
|
|
185
|
+
attribute.name = morphColor.name;
|
|
186
|
+
array.push( attribute.copyArray( colorArray ) );
|
|
107
187
|
}
|
|
188
|
+
bufferGeometry.morphAttributes[ "color" ] = array;
|
|
108
189
|
}
|
|
190
|
+
}
|
|
109
191
|
|
|
110
192
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
const attribute = new THREE.Float32BufferAttribute( colorArray, 3 );
|
|
124
|
-
attribute.name = morphColor.name;
|
|
125
|
-
array.push( attribute );
|
|
193
|
+
const copyMorphColorsToIndexedBufferGeometry = (geometry, bufferGeometry) => {
|
|
194
|
+
if (geometry && geometry.morphColors && geometry.morphColors.length > 0 ) {
|
|
195
|
+
let array = [];
|
|
196
|
+
let morphColors = geometry.morphColors;
|
|
197
|
+
const getColorsRGB = require("./utilities").getColorsRGB;
|
|
198
|
+
for ( let i = 0, l = morphColors.length; i < l; i ++ ) {
|
|
199
|
+
const morphColor = morphColors[ i ];
|
|
200
|
+
const colorArray = [];
|
|
201
|
+
for ( let j = 0; j < morphColor.colors.length * 3; j ++ ) {
|
|
202
|
+
let color = getColorsRGB(morphColor.colors, j);
|
|
203
|
+
colorArray.push(color[0], color[1], color[2]);
|
|
126
204
|
}
|
|
127
|
-
|
|
205
|
+
const attribute = new THREE.Float32BufferAttribute( colorArray, 3 );
|
|
206
|
+
attribute.name = morphColor.name;
|
|
207
|
+
array.push( attribute );
|
|
128
208
|
}
|
|
209
|
+
bufferGeometry.morphAttributes[ "color" ] = array;
|
|
129
210
|
}
|
|
211
|
+
}
|
|
130
212
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
tolerance = Math.max( tolerance, Number.EPSILON );
|
|
213
|
+
exports.mergeVertices = ( geometry, tolerance = 1e-4 ) => {
|
|
134
214
|
|
|
135
|
-
|
|
136
|
-
// if it's already available.
|
|
137
|
-
var hashToIndex = {};
|
|
138
|
-
var indices = geometry.getIndex();
|
|
139
|
-
var positions = geometry.getAttribute( 'position' );
|
|
140
|
-
var vertexCount = indices ? indices.count : positions.count;
|
|
215
|
+
tolerance = Math.max( tolerance, Number.EPSILON );
|
|
141
216
|
|
|
142
|
-
|
|
143
|
-
|
|
217
|
+
// Generate an index buffer if the geometry doesn't have one, or optimize it
|
|
218
|
+
// if it's already available.
|
|
219
|
+
var hashToIndex = {};
|
|
220
|
+
var indices = geometry.getIndex();
|
|
221
|
+
var positions = geometry.getAttribute( 'position' );
|
|
222
|
+
var vertexCount = indices ? indices.count : positions.count;
|
|
144
223
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
var attrArrays = {};
|
|
148
|
-
var morphAttrsArrays = {};
|
|
149
|
-
var newIndices = [];
|
|
150
|
-
var getters = [ 'getX', 'getY', 'getZ', 'getW' ];
|
|
224
|
+
// next value for triangle indices
|
|
225
|
+
var nextIndex = 0;
|
|
151
226
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
227
|
+
// attributes and new attribute arrays
|
|
228
|
+
var attributeNames = Object.keys( geometry.attributes );
|
|
229
|
+
var attrArrays = {};
|
|
230
|
+
var morphAttrsArrays = {};
|
|
231
|
+
var newIndices = [];
|
|
232
|
+
var getters = [ 'getX', 'getY', 'getZ', 'getW' ];
|
|
155
233
|
|
|
156
|
-
|
|
234
|
+
// initialize the arrays
|
|
235
|
+
for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
|
|
236
|
+
var name = attributeNames[ i ];
|
|
157
237
|
|
|
158
|
-
|
|
159
|
-
if ( morphAttr ) {
|
|
238
|
+
attrArrays[ name ] = [];
|
|
160
239
|
|
|
161
|
-
|
|
240
|
+
var morphAttr = geometry.morphAttributes[ name ];
|
|
241
|
+
if ( morphAttr ) {
|
|
162
242
|
|
|
163
|
-
|
|
243
|
+
morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] );
|
|
164
244
|
|
|
165
|
-
|
|
245
|
+
}
|
|
166
246
|
|
|
167
|
-
|
|
168
|
-
var decimalShift = Math.log10( 1 / tolerance );
|
|
169
|
-
var shiftMultiplier = Math.pow( 10, decimalShift );
|
|
170
|
-
for ( var i = 0; i < vertexCount; i ++ ) {
|
|
247
|
+
}
|
|
171
248
|
|
|
172
|
-
|
|
249
|
+
// convert the error tolerance to an amount of decimal places to truncate to
|
|
250
|
+
var decimalShift = Math.log10( 1 / tolerance );
|
|
251
|
+
var shiftMultiplier = Math.pow( 10, decimalShift );
|
|
252
|
+
for ( var i = 0; i < vertexCount; i ++ ) {
|
|
173
253
|
|
|
174
|
-
|
|
175
|
-
var hash = '';
|
|
176
|
-
for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
254
|
+
var index = indices ? indices.getX( i ) : i;
|
|
177
255
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
256
|
+
// Generate a hash for the vertex attributes at the current index 'i'
|
|
257
|
+
var hash = '';
|
|
258
|
+
for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
181
259
|
|
|
182
|
-
|
|
260
|
+
var name = attributeNames[ j ];
|
|
261
|
+
var attribute = geometry.getAttribute( name );
|
|
262
|
+
var itemSize = attribute.itemSize;
|
|
183
263
|
|
|
184
|
-
|
|
185
|
-
hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`;
|
|
264
|
+
for ( var k = 0; k < itemSize; k ++ ) {
|
|
186
265
|
|
|
187
|
-
|
|
266
|
+
// double tilde truncates the decimal value
|
|
267
|
+
hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * shiftMultiplier ) },`;
|
|
188
268
|
|
|
189
|
-
|
|
269
|
+
}
|
|
190
270
|
|
|
191
|
-
|
|
192
|
-
// used by another index
|
|
193
|
-
if ( hash in hashToIndex ) {
|
|
271
|
+
}
|
|
194
272
|
|
|
195
|
-
|
|
273
|
+
// Add another reference to the vertex if it's already
|
|
274
|
+
// used by another index
|
|
275
|
+
if ( hash in hashToIndex ) {
|
|
196
276
|
|
|
197
|
-
|
|
277
|
+
newIndices.push( hashToIndex[ hash ] );
|
|
198
278
|
|
|
199
|
-
|
|
200
|
-
for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
279
|
+
} else {
|
|
201
280
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
var morphAttr = geometry.morphAttributes[ name ];
|
|
205
|
-
var itemSize = attribute.itemSize;
|
|
206
|
-
var newarray = attrArrays[ name ];
|
|
207
|
-
var newMorphArrays = morphAttrsArrays[ name ];
|
|
281
|
+
// copy data to the new index in the attribute arrays
|
|
282
|
+
for ( var j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
208
283
|
|
|
209
|
-
|
|
284
|
+
var name = attributeNames[ j ];
|
|
285
|
+
var attribute = geometry.getAttribute( name );
|
|
286
|
+
var morphAttr = geometry.morphAttributes[ name ];
|
|
287
|
+
var itemSize = attribute.itemSize;
|
|
288
|
+
var newarray = attrArrays[ name ];
|
|
289
|
+
var newMorphArrays = morphAttrsArrays[ name ];
|
|
210
290
|
|
|
211
|
-
|
|
212
|
-
newarray.push( attribute[ getterFunc ]( index ) );
|
|
291
|
+
for ( var k = 0; k < itemSize; k ++ ) {
|
|
213
292
|
|
|
214
|
-
|
|
293
|
+
var getterFunc = getters[ k ];
|
|
294
|
+
newarray.push( attribute[ getterFunc ]( index ) );
|
|
215
295
|
|
|
216
|
-
|
|
296
|
+
if ( morphAttr ) {
|
|
217
297
|
|
|
218
|
-
|
|
298
|
+
for ( var m = 0, ml = morphAttr.length; m < ml; m ++ ) {
|
|
219
299
|
|
|
220
|
-
|
|
300
|
+
newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) );
|
|
221
301
|
|
|
222
|
-
|
|
302
|
+
}
|
|
223
303
|
|
|
224
|
-
|
|
304
|
+
}
|
|
225
305
|
|
|
226
|
-
|
|
306
|
+
}
|
|
227
307
|
|
|
228
|
-
|
|
229
|
-
newIndices.push( nextIndex );
|
|
230
|
-
nextIndex ++;
|
|
308
|
+
}
|
|
231
309
|
|
|
232
|
-
|
|
310
|
+
hashToIndex[ hash ] = nextIndex;
|
|
311
|
+
newIndices.push( nextIndex );
|
|
312
|
+
nextIndex ++;
|
|
233
313
|
|
|
234
|
-
|
|
314
|
+
}
|
|
235
315
|
|
|
236
|
-
|
|
237
|
-
// the attributeBuffers
|
|
238
|
-
const result = geometry.clone();
|
|
239
|
-
for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
|
|
316
|
+
}
|
|
240
317
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
318
|
+
// Generate typed arrays from new attribute arrays and update
|
|
319
|
+
// the attributeBuffers
|
|
320
|
+
const result = geometry.clone();
|
|
321
|
+
for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
|
|
244
322
|
|
|
245
|
-
|
|
246
|
-
|
|
323
|
+
var name = attributeNames[ i ];
|
|
324
|
+
var oldAttribute = geometry.getAttribute( name );
|
|
325
|
+
var attribute;
|
|
247
326
|
|
|
248
|
-
|
|
327
|
+
var buffer = new oldAttribute.array.constructor( attrArrays[ name ] );
|
|
328
|
+
if ( oldAttribute.isInterleavedBufferAttribute ) {
|
|
249
329
|
|
|
250
|
-
|
|
330
|
+
attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.itemSize );
|
|
251
331
|
|
|
252
|
-
|
|
253
|
-
attribute.setArray( buffer );
|
|
332
|
+
} else {
|
|
254
333
|
|
|
255
|
-
|
|
334
|
+
attribute = geometry.getAttribute( name ).clone();
|
|
335
|
+
attribute.setArray( buffer );
|
|
256
336
|
|
|
257
|
-
|
|
337
|
+
}
|
|
258
338
|
|
|
259
|
-
|
|
260
|
-
if ( name in morphAttrsArrays ) {
|
|
339
|
+
result.setAttribute( name, attribute );
|
|
261
340
|
|
|
262
|
-
|
|
341
|
+
// Update the attribute arrays
|
|
342
|
+
if ( name in morphAttrsArrays ) {
|
|
263
343
|
|
|
264
|
-
|
|
265
|
-
morphAttribute.setArray( new morphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ) );
|
|
266
|
-
result.morphAttributes[ name ][ j ] = morphAttribute;
|
|
344
|
+
for ( var j = 0; j < morphAttrsArrays[ name ].length; j ++ ) {
|
|
267
345
|
|
|
268
|
-
|
|
346
|
+
var morphAttribute = geometry.morphAttributes[ name ][ j ].clone();
|
|
347
|
+
morphAttribute.setArray( new morphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ) );
|
|
348
|
+
result.morphAttributes[ name ][ j ] = morphAttribute;
|
|
269
349
|
|
|
270
|
-
|
|
350
|
+
}
|
|
271
351
|
|
|
272
|
-
|
|
352
|
+
}
|
|
273
353
|
|
|
274
|
-
|
|
275
|
-
var cons = Uint8Array;
|
|
276
|
-
if ( newIndices.length >= Math.pow( 2, 8 ) ) cons = Uint16Array;
|
|
277
|
-
if ( newIndices.length >= Math.pow( 2, 16 ) ) cons = Uint32Array;
|
|
354
|
+
}
|
|
278
355
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
356
|
+
// Generate an index buffer typed array
|
|
357
|
+
var cons = Uint8Array;
|
|
358
|
+
if ( newIndices.length >= Math.pow( 2, 8 ) ) cons = Uint16Array;
|
|
359
|
+
if ( newIndices.length >= Math.pow( 2, 16 ) ) cons = Uint32Array;
|
|
282
360
|
|
|
283
|
-
|
|
361
|
+
var newIndexBuffer = new cons( newIndices );
|
|
362
|
+
var newIndices = null;
|
|
363
|
+
if ( indices === null ) {
|
|
284
364
|
|
|
285
|
-
|
|
365
|
+
newIndices = new THREE.BufferAttribute( newIndexBuffer, 1 );
|
|
286
366
|
|
|
287
|
-
|
|
288
|
-
newIndices.setArray( newIndexBuffer );
|
|
367
|
+
} else {
|
|
289
368
|
|
|
290
|
-
|
|
369
|
+
newIndices = geometry.getIndex().clone();
|
|
370
|
+
newIndices.setArray( newIndexBuffer );
|
|
291
371
|
|
|
292
|
-
|
|
372
|
+
}
|
|
293
373
|
|
|
294
|
-
|
|
374
|
+
result.setIndex( newIndices );
|
|
295
375
|
|
|
376
|
+
return result;
|
|
296
377
|
}
|
|
297
378
|
|
|
298
379
|
function PhongToToon(materialIn) {
|
|
@@ -314,7 +395,7 @@ function PhongToToon(materialIn) {
|
|
|
314
395
|
return materialIn;
|
|
315
396
|
}
|
|
316
397
|
|
|
317
|
-
|
|
398
|
+
exports.getBoundingBox = getBoundingBox;
|
|
318
399
|
exports.resolveURL = resolveURL;
|
|
319
400
|
exports.loadExternalFile = loadExternalFile;
|
|
320
401
|
exports.loadExternalFiles = loadExternalFiles;
|
|
@@ -9,10 +9,10 @@ module.exports = function (self) {
|
|
|
9
9
|
var JSONParser = new JSONLoader();
|
|
10
10
|
var geometry = JSONParser.parse(object);
|
|
11
11
|
var material = new THREE.MeshPhongMaterial();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
var mesh = new THREE.Mesh(geometry.geometry, material);
|
|
13
|
+
var host = new Geometry();
|
|
14
|
+
host.setMorph(mesh);
|
|
15
|
+
return host;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
var initialise = function(object) {
|