@volter/blender-engine 0.1.29 → 0.1.31

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.
@@ -746,6 +746,38 @@ export class BlenderRuntimeView {
746
746
  private readonly frameListeners = new Set<() => void>();
747
747
  /** The views drawing this one's frames in a second area ({@link follow}). */
748
748
  private readonly followers = new Set<BlenderRuntimeView>();
749
+ /** The view this one follows ({@link follow}), or null for a view that leads. */
750
+ private leader: BlenderRuntimeView | null = null;
751
+
752
+ /**
753
+ * A POSE MOVED HERE MID-GESTURE, DRAWN BY EVERY OTHER VIEW OF THE MODEL NOW. The gizmo moves a
754
+ * presented object in the view whose area it is dragged in (`blender-outliner-authoring.ts`,
755
+ * `apply`), and Blender's frame for the move comes only when the gesture ends; without this the
756
+ * other area — a Rendered one, as Blender's always-on render preview is — stood still until the
757
+ * release, where Blender redraws every area on every move. Each view holds its own object for
758
+ * the same Blender object (the frame's id) under the same parent, so the local matrix carries.
759
+ */
760
+ mirrorPose(object: THREE.Object3D): void {
761
+ let id: string | null = null;
762
+ for (const [key, held] of this.objects)
763
+ if (held === object) {
764
+ id = key;
765
+ break;
766
+ }
767
+ if (id === null) return;
768
+ const views = this.leader ? [this.leader, ...this.leader.followers] : [...this.followers];
769
+ let moved = false;
770
+ for (const view of views) {
771
+ if (view === this) continue;
772
+ const twin = view.objects.get(id);
773
+ if (twin === undefined) continue;
774
+ twin.matrix.copy(object.matrix);
775
+ twin.matrix.decompose(twin.position, twin.quaternion, twin.scale);
776
+ twin.updateMatrixWorld(true);
777
+ moved = true;
778
+ }
779
+ if (moved) presenterChanged();
780
+ }
749
781
 
750
782
  /** Subscribe to frames. Returns the unsubscribe. */
751
783
  subscribeFrames(listener: () => void): () => void {
@@ -2005,6 +2037,7 @@ export class BlenderRuntimeView {
2005
2037
  const follower = new BlenderRuntimeView();
2006
2038
  if (this.frame) follower.applyFrame(this.fullFrame());
2007
2039
  this.followers.add(follower);
2040
+ follower.leader = this;
2008
2041
  let disposed = false;
2009
2042
  return {
2010
2043
  view: follower,
@@ -2012,6 +2045,7 @@ export class BlenderRuntimeView {
2012
2045
  if (disposed) return;
2013
2046
  disposed = true;
2014
2047
  this.followers.delete(follower);
2048
+ follower.leader = null;
2015
2049
  follower.dispose();
2016
2050
  follower.root.removeFromParent();
2017
2051
  },
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@volter/blender-engine",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "GPL-3.0-or-later",
5
- "version": "0.1.29",
5
+ "version": "0.1.31",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },