Ver Fonte

Canvas3D tweaks:
- update "forceDraw" logic
- Ensure the scene is re-rendered when viewport size changes
- Support noDraw mode in PluginAnimationLoop

dsehnal há 3 anos atrás
pai
commit
0e9238e5ec
3 ficheiros alterados com 31 adições e 14 exclusões
  1. 4 0
      CHANGELOG.md
  2. 18 11
      src/mol-canvas3d/canvas3d.ts
  3. 9 3
      src/mol-plugin/animation-loop.ts

+ 4 - 0
CHANGELOG.md

@@ -17,6 +17,10 @@ Note that since we don't clearly distinguish between a public and private interf
 - Add `operator` Loci granularity, selecting everything with the same operator name.
 - Prefer ``_label_seq_id`` fields in secondary structure assignment.
 - Support new EMDB API (https://www.ebi.ac.uk/emdb/api/entry/map/[EMBD-ID]) for EM volume contour levels.
+- ``Canvas3D`` tweaks:
+    - Update ``forceDraw`` logic.
+    - Ensure the scene is re-rendered when viewport size changes.
+    - Support ``noDraw`` mode in ``PluginAnimationLoop``.
 
 ## [v2.1.0] - 2021-07-05
 

+ 18 - 11
src/mol-canvas3d/canvas3d.ts

@@ -222,9 +222,11 @@ interface Canvas3D {
     animate(): void
     /**
      * Pause animation loop and optionally any rendering
-     * @param noDraw pause any rendering
+     * @param noDraw pause any rendering (drawPaused = true)
      */
     pause(noDraw?: boolean): void
+    /** Sets drawPaused = false without starting the built in animation loop */
+    resume(): void
     identify(x: number, y: number): PickData | undefined
     mark(loci: Representation.Loci, action: MarkerAction): void
     getLoci(pickingId: PickingId | undefined): Representation.Loci
@@ -305,7 +307,6 @@ namespace Canvas3D {
         const interactionHelper = new Canvas3dInteractionHelper(identify, getLoci, input, camera);
         const multiSampleHelper = new MultiSampleHelper(passes.multiSample);
 
-        let drawPending = false;
         let cameraResetRequested = false;
         let nextCameraResetDuration: number | undefined = void 0;
         let nextCameraResetSnapshot: Camera.SnapshotProvider | undefined = void 0;
@@ -373,9 +374,13 @@ namespace Canvas3D {
             let didRender = false;
             controls.update(currentTime);
             const cameraChanged = camera.update();
-            const multiSampleChanged = multiSampleHelper.update(force || cameraChanged, p.multiSample);
 
-            if (resized || force || cameraChanged || multiSampleChanged) {
+            const shouldRender = force || cameraChanged || resized || forceNextRender;
+            forceNextRender = false;
+
+            const multiSampleChanged = multiSampleHelper.update(shouldRender, p.multiSample);
+
+            if (shouldRender || multiSampleChanged) {
                 let cam: Camera | StereoCamera = camera;
                 if (p.camera.stereo.name === 'on') {
                     stereoCamera.update();
@@ -394,24 +399,20 @@ namespace Canvas3D {
             return didRender;
         }
 
-        let forceNextDraw = false;
+        let forceNextRender = false;
         let forceDrawAfterAllCommited = false;
         let currentTime = 0;
         let drawPaused = false;
 
         function draw(force?: boolean) {
             if (drawPaused) return;
-            if (render(!!force || forceNextDraw) && notifyDidDraw) {
+            if (render(!!force) && notifyDidDraw) {
                 didDraw.next(now() - startTime as now.Timestamp);
             }
-            forceNextDraw = false;
-            drawPending = false;
         }
 
         function requestDraw(force?: boolean) {
-            if (drawPending) return;
-            drawPending = true;
-            forceNextDraw = !!force;
+            forceNextRender = forceNextRender || !!force;
         }
 
         let animationFrameHandle = 0;
@@ -703,6 +704,7 @@ namespace Canvas3D {
             animate,
             resetTime,
             pause,
+            resume: () => { drawPaused = false; },
             identify,
             mark,
             getLoci,
@@ -816,6 +818,8 @@ namespace Canvas3D {
         };
 
         function updateViewport() {
+            const oldX = x, oldY = y, oldWidth = width, oldHeight = height;
+
             if (p.viewport.name === 'canvas') {
                 x = 0;
                 y = 0;
@@ -836,6 +840,9 @@ namespace Canvas3D {
                 // console.log({ x, y, width, height });
             }
 
+            if (oldX !== x || oldY !== y || oldWidth !== width || oldHeight !== height) {
+                forceNextRender = true;
+            }
         }
 
         function syncViewport() {

+ 9 - 3
src/mol-plugin/animation-loop.ts

@@ -31,18 +31,24 @@ export class PluginAnimationLoop {
         this.plugin.canvas3d?.resetTime(t);
     }
 
-    start() {
+    start(options?: { immediate?: boolean }) {
+        this.plugin.canvas3d?.resume();
         this._isAnimating = true;
         this.resetTime();
-        this.currentFrame = requestAnimationFrame(this.frame);
+        // TODO: should immediate be the default mode?
+        if (options?.immediate) this.frame();
+        else this.currentFrame = requestAnimationFrame(this.frame);
     }
 
-    stop() {
+    stop(options?: { noDraw?: boolean }) {
         this._isAnimating = false;
         if (this.currentFrame !== void 0) {
             cancelAnimationFrame(this.currentFrame);
             this.currentFrame = void 0;
         }
+        if (options?.noDraw) {
+            this.plugin.canvas3d?.pause(options?.noDraw);
+        }
     }
 
     constructor(private plugin: PluginContext) {