@volter/editor-threejs 0.5.187 → 0.5.189

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@volter/editor-threejs",
3
3
  "author": "Volter AI, Inc.",
4
- "version": "0.5.187",
4
+ "version": "0.5.189",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -135,12 +135,12 @@
135
135
  "serving": "./dist-node/serving.mjs"
136
136
  },
137
137
  "dependencies": {
138
- "@volter/editor-project": "0.5.187",
138
+ "@volter/editor-project": "0.5.189",
139
139
  "@sparkjsdev/spark": "^2.1.0",
140
140
  "three.quarks": "^0.16.0",
141
141
  "zod": "^4.3.6",
142
142
  "typescript": "5.9.3",
143
- "@volter/editor-sdk": "0.5.187",
143
+ "@volter/editor-sdk": "0.5.189",
144
144
  "postprocessing": "6.38.3",
145
145
  "quarks.core": "0.16.0",
146
146
  "@fortawesome/free-solid-svg-icons": "^7.2.0"
@@ -1,5 +1,5 @@
1
1
  import { createPerformanceProfiler } from '@volter/editor-sdk/kit/performance-profiler';
2
- import { resetViewPresentation, type ViewportXray } from '@volter/editor-sdk/kit/viewport-presentation';
2
+ import { resetViewPresentation, setViewPresentation, type ViewportXray } from '@volter/editor-sdk/kit/viewport-presentation';
3
3
  import { invalidateStages } from '@volter/editor-sdk/kit/stage-invalidation';
4
4
  import type { AuthoringAdapter } from '@volter/editor-project/adapter';
5
5
  import { viewportCaptureOutputPass } from '@volter/editor-threejs/capture/output-pass';
@@ -7,6 +7,7 @@ import { contentWorldBounds } from '@volter/editor-threejs/viewport/content-boun
7
7
  import { setUserData } from '@volter/editor-threejs/ecs/user-data';
8
8
  import {
9
9
  type ViewportShadingMode,
10
+ VIEWPORT_SHADING_MODES,
10
11
  ViewportShadingRenderer,
11
12
  } from '@volter/editor-threejs/render/viewport-shading';
12
13
  import type { EffectComposer, EffectPass, RenderPass } from 'postprocessing';
@@ -630,6 +631,9 @@ export class Object3DDocumentSession {
630
631
  invalidateStages();
631
632
  this.leaveCameraView(false);
632
633
  this.settleFlight('superseded');
634
+ if (fov !== undefined && Number.isFinite(fov) && fov > 0 && fov < 180) {
635
+ setViewPresentation(this.documentId, { camera: { fov: { degrees: fov, axis: 'vertical' } } });
636
+ }
633
637
  this.viewport.setPose(position, target, fov);
634
638
  }
635
639
 
@@ -1062,6 +1066,10 @@ export class Object3DDocumentSession {
1062
1066
  }
1063
1067
 
1064
1068
  setMode(mode: Object3DDocumentViewMode): void {
1069
+ if (mode !== 'uv' && mode !== 'vertex-colors' &&
1070
+ !(VIEWPORT_SHADING_MODES as readonly string[]).includes(mode)) {
1071
+ throw new Error(`Unknown document shading mode "${mode}".`);
1072
+ }
1065
1073
  invalidateStages();
1066
1074
  if (this.state.mode === mode) return;
1067
1075
  this.clearDiagnosticPresentation();
@@ -394,6 +394,10 @@ function mountViewportSurface(
394
394
  );
395
395
  const { canvas, renderer } = lease;
396
396
  canvas.setAttribute('aria-label', `${displayName} authoring viewport`);
397
+ // This is the document's main renderer, rather than a canvas embedded in UI.
398
+ // Capture draws it once beneath the document overlays; encoding it again in
399
+ // the DOM clone duplicates megapixel PNG work and can hide the React HUD.
400
+ canvas.setAttribute('data-volter-root-surface', 'true');
397
401
  canvasHost.appendChild(canvas);
398
402
  return { canvas, renderer, lease };
399
403
  }
@@ -532,6 +536,7 @@ class Object3DDocumentHost {
532
536
  () => this.viewport?.dispose(),
533
537
  () => this.rendererSession.dispose(),
534
538
  () => this.dressing?.dispose(),
539
+ () => canvas.removeAttribute('data-volter-root-surface'),
535
540
  ...(lease
536
541
  ? [() => lease.release()]
537
542
  : [() => renderer.dispose(), () => renderer.forceContextLoss(), () => canvas.remove()]),
@@ -590,6 +595,7 @@ export function Object3DDocumentViewport({
590
595
  active = true,
591
596
  audit = true,
592
597
  chromeless = false,
598
+ fillContainer = false,
593
599
  modelSource,
594
600
  assetType,
595
601
  sourceAuthoring,
@@ -1375,7 +1381,7 @@ export function Object3DDocumentViewport({
1375
1381
  onProjectionChange: setProjection,
1376
1382
  // The same expression that places the DOM furniture, for the one
1377
1383
  // piece of furniture that is drawn on the canvas instead.
1378
- chromeInsetPx: chromeless || hasShell ? 0 : STAGE_BLEED_PX,
1384
+ chromeInsetPx: chromeless || hasShell || fillContainer ? 0 : STAGE_BLEED_PX,
1379
1385
  // A document that turns the dressing's key light off has said it
1380
1386
  // lights itself, and the editor's design-time rig answers exactly
1381
1387
  // the same question. MEASURED on the Model stage before this
@@ -2350,7 +2356,8 @@ export function Object3DDocumentViewport({
2350
2356
  break;
2351
2357
  }
2352
2358
  case 'set-camera-pose':
2353
- viewport.setPose(action.position, action.target, action.fov);
2359
+ if (host.session) host.session.setCameraPose(action.position, action.target, action.fov);
2360
+ else viewport.setPose(action.position, action.target, action.fov);
2354
2361
  break;
2355
2362
  }
2356
2363
  }),
@@ -2434,6 +2441,7 @@ export function Object3DDocumentViewport({
2434
2441
  dressingViewLocked,
2435
2442
  dressingToneMapping,
2436
2443
  chromeless,
2444
+ fillContainer,
2437
2445
  modelSourceEntityId,
2438
2446
  modelSourceKind,
2439
2447
  modelSourcePath,
@@ -2495,7 +2503,7 @@ export function Object3DDocumentViewport({
2495
2503
  ? { width: '100%', height: '100%' }
2496
2504
  : hasShell
2497
2505
  ? { flex: 1, minHeight: 0 }
2498
- : { inset: -STAGE_BLEED_PX }),
2506
+ : { inset: fillContainer ? 0 : -STAGE_BLEED_PX }),
2499
2507
  overflow: 'hidden',
2500
2508
  // Asset documents paint the shared studio stage through their class.
2501
2509
  // An inline background here would win the cascade and hide it.
@@ -2604,7 +2612,7 @@ export function Object3DDocumentViewport({
2604
2612
  <div
2605
2613
  style={{
2606
2614
  position: 'absolute',
2607
- inset: chromeless || hasShell ? 0 : STAGE_BLEED_PX,
2615
+ inset: chromeless || hasShell || fillContainer ? 0 : STAGE_BLEED_PX,
2608
2616
  pointerEvents: 'none',
2609
2617
  }}
2610
2618
  >
@@ -3820,8 +3820,10 @@ export class EditorViewport {
3820
3820
  this.orbitControls.target.set(target.x, target.y, target.z);
3821
3821
  this.camera.lookAt(this.orbitControls.target);
3822
3822
  if (fov !== undefined) {
3823
- this.camera.fov = fov;
3824
- this.camera.updateProjectionMatrix();
3823
+ // A free pose states three's vertical angle. Keep the resize source in
3824
+ // sync; writing only camera.fov lets the next layout change restore the
3825
+ // previous lens, even when the camera position and target were retained.
3826
+ this.setFieldOfView({ degrees: fov, axis: 'vertical' });
3825
3827
  }
3826
3828
  this.orbitControls.update();
3827
3829
  }
@@ -207,6 +207,8 @@ export interface ToolObject3DAuthoringProps {
207
207
  * Object Data tab is the mesh's own, not an importer's report.
208
208
  */
209
209
  readonly audit?: boolean;
210
+ /** Fill the supplied container exactly, without the bare dock panel's padding bleed. */
211
+ readonly fillContainer?: boolean;
210
212
  readonly cameraDirection?: readonly [number, number, number];
211
213
  /** Per-document overrides of the standard viewport dressing. */
212
214
  readonly dressing?: ToolViewportDressing;