three-cad-viewer 5.1.0 → 5.1.1

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.
@@ -92269,6 +92269,20 @@ void main() {
92269
92269
  this.tracks = [];
92270
92270
  this.root = null;
92271
92271
  }
92272
+ /**
92273
+ * Apply the current animation time to the objects without advancing it, so a
92274
+ * single on-demand render shows the pose (e.g. after {@link setRelativeTime}).
92275
+ */
92276
+ apply() {
92277
+ this.mixer?.update(0);
92278
+ }
92279
+ /**
92280
+ * Restart the frame-time measurement, so resuming playback after a pause does
92281
+ * not advance the animation by the whole pause.
92282
+ */
92283
+ resetClock() {
92284
+ this.clock.reset();
92285
+ }
92272
92286
  /**
92273
92287
  * Update the animation mixer (call each frame when animating).
92274
92288
  */
@@ -97840,7 +97854,7 @@ void main() {
97840
97854
  }
97841
97855
  }
97842
97856
 
97843
- const version = "5.1.0";
97857
+ const version = "5.1.1";
97844
97858
 
97845
97859
  /**
97846
97860
  * `PickedComponent` over a GPU id-pick result. Drives the shader
@@ -109435,6 +109449,8 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
109435
109449
  * @param updateMarker - enforce to redraw orientation marker after every ui activity
109436
109450
  */
109437
109451
  constructor(display, options, notifyCallback, pinAsPngCallback = null, updateMarker = true) {
109452
+ /** Reasons for continuous rendering; the render loop runs while any is set. */
109453
+ this._loopReasons = new Set();
109438
109454
  // Hide-undo stack: each meta-double-click hide pushes the leaf id + its pre-hide
109439
109455
  // state; meta-double-click on empty space pops and restores the last one. Lets a
109440
109456
  // hidden object be brought back without the tree (e.g. in Studio, where it's hidden).
@@ -109870,12 +109886,15 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
109870
109886
  this.clipAction.paused = false;
109871
109887
  }
109872
109888
  this.clipAction.play();
109889
+ this._setAnimationPlaying(true);
109873
109890
  break;
109874
109891
  case "pause":
109875
109892
  this.clipAction.paused = !this.clipAction.paused;
109893
+ this._setAnimationPlaying(!this.clipAction.paused && this.clipAction.isRunning());
109876
109894
  break;
109877
109895
  case "stop":
109878
109896
  this.clipAction.stop();
109897
+ this._setAnimationPlaying(false);
109879
109898
  break;
109880
109899
  }
109881
109900
  };
@@ -110765,10 +110784,7 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
110765
110784
  return Promise.resolve({ task: taskId, dataUrl: null });
110766
110785
  }
110767
110786
  // canvas.toBlob can be very slow when animation loop is off!
110768
- const animationLoop = this.hasAnimationLoop;
110769
- if (!animationLoop) {
110770
- this.toggleAnimationLoop(true);
110771
- }
110787
+ this.setLoopReason("capture", true);
110772
110788
  this.rendered.orientationMarker.setVisible(false);
110773
110789
  this.update(true);
110774
110790
  return this.display.captureCanvas({
@@ -110786,10 +110802,8 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
110786
110802
  }
110787
110803
  },
110788
110804
  onComplete: () => {
110789
- // Restore animation loop to original state
110790
- if (!animationLoop) {
110791
- this.toggleAnimationLoop(false);
110792
- }
110805
+ // Restore the loop to what the other reasons need
110806
+ this.setLoopReason("capture", false);
110793
110807
  this.rendered.orientationMarker.setVisible(true);
110794
110808
  this.update(true);
110795
110809
  },
@@ -111187,14 +111201,13 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
111187
111201
  return;
111188
111202
  }
111189
111203
  logger.debug("Animation initialized");
111190
- if (!this.hasAnimationLoop) {
111191
- this.toggleAnimationLoop(true);
111192
- }
111193
111204
  this.state.set("animationMode", label === "E" ? "explode" : "animation");
111194
111205
  this._animationStarted = false;
111195
111206
  this.clipAction = this.animation.animate(this.rendered.nestedGroup.rootGroup, duration, speed, repeat);
