zincjs 2.4.1-beta.3 → 2.4.1-beta.5
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 +86 -70
- package/build/zinc.js +5 -5
- package/build/zinc.js.map +1 -1
- package/package.json +1 -1
- package/src/controls.js +71 -49
- package/src/loaders/GLTFToZincJSLoader.js +4 -1
- package/src/loaders/JSONLoader.js +2 -2
- package/src/loaders/primitivesLoader.js +60 -17
- 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 +33 -7
- 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 +18 -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/texturePrimitive.js +12 -0
- package/src/primitives/textureSlides.js +24 -3
- package/src/primitives/textureVolume.js +2 -0
- package/src/primitives/tubeLines.js +4 -0
- package/src/primitives/zincObject.js +80 -10
- package/src/region.js +92 -37
- package/src/renderRequests.js +20 -0
- package/src/renderer.js +81 -9
- package/src/scene.js +133 -23
- package/src/sceneExporter.js +4 -0
- package/src/sceneLoader.js +114 -18
- package/src/textSprite.js +211 -0
- package/src/texture/texture.js +10 -0
- package/src/texture/textureArray.js +9 -0
- package/src/utilities.js +147 -47
package/src/renderer.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as THREE from 'three/webgpu';
|
|
2
2
|
import { ResizeSensor } from 'css-element-queries';
|
|
3
3
|
import { Scene } from './scene';
|
|
4
|
+
import { onRenderRequest, offRenderRequest } from './renderRequests';
|
|
5
|
+
import { setTextPixelsPerUnit } from './textSprite';
|
|
4
6
|
/**
|
|
5
7
|
* Create a Zinc 3D renderer in the container provided.
|
|
6
8
|
* The primary function of a Zinc 3D renderer is to display the current
|
|
@@ -48,6 +50,15 @@ const Renderer = function (containerIn) {
|
|
|
48
50
|
const _this = this;
|
|
49
51
|
const currentSize = [0, 0];
|
|
50
52
|
const currentOffset = [0, 0];
|
|
53
|
+
//Render on demand is opt-in, when enabled the scene is only drawn when
|
|
54
|
+
//something has changed.
|
|
55
|
+
let renderOnDemand = false;
|
|
56
|
+
let needsRender = true;
|
|
57
|
+
const requestRender = () => {
|
|
58
|
+
needsRender = true;
|
|
59
|
+
}
|
|
60
|
+
//Camera of the current scene shared with additional active scenes
|
|
61
|
+
const sharedCamera = { controls: undefined, updated: false };
|
|
51
62
|
|
|
52
63
|
this.getDrawingWidth = () => {
|
|
53
64
|
if (container) {
|
|
@@ -75,6 +86,7 @@ const Renderer = function (containerIn) {
|
|
|
75
86
|
* Call this to resize the renderer, this is normally call automatically.
|
|
76
87
|
*/
|
|
77
88
|
this.onWindowResize = () => {
|
|
89
|
+
needsRender = true;
|
|
78
90
|
currentScene.onWindowResize();
|
|
79
91
|
//Give it a miniumum size of 1 x 1
|
|
80
92
|
const width = this.getDrawingWidth() || 1;
|
|
@@ -103,6 +115,12 @@ const Renderer = function (containerIn) {
|
|
|
103
115
|
renderer.getSize(target);
|
|
104
116
|
currentSize[0] = target.x;
|
|
105
117
|
currentSize[1] = target.y;
|
|
118
|
+
//Text sprites are drawn at the resolution they occupy on screen
|
|
119
|
+
const fov = currentScene?.camera?.fov;
|
|
120
|
+
if (fov) {
|
|
121
|
+
setTextPixelsPerUnit(currentSize[1] * renderer.getPixelRatio() /
|
|
122
|
+
(2 * Math.tan(fov * Math.PI / 360)));
|
|
123
|
+
}
|
|
106
124
|
}
|
|
107
125
|
}
|
|
108
126
|
|
|
@@ -172,6 +190,7 @@ const Renderer = function (containerIn) {
|
|
|
172
190
|
renderer.autoClear = false;
|
|
173
191
|
const scene = this.createScene("default");
|
|
174
192
|
this.setCurrentScene(scene);
|
|
193
|
+
onRenderRequest(requestRender);
|
|
175
194
|
isInitialised = true;
|
|
176
195
|
}
|
|
177
196
|
}
|
|
@@ -218,6 +237,7 @@ const Renderer = function (containerIn) {
|
|
|
218
237
|
}
|
|
219
238
|
currentScene.setInteractiveControlEnable(true);
|
|
220
239
|
currentScene.setAdditionalScenesGroup(scenesGroup);
|
|
240
|
+
needsRender = true;
|
|
221
241
|
this.onWindowResize();
|
|
222
242
|
}
|
|
223
243
|
}
|
|
@@ -377,6 +397,7 @@ const Renderer = function (containerIn) {
|
|
|
377
397
|
if (!isRendering) {
|
|
378
398
|
clock.reset();
|
|
379
399
|
isRendering = true;
|
|
400
|
+
needsRender = true;
|
|
380
401
|
runAnimation();
|
|
381
402
|
}
|
|
382
403
|
}
|
|
@@ -486,6 +507,41 @@ const Renderer = function (containerIn) {
|
|
|
486
507
|
*/
|
|
487
508
|
this.setPlayRate = playRateIn => {
|
|
488
509
|
playRate = playRateIn;
|
|
510
|
+
needsRender = true;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Enable or disable render on demand, it is disabled by default.
|
|
515
|
+
* When enabled, the scenes are only drawn when something has changed,
|
|
516
|
+
* e.g. camera movement, animation, loading and changes made through
|
|
517
|
+
* the Zinc APIs. Call {@link Renderer#invalidate} after modifying
|
|
518
|
+
* THREE.js objects directly or after changing the THREE.js renderer,
|
|
519
|
+
* e.g. setClearColor.
|
|
520
|
+
* Pre-render callbacks are called on every frame, post-render callbacks
|
|
521
|
+
* are only called when the scenes are drawn.
|
|
522
|
+
*
|
|
523
|
+
* @param {Boolean} flag - Enable or disable render on demand.
|
|
524
|
+
*/
|
|
525
|
+
this.setRenderOnDemand = flag => {
|
|
526
|
+
renderOnDemand = flag ? true : false;
|
|
527
|
+
needsRender = true;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Check if render on demand is enabled.
|
|
532
|
+
*
|
|
533
|
+
* @return {Boolean}
|
|
534
|
+
*/
|
|
535
|
+
this.isRenderOnDemand = () => {
|
|
536
|
+
return renderOnDemand;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Request the scenes to be drawn on the next frame, this is only
|
|
541
|
+
* required when render on demand is enabled.
|
|
542
|
+
*/
|
|
543
|
+
this.invalidate = () => {
|
|
544
|
+
needsRender = true;
|
|
489
545
|
}
|
|
490
546
|
|
|
491
547
|
this.getCurrentTime = () => {
|
|
@@ -534,6 +590,7 @@ const Renderer = function (containerIn) {
|
|
|
534
590
|
cameraOrtho.position.z = 10;
|
|
535
591
|
}
|
|
536
592
|
sceneOrtho.add(object)
|
|
593
|
+
needsRender = true;
|
|
537
594
|
}
|
|
538
595
|
|
|
539
596
|
const createHUDSprites = logoSprite => {
|
|
@@ -575,22 +632,33 @@ const Renderer = function (containerIn) {
|
|
|
575
632
|
}
|
|
576
633
|
clock.update();
|
|
577
634
|
const delta = clock.getDelta();
|
|
578
|
-
currentScene.renderGeometries(playRate, delta, this.playAnimation);
|
|
635
|
+
let changed = currentScene.renderGeometries(playRate, delta, this.playAnimation);
|
|
636
|
+
if (additionalActiveScenes.length > 0) {
|
|
637
|
+
//Additional scenes are displayed with the current scene's camera
|
|
638
|
+
sharedCamera.controls = currentScene.getZincCameraControls();
|
|
639
|
+
sharedCamera.updated = currentScene.isCameraUpdated();
|
|
640
|
+
}
|
|
579
641
|
for(let i = 0; i < additionalActiveScenes.length; i++) {
|
|
580
642
|
const sceneItem = additionalActiveScenes[i];
|
|
581
|
-
sceneItem.renderGeometries(playRate, delta, this.playAnimation)
|
|
643
|
+
if (sceneItem.renderGeometries(playRate, delta, this.playAnimation, sharedCamera))
|
|
644
|
+
changed = true;
|
|
582
645
|
}
|
|
583
|
-
|
|
584
|
-
renderer.clearDepth();
|
|
585
|
-
renderer.render( sceneOrtho, cameraOrtho );
|
|
586
|
-
}
|
|
587
|
-
for (let key of Object.keys(preRenderCallbackFunctions)) {
|
|
646
|
+
for (let key in preRenderCallbackFunctions) {
|
|
588
647
|
if (preRenderCallbackFunctions.hasOwnProperty(key)) {
|
|
589
648
|
preRenderCallbackFunctions[key].call();
|
|
590
649
|
}
|
|
591
650
|
}
|
|
651
|
+
//Pre-render callbacks may have requested a frame
|
|
652
|
+
if (renderOnDemand && !changed && !needsRender) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
needsRender = false;
|
|
592
656
|
currentScene.render(renderer);
|
|
593
|
-
|
|
657
|
+
if (cameraOrtho != undefined && sceneOrtho != undefined) {
|
|
658
|
+
renderer.clearDepth();
|
|
659
|
+
renderer.render( sceneOrtho, cameraOrtho );
|
|
660
|
+
}
|
|
661
|
+
for (let key in postRenderCallbackFunctions) {
|
|
594
662
|
if (postRenderCallbackFunctions.hasOwnProperty(key)) {
|
|
595
663
|
postRenderCallbackFunctions[key].call();
|
|
596
664
|
}
|
|
@@ -639,6 +707,7 @@ const Renderer = function (containerIn) {
|
|
|
639
707
|
if (!this.isSceneActive(additionalScene)) {
|
|
640
708
|
additionalActiveScenes.push(additionalScene);
|
|
641
709
|
scenesGroup.add(additionalScene.getThreeJSScene());
|
|
710
|
+
needsRender = true;
|
|
642
711
|
}
|
|
643
712
|
}
|
|
644
713
|
|
|
@@ -653,6 +722,7 @@ const Renderer = function (containerIn) {
|
|
|
653
722
|
if (sceneItem === additionalScene) {
|
|
654
723
|
additionalActiveScenes.splice(i, 1);
|
|
655
724
|
scenesGroup.remove(additionalScene.getThreeJSScene());
|
|
725
|
+
needsRender = true;
|
|
656
726
|
return;
|
|
657
727
|
}
|
|
658
728
|
}
|
|
@@ -666,6 +736,7 @@ const Renderer = function (containerIn) {
|
|
|
666
736
|
scenesGroup.remove(additionalActiveScenes[i].getThreeJSScene());
|
|
667
737
|
}
|
|
668
738
|
additionalActiveScenes.splice(0,additionalActiveScenes.length);
|
|
739
|
+
needsRender = true;
|
|
669
740
|
}
|
|
670
741
|
|
|
671
742
|
/**
|
|
@@ -686,7 +757,7 @@ const Renderer = function (containerIn) {
|
|
|
686
757
|
preRenderCallbackFunctions = {};
|
|
687
758
|
preRenderCallbackFunctions_id = 0;
|
|
688
759
|
postRenderCallbackFunctions = {};
|
|
689
|
-
|
|
760
|
+
postRenderCallbackFunctions_id = 0;
|
|
690
761
|
contextLostCallbackFunctions = {};
|
|
691
762
|
contextLostCallbackFunctions_id = 0;
|
|
692
763
|
contextRestoredCallbackFunctions = {};
|
|
@@ -697,6 +768,7 @@ const Renderer = function (containerIn) {
|
|
|
697
768
|
const scene = this.createScene("default");
|
|
698
769
|
this.setCurrentScene(scene);
|
|
699
770
|
sensor = undefined;
|
|
771
|
+
offRenderRequest(requestRender);
|
|
700
772
|
renderer?.dispose();
|
|
701
773
|
}
|
|
702
774
|
|
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,11 +1120,12 @@ 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();
|
|
1027
1127
|
this.clearZincObjectRemovedCallbacks();
|
|
1028
|
-
sceneLoader.
|
|
1128
|
+
sceneLoader.cancelPendingLoads();
|
|
1029
1129
|
if (zincCameraControls) {
|
|
1030
1130
|
zincCameraControls.calculateMaxAllowedDistance(this);
|
|
1031
1131
|
}
|
|
@@ -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
|
}
|