zincjs 2.4.1-beta.4 → 2.4.1-beta.6
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 +10 -0
- package/build/zinc.js +3 -3
- package/build/zinc.js.map +1 -1
- package/package.json +1 -1
- package/src/controls.js +71 -49
- package/src/loaders/primitivesLoader.js +59 -16
- package/src/minimap.js +48 -13
- package/src/primitives/geometry.js +2 -0
- package/src/primitives/glyph.js +11 -1
- package/src/primitives/glyphset.js +26 -9
- package/src/primitives/label.js +39 -24
- package/src/primitives/lines.js +2 -0
- package/src/primitives/lines2.js +76 -24
- package/src/primitives/lod.js +11 -4
- package/src/primitives/marker.js +6 -1
- package/src/primitives/markerCluster.js +5 -1
- package/src/primitives/pointset.js +33 -28
- package/src/primitives/textureSlides.js +19 -3
- package/src/primitives/textureVolume.js +2 -0
- package/src/primitives/tubeLines.js +4 -0
- package/src/primitives/zincObject.js +76 -10
- package/src/region.js +85 -35
- package/src/renderRequests.js +20 -0
- package/src/renderer.js +85 -13
- package/src/scene.js +132 -22
- package/src/sceneExporter.js +4 -0
- package/src/sceneLoader.js +58 -19
- package/src/textSprite.js +211 -0
- package/src/tsl/glyphTransform.js +85 -54
- package/src/utilities.js +147 -47
package/src/scene.js
CHANGED
|
@@ -47,6 +47,21 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
47
47
|
const container = containerIn;
|
|
48
48
|
let cameraHelper = undefined;
|
|
49
49
|
let videoHandler = undefined;
|
|
50
|
+
//Set when something has changed and the scene needs to be drawn,
|
|
51
|
+
//used for render on demand.
|
|
52
|
+
let needsRender = true;
|
|
53
|
+
//Set when the camera has been updated on the current frame
|
|
54
|
+
let cameraUpdated = false;
|
|
55
|
+
//Options passed to the objects on every frame
|
|
56
|
+
const renderOptions = {};
|
|
57
|
+
//Values of the display properties on the last frame, changing them
|
|
58
|
+
//requires the scene to be drawn.
|
|
59
|
+
const lastDisplayState = {
|
|
60
|
+
displayMarkers: undefined,
|
|
61
|
+
displayMinimap: undefined,
|
|
62
|
+
displayMiniAxes: undefined,
|
|
63
|
+
playAnimation: undefined,
|
|
64
|
+
};
|
|
50
65
|
let sceneLoader = new SceneLoader(this);
|
|
51
66
|
let minimap = undefined;
|
|
52
67
|
let zincObjectAddedCallbacks = {};
|
|
@@ -130,6 +145,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
130
145
|
|
|
131
146
|
//called from Renderer when panel has been resized
|
|
132
147
|
this.onWindowResize = () => {
|
|
148
|
+
needsRender = true;
|
|
133
149
|
const wHeight = getDrawingHeight();
|
|
134
150
|
this.camera.aspect = getDrawingWidth() / wHeight;
|
|
135
151
|
this.camera.updateProjectionMatrix();
|
|
@@ -142,6 +158,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
142
158
|
* Reset the viewport of this scene to its original state.
|
|
143
159
|
*/
|
|
144
160
|
this.resetView = () => {
|
|
161
|
+
needsRender = true;
|
|
145
162
|
this.onWindowResize();
|
|
146
163
|
zincCameraControls.resetView();
|
|
147
164
|
}
|
|
@@ -150,6 +167,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
150
167
|
* Set the zoom level by unit scroll rate
|
|
151
168
|
*/
|
|
152
169
|
this.changeZoomByScrollRateUnit = unit => {
|
|
170
|
+
needsRender = true;
|
|
153
171
|
zincCameraControls.changeZoomByScrollRateUnit(unit);
|
|
154
172
|
}
|
|
155
173
|
|
|
@@ -178,6 +196,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
178
196
|
* @param {Zinc.Viewport} viewData - Viewport data to be loaded.
|
|
179
197
|
*/
|
|
180
198
|
this.loadView = settings => {
|
|
199
|
+
needsRender = true;
|
|
181
200
|
const viewPort = new Viewport();
|
|
182
201
|
viewPort.setFromObject(settings);
|
|
183
202
|
zincCameraControls.setCurrentCameraSettings(viewPort);
|
|
@@ -214,6 +233,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
214
233
|
* which we the viewport should be displaying.
|
|
215
234
|
*/
|
|
216
235
|
this.viewAllWithBoundingBox = boundingBox => {
|
|
236
|
+
needsRender = true;
|
|
217
237
|
if (boundingBox) {
|
|
218
238
|
const viewport = zincCameraControls.getViewportFromBoundingBox(boundingBox, 1.0);
|
|
219
239
|
zincCameraControls.setCurrentCameraSettings(viewport);
|
|
@@ -226,6 +246,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
226
246
|
* Adjust zoom distance to include all primitives in scene only.
|
|
227
247
|
*/
|
|
228
248
|
this.viewAll = () => {
|
|
249
|
+
needsRender = true;
|
|
229
250
|
const boundingBox = this.getBoundingBox();
|
|
230
251
|
this.viewAllWithBoundingBox(boundingBox);
|
|
231
252
|
markerCluster.markerUpdateRequired = true;
|
|
@@ -400,6 +421,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
400
421
|
* @returns {THREE.Vector3}
|
|
401
422
|
*/
|
|
402
423
|
this.addZincObject = zincObject => {
|
|
424
|
+
needsRender = true;
|
|
403
425
|
if (zincObject) {
|
|
404
426
|
rootRegion.addZincObject(zincObject);
|
|
405
427
|
if (zincCameraControls)
|
|
@@ -530,6 +552,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
530
552
|
|
|
531
553
|
//Update the directional light for this scene.
|
|
532
554
|
this.updateDirectionalLight = () => {
|
|
555
|
+
needsRender = true;
|
|
533
556
|
zincCameraControls.updateDirectionalLight();
|
|
534
557
|
}
|
|
535
558
|
|
|
@@ -538,6 +561,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
538
561
|
* @param {THREE.Object} object - to be addded into this scene.
|
|
539
562
|
*/
|
|
540
563
|
this.addObject = object => {
|
|
564
|
+
needsRender = true;
|
|
541
565
|
scene.add(object);
|
|
542
566
|
}
|
|
543
567
|
|
|
@@ -546,6 +570,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
546
570
|
* @param {THREE.Object} object - to be removed from this scene.
|
|
547
571
|
*/
|
|
548
572
|
this.removeObject = object => {
|
|
573
|
+
needsRender = true;
|
|
549
574
|
scene.remove(object);
|
|
550
575
|
}
|
|
551
576
|
|
|
@@ -569,6 +594,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
569
594
|
* @param {Number} time - Value to set the time to.
|
|
570
595
|
*/
|
|
571
596
|
this.setMorphsTime = (time) => {
|
|
597
|
+
needsRender = true;
|
|
572
598
|
if (videoHandler != undefined) {
|
|
573
599
|
videoHandler.setMorphTime(time, duration);
|
|
574
600
|
}
|
|
@@ -591,16 +617,22 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
591
617
|
* Update geometries and glyphsets based on the calculated time.
|
|
592
618
|
* @private
|
|
593
619
|
*/
|
|
594
|
-
this.renderGeometries = (playRate, delta, playAnimation) => {
|
|
595
|
-
//
|
|
596
|
-
let
|
|
597
|
-
|
|
620
|
+
this.renderGeometries = (playRate, delta, playAnimation, sharedCamera) => {
|
|
621
|
+
//Anything requested since the last frame
|
|
622
|
+
let changed = needsRender;
|
|
623
|
+
needsRender = false;
|
|
624
|
+
cameraUpdated = false;
|
|
625
|
+
//Additional active scenes are displayed with the current scene's camera
|
|
626
|
+
const cameraControls = sharedCamera ? sharedCamera.controls : zincCameraControls;
|
|
627
|
+
//Reused on every frame to avoid allocations
|
|
628
|
+
const options = renderOptions;
|
|
629
|
+
options.camera = cameraControls;
|
|
598
630
|
//Global markers flag, marker can be set at individual zinc object level
|
|
599
631
|
//overriding this flag.
|
|
600
632
|
options.displayMarkers = this.displayMarkers;
|
|
601
633
|
options.markerCluster = markerCluster;
|
|
602
634
|
options.markersList = markerCluster.markers;
|
|
603
|
-
options.ndcToBeUpdated = false;
|
|
635
|
+
options.ndcToBeUpdated = sharedCamera ? sharedCamera.updated : false;
|
|
604
636
|
//Always set marker cluster update required when playAnimation is true
|
|
605
637
|
//to make sure it is updated when it stops
|
|
606
638
|
if (playAnimation) {
|
|
@@ -616,29 +648,90 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
616
648
|
const currentTime = videoHandler.video.currentTime /
|
|
617
649
|
videoHandler.getVideoDuration() * duration;
|
|
618
650
|
if (0 == sceneLoader.toBeDownloaded) {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
651
|
+
if (!sharedCamera) {
|
|
652
|
+
zincCameraControls.setTime(currentTime);
|
|
653
|
+
options.ndcToBeUpdated = zincCameraControls.update(0);
|
|
654
|
+
if (options.ndcToBeUpdated) {
|
|
655
|
+
zincCameraControls.calculateHeightPerPixelAtZeroDepth(getDrawingHeight());
|
|
656
|
+
}
|
|
623
657
|
}
|
|
624
658
|
rootRegion.setMorphTime(currentTime, true);
|
|
625
|
-
rootRegion.renderGeometries(0, 0, playAnimation,
|
|
626
|
-
} else {
|
|
627
|
-
|
|
659
|
+
rootRegion.renderGeometries(0, 0, playAnimation, cameraControls, options, true);
|
|
660
|
+
} else if (!sharedCamera && zincCameraControls.update(0)) {
|
|
661
|
+
changed = true;
|
|
662
|
+
cameraUpdated = true;
|
|
628
663
|
}
|
|
629
664
|
//console.log(videoHandler.video.currentTime / videoHandler.getVideoDuration() * 6000);
|
|
630
665
|
}
|
|
666
|
+
//The video texture changes while playing or loading
|
|
667
|
+
if (playAnimation || !videoHandler.isReadyToPlay())
|
|
668
|
+
changed = true;
|
|
631
669
|
} else {
|
|
632
670
|
if (0 == sceneLoader.toBeDownloaded) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
671
|
+
if (!sharedCamera) {
|
|
672
|
+
options.ndcToBeUpdated = zincCameraControls.update(delta);
|
|
673
|
+
if (options.ndcToBeUpdated) {
|
|
674
|
+
zincCameraControls.calculateHeightPerPixelAtZeroDepth(getDrawingHeight());
|
|
675
|
+
}
|
|
636
676
|
}
|
|
637
|
-
rootRegion.renderGeometries(playRate, delta, playAnimation,
|
|
638
|
-
} else {
|
|
639
|
-
|
|
677
|
+
rootRegion.renderGeometries(playRate, delta, playAnimation, cameraControls, options, true);
|
|
678
|
+
} else if (!sharedCamera && zincCameraControls.update(0)) {
|
|
679
|
+
changed = true;
|
|
680
|
+
cameraUpdated = true;
|
|
640
681
|
}
|
|
641
682
|
}
|
|
683
|
+
//These are plain properties, check if they have changed
|
|
684
|
+
if (lastDisplayState.displayMarkers !== this.displayMarkers ||
|
|
685
|
+
lastDisplayState.displayMinimap !== this.displayMinimap ||
|
|
686
|
+
lastDisplayState.displayMiniAxes !== this.displayMiniAxes ||
|
|
687
|
+
lastDisplayState.playAnimation !== playAnimation) {
|
|
688
|
+
lastDisplayState.displayMarkers = this.displayMarkers;
|
|
689
|
+
lastDisplayState.displayMinimap = this.displayMinimap;
|
|
690
|
+
lastDisplayState.displayMiniAxes = this.displayMiniAxes;
|
|
691
|
+
lastDisplayState.playAnimation = playAnimation;
|
|
692
|
+
changed = true;
|
|
693
|
+
}
|
|
694
|
+
//The flag is only cleared when the minimap is drawn
|
|
695
|
+
if (this.minimapScissor.updateRequired &&
|
|
696
|
+
(this.displayMinimap || this.displayMiniAxes)) {
|
|
697
|
+
changed = true;
|
|
698
|
+
}
|
|
699
|
+
if (!sharedCamera && options.ndcToBeUpdated)
|
|
700
|
+
cameraUpdated = true;
|
|
701
|
+
if (options.ndcToBeUpdated ||
|
|
702
|
+
(playAnimation && this.isTimeVarying()) ||
|
|
703
|
+
//Objects appear as they are loaded
|
|
704
|
+
sceneLoader.toBeDownloaded > 0 ||
|
|
705
|
+
//Clusters are recalculated on a later frame
|
|
706
|
+
(markerCluster.isEnabled() && markerCluster.markerUpdateRequired)) {
|
|
707
|
+
changed = true;
|
|
708
|
+
}
|
|
709
|
+
//Changes made during this frame, e.g. LOD switching
|
|
710
|
+
if (needsRender) {
|
|
711
|
+
changed = true;
|
|
712
|
+
needsRender = false;
|
|
713
|
+
}
|
|
714
|
+
return changed;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Request this scene to be drawn on the next frame, this is only
|
|
719
|
+
* required when render on demand is enabled on the renderer.
|
|
720
|
+
* See {@link Renderer#setRenderOnDemand}.
|
|
721
|
+
*/
|
|
722
|
+
this.invalidate = () => {
|
|
723
|
+
needsRender = true;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Check if the camera of this scene has been updated during the last
|
|
728
|
+
* call to renderGeometries.
|
|
729
|
+
*
|
|
730
|
+
* @return {Boolean}
|
|
731
|
+
* @private
|
|
732
|
+
*/
|
|
733
|
+
this.isCameraUpdated = () => {
|
|
734
|
+
return cameraUpdated;
|
|
642
735
|
}
|
|
643
736
|
|
|
644
737
|
/**
|
|
@@ -650,6 +743,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
650
743
|
}
|
|
651
744
|
|
|
652
745
|
this.setVideoHandler = (videoHandlerIn) => {
|
|
746
|
+
needsRender = true;
|
|
653
747
|
if (!videoHandler)
|
|
654
748
|
videoHandler = videoHandlerIn;
|
|
655
749
|
}
|
|
@@ -770,6 +864,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
770
864
|
* @param {Number} durationIn - duration of the scene.
|
|
771
865
|
*/
|
|
772
866
|
this.setDuration = durationIn => {
|
|
867
|
+
needsRender = true;
|
|
773
868
|
rootRegion.setDuration(durationIn);
|
|
774
869
|
duration = durationIn;
|
|
775
870
|
zincCameraControls.setPathDuration(durationIn);
|
|
@@ -790,6 +885,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
790
885
|
* should be enabled or disabled.
|
|
791
886
|
*/
|
|
792
887
|
this.setStereoEffectEnable = stereoFlag => {
|
|
888
|
+
needsRender = true;
|
|
793
889
|
if (stereoFlag == true) {
|
|
794
890
|
if (!stereoEffect) {
|
|
795
891
|
stereoEffect = new StereoEffect(rendererIn);
|
|
@@ -819,6 +915,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
819
915
|
* @param {Number} transitionTime - Duration to perform the transition.
|
|
820
916
|
*/
|
|
821
917
|
this.alignBoundingBoxToCameraView = (boundingBox, transitionTime) => {
|
|
918
|
+
needsRender = true;
|
|
822
919
|
if (boundingBox) {
|
|
823
920
|
boundingBox.getCenter(_v3);
|
|
824
921
|
const viewport = this.getZincCameraControls().getCurrentViewport();
|
|
@@ -886,6 +983,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
886
983
|
* @param {ZincObject} zincObject - the bounding box to target
|
|
887
984
|
*/
|
|
888
985
|
this.setCameraTargetToObject = zincObject => {
|
|
986
|
+
needsRender = true;
|
|
889
987
|
if (this.objectIsInScene(zincObject)) {
|
|
890
988
|
const boundingBox = zincObject.getBoundingBox();
|
|
891
989
|
const viewport = this.getZincCameraControls().getCurrentViewport();
|
|
@@ -923,6 +1021,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
923
1021
|
* @param {Zinc.Object} zincObject - object to be removed from this scene.
|
|
924
1022
|
*/
|
|
925
1023
|
this.removeZincObject = zincObject => {
|
|
1024
|
+
needsRender = true;
|
|
926
1025
|
rootRegion.removeZincObject(zincObject);
|
|
927
1026
|
if (zincCameraControls) {
|
|
928
1027
|
zincCameraControls.calculateMaxAllowedDistance(this);
|
|
@@ -1021,6 +1120,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1021
1120
|
* This does not remove obejcts that are added using the addObject APIs.
|
|
1022
1121
|
*/
|
|
1023
1122
|
this.clearAll = () => {
|
|
1123
|
+
needsRender = true;
|
|
1024
1124
|
markerCluster.clear();
|
|
1025
1125
|
rootRegion.clear(true);
|
|
1026
1126
|
this.clearZincObjectAddedCallbacks();
|
|
@@ -1259,6 +1359,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1259
1359
|
* with clearTemporaryPrimitives method.
|
|
1260
1360
|
*/
|
|
1261
1361
|
this.addTemporaryPoints = (coords, colour) => {
|
|
1362
|
+
needsRender = true;
|
|
1262
1363
|
const geometry = createPointQuadGeometry(coords.length);
|
|
1263
1364
|
const material = createInstancedPointsMaterial(getCircularTexture());
|
|
1264
1365
|
material.color.set(colour);
|
|
@@ -1266,13 +1367,11 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1266
1367
|
material.userData.uniforms.pointSize.value = 15;
|
|
1267
1368
|
material.alphaTest = 0.5;
|
|
1268
1369
|
const point = new InstancedPoints(geometry, material, coords.length);
|
|
1269
|
-
point.pointPositions = new Float32Array(coords.length * 3);
|
|
1270
1370
|
const instancePosition = geometry.getAttribute('instancePosition');
|
|
1371
|
+
//Share the array with the instance positions
|
|
1372
|
+
point.pointPositions = instancePosition.array;
|
|
1271
1373
|
coords.forEach((coord, index) => {
|
|
1272
1374
|
instancePosition.setXYZ(index, coord[0], coord[1], coord[2]);
|
|
1273
|
-
point.pointPositions[index * 3] = coord[0];
|
|
1274
|
-
point.pointPositions[index * 3 + 1] = coord[1];
|
|
1275
|
-
point.pointPositions[index * 3 + 2] = coord[2];
|
|
1276
1375
|
});
|
|
1277
1376
|
instancePosition.needsUpdate = true;
|
|
1278
1377
|
tempGroup.add(point);
|
|
@@ -1284,6 +1383,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1284
1383
|
* with clearTemporaryPrimitives method.
|
|
1285
1384
|
*/
|
|
1286
1385
|
this.addTemporaryLines = (coords, colour) => {
|
|
1386
|
+
needsRender = true;
|
|
1287
1387
|
const geometry = createBufferGeometry(coords.length, coords);
|
|
1288
1388
|
const material = new THREE.LineBasicMaterial({color:colour});
|
|
1289
1389
|
const line = new LineSegments(geometry, material);
|
|
@@ -1296,6 +1396,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1296
1396
|
* Display frustum
|
|
1297
1397
|
*/
|
|
1298
1398
|
this.enableFrustumDisplay = () => {
|
|
1399
|
+
needsRender = true;
|
|
1299
1400
|
if (this.camera && !cameraHelper) {
|
|
1300
1401
|
cameraHelper = new THREE.CameraHelper(this.camera);
|
|
1301
1402
|
scene.add(cameraHelper);
|
|
@@ -1306,6 +1407,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1306
1407
|
* Hide frustum
|
|
1307
1408
|
*/
|
|
1308
1409
|
this.disableFrustumDisplay = () => {
|
|
1410
|
+
needsRender = true;
|
|
1309
1411
|
if (cameraHelper) {
|
|
1310
1412
|
scene.remove(cameraHelper);
|
|
1311
1413
|
cameraHelper.dispose();
|
|
@@ -1317,6 +1419,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1317
1419
|
* Remove object from temporary objects list
|
|
1318
1420
|
*/
|
|
1319
1421
|
this.removeTemporaryPrimitive = (object) => {
|
|
1422
|
+
needsRender = true;
|
|
1320
1423
|
tempGroup.remove(object);
|
|
1321
1424
|
object.geometry.dispose();
|
|
1322
1425
|
object.material.dispose();
|
|
@@ -1327,6 +1430,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1327
1430
|
* Return number of primitives removed;
|
|
1328
1431
|
*/
|
|
1329
1432
|
this.clearTemporaryPrimitives = () => {
|
|
1433
|
+
needsRender = true;
|
|
1330
1434
|
let i = 0;
|
|
1331
1435
|
const children = tempGroup.children;
|
|
1332
1436
|
children.forEach(child => {
|
|
@@ -1344,6 +1448,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1344
1448
|
*/
|
|
1345
1449
|
this.addBoundingBoxPrimitive = (regionPath, group, colour, opacity,
|
|
1346
1450
|
visibility, boundingBox = undefined) => {
|
|
1451
|
+
needsRender = true;
|
|
1347
1452
|
let region = rootRegion.findChildFromPath(regionPath);
|
|
1348
1453
|
if (region === undefined) {
|
|
1349
1454
|
region = rootRegion.createChildFromPath(regionPath);
|
|
@@ -1365,6 +1470,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1365
1470
|
*/
|
|
1366
1471
|
this.addSlicesPrimitive = (regionPath, groups, colours, opacity,
|
|
1367
1472
|
visibility, boundingBox = undefined) => {
|
|
1473
|
+
needsRender = true;
|
|
1368
1474
|
if (groups && groups.length >= 3 &&
|
|
1369
1475
|
colours && colours.length >= 3) {
|
|
1370
1476
|
let region = rootRegion.findChildFromPath(regionPath);
|
|
@@ -1418,6 +1524,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1418
1524
|
* Enable marker cluster to work with markers
|
|
1419
1525
|
*/
|
|
1420
1526
|
this.enableMarkerCluster = (flag) => {
|
|
1527
|
+
needsRender = true;
|
|
1421
1528
|
if (flag) {
|
|
1422
1529
|
markerCluster.markerUpdateRequired = true;
|
|
1423
1530
|
markerCluster.enable();
|
|
@@ -1432,6 +1539,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1432
1539
|
* Destory static axis display object
|
|
1433
1540
|
*/
|
|
1434
1541
|
this.destroyAxisDisplay = () => {
|
|
1542
|
+
needsRender = true;
|
|
1435
1543
|
this.displayMiniAxes = false;
|
|
1436
1544
|
if (axisDisplay.main) {
|
|
1437
1545
|
this.enableAxisDisplay(false, false);
|
|
@@ -1459,6 +1567,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1459
1567
|
* Create static axis display object
|
|
1460
1568
|
*/
|
|
1461
1569
|
this.createAxisDisplay = (fitBoundingBox = false) => {
|
|
1570
|
+
needsRender = true;
|
|
1462
1571
|
this.destroyAxisDisplay();
|
|
1463
1572
|
const XYZ = [
|
|
1464
1573
|
{
|
|
@@ -1511,6 +1620,7 @@ const Scene = function (containerIn, rendererIn) {
|
|
|
1511
1620
|
* before the axis can be display.
|
|
1512
1621
|
*/
|
|
1513
1622
|
this.enableAxisDisplay = (enable, miniaxes = false) => {
|
|
1623
|
+
needsRender = true;
|
|
1514
1624
|
if (miniaxes && axisDisplay?.mini?.length) {
|
|
1515
1625
|
this.displayMiniAxes = enable;
|
|
1516
1626
|
axisDisplay.mini.forEach(axis => {
|
package/src/sceneExporter.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BufferAttribute } from 'three/webgpu';
|
|
2
2
|
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter';
|
|
3
|
+
import { useStandardIndexType } from './utilities';
|
|
3
4
|
|
|
4
5
|
/*
|
|
5
6
|
* GLTFExporter only writes POSITION and NORMAL morph targets. glTF allows
|
|
@@ -89,6 +90,8 @@ const SceneExporter = function (sceneIn) {
|
|
|
89
90
|
glyphsetsToRestore.push(zincObject);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
93
|
+
//GLTFExporter only accepts plain typed arrays
|
|
94
|
+
const restoreIndexType = useStandardIndexType(scene.getThreeJSScene());
|
|
92
95
|
const exporter = new GLTFExporter();
|
|
93
96
|
exporter.register(writer => new GLTFMorphColourPlugin(writer));
|
|
94
97
|
const options = { binary, animations, onlyVisible: true };
|
|
@@ -106,6 +109,7 @@ const SceneExporter = function (sceneIn) {
|
|
|
106
109
|
options );
|
|
107
110
|
});
|
|
108
111
|
} finally {
|
|
112
|
+
restoreIndexType();
|
|
109
113
|
glyphsetsToRestore.forEach(zincObject => zincObject.clearColorExportState());
|
|
110
114
|
}
|
|
111
115
|
}
|
package/src/sceneLoader.js
CHANGED
|
@@ -27,8 +27,6 @@ const SceneLoader = function (sceneIn) {
|
|
|
27
27
|
this.progressMap = {};
|
|
28
28
|
let viewLoaded = false;
|
|
29
29
|
let errorDownload = false;
|
|
30
|
-
//Incremented when pending loads are cancelled, loads requested
|
|
31
|
-
//before the increment are discarded once they complete.
|
|
32
30
|
let generation = 0;
|
|
33
31
|
const primitivesLoader = new PrimitivesLoader();
|
|
34
32
|
|
|
@@ -450,7 +448,8 @@ const SceneLoader = function (sceneIn) {
|
|
|
450
448
|
const loader = new STLLoader();
|
|
451
449
|
loader.crossOrigin = "Anonymous";
|
|
452
450
|
loader.load(url, meshloader(region, colour, opacity, false,
|
|
453
|
-
false, groupName, undefined, undefined,
|
|
451
|
+
false, groupName, undefined, undefined, {}, finishCallback),
|
|
452
|
+
this.onProgress(url), this.onError(finishCallback));
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
/**
|
|
@@ -468,8 +467,9 @@ const SceneLoader = function (sceneIn) {
|
|
|
468
467
|
const opacity = Zinc.defaultOpacity;
|
|
469
468
|
const loader = new OBJLoader();
|
|
470
469
|
loader.crossOrigin = "Anonymous";
|
|
471
|
-
loader.load(url,
|
|
472
|
-
false, groupName, undefined, undefined,
|
|
470
|
+
loader.load(url, objloader(region, colour, opacity, false,
|
|
471
|
+
false, groupName, undefined, undefined, {}, finishCallback),
|
|
472
|
+
this.onProgress(url), this.onError(finishCallback));
|
|
473
473
|
}
|
|
474
474
|
|
|
475
475
|
/**
|
|
@@ -500,17 +500,14 @@ const SceneLoader = function (sceneIn) {
|
|
|
500
500
|
if (morphColour != undefined)
|
|
501
501
|
localMorphColour = morphColour ? true : false;
|
|
502
502
|
let loader = primitivesLoader;
|
|
503
|
-
if (fileFormat
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
options.loaderOptions);
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
503
|
+
if (fileFormat == "STL" || fileFormat == "OBJ") {
|
|
504
|
+
const typedLoader = fileFormat == "STL" ? meshloader : objloader;
|
|
505
|
+
loader = fileFormat == "STL" ? new STLLoader() : new OBJLoader();
|
|
506
|
+
loader.crossOrigin = "Anonymous";
|
|
507
|
+
loader.load(url, typedLoader(region, colour, opacity, localTimeEnabled,
|
|
508
|
+
localMorphColour, groupName, anatomicalId, renderOrder, options ? options : {},
|
|
509
|
+
finishCallback), this.onProgress(url), this.onError(finishCallback));
|
|
510
|
+
return;
|
|
514
511
|
}
|
|
515
512
|
if (isInline) {
|
|
516
513
|
const object = primitivesLoader.parse( url );
|
|
@@ -723,7 +720,7 @@ const SceneLoader = function (sceneIn) {
|
|
|
723
720
|
}
|
|
724
721
|
const zincGeometry = addZincGeometry(region, geometry, colour, opacity,
|
|
725
722
|
localTimeEnabled, localMorphColour, undefined, material, groupName, renderOrder, anatomicalId);
|
|
726
|
-
if (options
|
|
723
|
+
if (options?.lod?.levels) {
|
|
727
724
|
for (const [key, value] of Object.entries(options.lod.levels)) {
|
|
728
725
|
zincGeometry.addLOD(primitivesLoader, key, value.URL, value.Index, options.lod.preload);
|
|
729
726
|
}
|
|
@@ -736,6 +733,48 @@ const SceneLoader = function (sceneIn) {
|
|
|
736
733
|
};
|
|
737
734
|
}
|
|
738
735
|
|
|
736
|
+
//Internal loader for OBJ files, OBJLoader returns a group and each mesh
|
|
737
|
+
//in it is added as a separate zinc geometry.
|
|
738
|
+
const objloader = (
|
|
739
|
+
region,
|
|
740
|
+
colour,
|
|
741
|
+
opacity,
|
|
742
|
+
localTimeEnabled,
|
|
743
|
+
localMorphColour,
|
|
744
|
+
groupName,
|
|
745
|
+
anatomicalId,
|
|
746
|
+
renderOrder,
|
|
747
|
+
options,
|
|
748
|
+
finishCallback
|
|
749
|
+
) => {
|
|
750
|
+
const isStale = createStaleCheck();
|
|
751
|
+
const onMeshLoaded = meshloader(region, colour, opacity, localTimeEnabled,
|
|
752
|
+
localMorphColour, groupName, anatomicalId, renderOrder, options, finishCallback);
|
|
753
|
+
return (group) => {
|
|
754
|
+
const meshes = [];
|
|
755
|
+
group.traverse((child) => {
|
|
756
|
+
if (child.isMesh && child.geometry) {
|
|
757
|
+
meshes.push(child);
|
|
758
|
+
}
|
|
759
|
+
if (child.material) {
|
|
760
|
+
const materials = Array.isArray(child.material) ? child.material : [child.material];
|
|
761
|
+
materials.forEach((material) => material.dispose());
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
if (isStale()) {
|
|
765
|
+
meshes.forEach((mesh) => mesh.geometry.dispose());
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
if (meshes.length === 0) {
|
|
769
|
+
--this.toBeDownloaded;
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
//meshloader decrements the counter once per mesh
|
|
773
|
+
this.toBeDownloaded += meshes.length - 1;
|
|
774
|
+
meshes.forEach((mesh) => onMeshLoaded(mesh.geometry));
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
|
|
739
778
|
//Turn ISO 8601 duration string into an array.
|
|
740
779
|
const parseDuration = (durationString) => {
|
|
741
780
|
const regex = /P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/;
|
|
@@ -1017,9 +1056,9 @@ const SceneLoader = function (sceneIn) {
|
|
|
1017
1056
|
// view file does not receive callback
|
|
1018
1057
|
let callback = new metaFinishCallback(numberOfObjects, finishCallback, allCompletedCallback);
|
|
1019
1058
|
// Prioritise the view file and settings before loading anything else
|
|
1020
|
-
for (let i = 0; i <
|
|
1059
|
+
for (let i = 0; i < filteredMetada.length; i++)
|
|
1021
1060
|
readViewAndSettingsItem(referenceURL, filteredMetada[i], callback);
|
|
1022
|
-
for (let i = 0; i <
|
|
1061
|
+
for (let i = 0; i < filteredMetada.length; i++) {
|
|
1023
1062
|
readVersionOneRegionPath(targetRegion, referenceURL, filteredMetada[i], i, callback);
|
|
1024
1063
|
}
|
|
1025
1064
|
}
|