111196
111207
  // Reset animation slider to start
111197
111208
  this.state.set("animationSliderValue", 0);
111209
+ // Not playing yet: render on demand only (the loop starts with Play).
111210
+ this._setAnimationPlaying(false);
111198
111211
  }
111199
111212
  /**
111200
111213
  * Check whether animation object exists
@@ -111211,7 +111224,7 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
111211
111224
  }
111212
111225
  this.state.set("animationMode", "none");
111213
111226
  this._animationStarted = false;
111214
- this.toggleAnimationLoop(false);
111227
+ this.setLoopReason("animation", false);
111215
111228
  }
111216
111229
  /**
111217
111230
  * Set the animation to a specific relative time (0-1).
@@ -111223,6 +111236,8 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
111223
111236
  this._animationStarted = true;
111224
111237
  this.animation.setRelativeTime(fraction);
111225
111238
  this.state.set("animationSliderValue", fraction * 1000);
111239
+ // Setting a time pauses the animation: stop the loop and show the new pose.
111240
+ this._setAnimationPlaying(false);
111226
111241
  }
111227
111242
  /**
111228
111243
  * Get the current relative animation time (0-1).
@@ -111231,6 +111246,44 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
111231
111246
  getRelativeTime() {
111232
111247
  return this.animation.getRelativeTime();
111233
111248
  }
111249
+ /**
111250
+ * Add or remove a reason for continuous rendering. The render loop runs while at
111251
+ * least one reason is set; otherwise the viewer renders on demand (camera changes
111252
+ * and explicit updates), so an idle viewer costs no CPU/GPU time.
111253
+ * @param reason - why continuous rendering is needed.
111254
+ * @param flag - whether the reason applies.
111255
+ */
111256
+ setLoopReason(reason, flag) {
111257
+ if (flag) {
111258
+ this._loopReasons.add(reason);
111259
+ }
111260
+ else {
111261
+ this._loopReasons.delete(reason);
111262
+ }
111263
+ const run = this._loopReasons.size > 0;
111264
+ if (run !== this.hasAnimationLoop)
111265
+ this.toggleAnimationLoop(run);
111266
+ }
111267
+ /**
111268
+ * Run the render loop only while the animation plays. When it stops (pause,
111269
+ * stop, slider), render once so the final pose is shown.
111270
+ */
111271
+ _setAnimationPlaying(playing) {
111272
+ if (playing) {
111273
+ // Resume without jumping ahead by the time spent paused.
111274
+ this.animation.resetClock();
111275
+ }
111276
+ this.setLoopReason("animation", playing);
111277
+ if (!playing && this._rendered !== null) {
111278
+ this.animation.apply();
111279
+ this.update(true, false);
111280
+ }
111281
+ }
111282
+ /**
111283
+ * Start or stop the render loop directly. Prefer {@link setLoopReason}, which keeps
111284
+ * the loop running while any other reason still needs it.
111285
+ * @param flag - whether the render loop should run.
111286
+ */
111234
111287
  toggleAnimationLoop(flag) {
111235
111288
  if (flag) {
111236
111289
  this.continueAnimation = true;
@@ -111381,6 +111434,7 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
111381
111434
  // Hide the topo filter (+ detach its shortcuts) for a clean cleared canvas.
111382
111435
  this.display.shapeFilterDropDownMenu.show(false);
111383
111436
  // stop animation
111437
+ this._loopReasons.clear();
111384
111438
  this.hasAnimationLoop = false;
111385
111439
  this.continueAnimation = false;
111386
111440
  // remove change listener if exists
@@ -114075,7 +114129,7 @@ void mainImage(const in vec4 inputColor, const in vec2 uv, const in float depth,
114075
114129
  if (flag && this.viewer.isStudioActive) {
114076
114130
  return;
114077
114131
  }
114078
- this.viewer.toggleAnimationLoop(flag);
114132
+ this.viewer.setLoopReason("tool", flag);
114079
114133
  if (flag) {
114080
114134
  // Delegate state mutations to Viewer
114081
114135
  this.viewer.activateTool(name, true);