@combeenation/3d-viewer 6.2.0-beta1 → 6.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@combeenation/3d-viewer",
3
- "version": "6.2.0-beta1",
3
+ "version": "6.2.1",
4
4
  "description": "Combeenation 3D Viewer",
5
5
  "homepage": "https://github.com/Combeenation/3d-viewer#readme",
6
6
  "bugs": {
@@ -65,6 +65,15 @@ export class Viewer extends EventBroadcaster {
65
65
 
66
66
  static version = buildInfo.version;
67
67
 
68
+ // these are constants for calculating the camera settings, depending on the bounding box size of the meshes to zoom
69
+ // the algorithms and constant values are directly taken from the BabylonJS repository
70
+ private static readonly _autofocusConstants = {
71
+ minZ: 100,
72
+ wheelPrecision: 100,
73
+ panningSensibility: 5000,
74
+ pinchPrecision: 200,
75
+ };
76
+
68
77
  /**
69
78
  * Help function for automatically creating a valid Spec from a list of variant names and dedicated GLB/Babylon URLs.
70
79
  * This data is most likely coming from babylon assets from the Combeenation system but other sources are also valid.
@@ -461,12 +470,40 @@ export class Viewer extends EventBroadcaster {
461
470
  // get bounding box of all visible meshes, this is the base for the autofocus algorithm
462
471
  const boundingBox = await this.calculateBoundingBox(exclude);
463
472
 
464
- // focus the helper camera and set the calculated camera data to the real camera
465
- const helperCamera = this.getFocusedHelperCamera(boundingBox, settings);
466
- await this.applyFocusedHelperCameraData(activeCamera, helperCamera, settings);
473
+ const radius = boundingBox.getBoundingInfo().boundingSphere.radius;
474
+ const center = boundingBox.getBoundingInfo().boundingSphere.center;
475
+ const diameter = radius * 2;
476
+
477
+ // set lower radius limit on edge of bounding sphere to make sure that we can't dive into the meshes
478
+ activeCamera.lowerRadiusLimit = radius;
467
479
 
468
- // remove the helper camera
469
- helperCamera.dispose();
480
+ // additional settings
481
+ // constants for division are taken directly from BabylonJS repository
482
+ activeCamera.minZ = Math.min(radius / Viewer._autofocusConstants.minZ, 1);
483
+ if (settings?.adjustWheelPrecision !== false) {
484
+ activeCamera.wheelPrecision = Viewer._autofocusConstants.wheelPrecision / radius;
485
+ }
486
+ if (settings?.adjustPanningSensibility !== false) {
487
+ activeCamera.panningSensibility = Viewer._autofocusConstants.panningSensibility / diameter;
488
+ }
489
+ if (settings?.adjustPinchPrecision !== false) {
490
+ activeCamera.pinchPrecision = Viewer._autofocusConstants.pinchPrecision / radius;
491
+ }
492
+
493
+ const radiusFactor = settings?.radiusFactor ?? 1;
494
+ const alpha = (settings?.alpha ?? -90) * (Math.PI / 180);
495
+ const beta = (settings?.beta ?? 90) * (Math.PI / 180);
496
+
497
+ const newCameraPosition = {
498
+ alpha: alpha,
499
+ beta: beta,
500
+ // this calculation is a bit "simplified", as it doesn't consider the viewport ratio or the frustum angle
501
+ // but it's also done this way in the BabylonJs repository, so it should be fine for us
502
+ radius: diameter * radiusFactor,
503
+ target: center,
504
+ };
505
+
506
+ await this.animationManager.animateToPlacement(activeCamera, newCameraPosition, settings?.animation);
470
507
  }
471
508
 
472
509
  /**
@@ -629,7 +666,10 @@ export class Viewer extends EventBroadcaster {
629
666
  const setupJson = SpecStorage.get<SetupJson>('setup');
630
667
  const instances: VariantInstance[] = [];
631
668
  for (const instanceDefinition of setupJson.instances) {
632
- if (instanceDefinition.lazy) {
669
+ // don't create the instance right away if `lazy` is set, register it for later creation (on first usage) instead
670
+ // however if the variant should be `visible` by default, `lazy` loading doesn't make sense and should therefore
671
+ // be overruled by the `visible` flag
672
+ if (instanceDefinition.lazy && instanceDefinition.parameters?.visible !== true) {
633
673
  this.variantInstances.register(instanceDefinition);
634
674
  continue;
635
675
  }
@@ -643,78 +683,4 @@ export class Viewer extends EventBroadcaster {
643
683
  }
644
684
  return instances;
645
685
  }
646
-
647
- /**
648
- * Help function for focusing a helper camera exactly onto the given bounding box
649
- */
650
- private getFocusedHelperCamera(boundingBox: Mesh, settings?: AutofocusSettings): ArcRotateCamera {
651
- // use helper camera to get some default values and set the values of the real camera accordingly
652
- const helperCamera = new ArcRotateCamera(
653
- '__helper_camera__',
654
- 0, // camera angles will be overwritten after the target has been set
655
- 0,
656
- 0, // radius will be calculated, so we can set to 0 here
657
- Vector3.Zero(),
658
- this.scene
659
- );
660
- // this is required for automatically calculating the `lowerRadiusLimit`, so that we don't "dive" into meshes
661
- // see https://doc.babylonjs.com/divingDeeper/behaviors/cameraBehaviors#framing-behavior
662
- helperCamera.useFramingBehavior = true;
663
-
664
- // `minZ` is the camera distance beyond which the mesh will be clipped
665
- // this should be very low, but can't be zero
666
- // a good value seems to be 1% of the bounding box size (= radius), whereas the value shouldn't go above 1, which is
667
- // also the default value
668
- const radius = boundingBox.getBoundingInfo().boundingSphere.radius;
669
- helperCamera.minZ = Math.min(radius / 100, 1);
670
-
671
- // set desired camera data, these won't be changed by the autofocus function!
672
- // default values should focus the element exactly from the front (= XY Plane)
673
- helperCamera.setTarget(boundingBox, true);
674
- helperCamera.alpha = (settings?.alpha ?? -90) * (Math.PI / 180);
675
- helperCamera.beta = (settings?.beta ?? 90) * (Math.PI / 180);
676
-
677
- // finally zoom to the bounding box
678
- // also apply a zoom factor, this adjusts the borders around the model in the viewport
679
- helperCamera.zoomOnFactor = settings?.radiusFactor || 1;
680
- helperCamera.zoomOn([boundingBox], true);
681
-
682
- return helperCamera;
683
- }
684
-
685
- /**
686
- * Help function for applying the relevant data of the focused helper camera to the real camera
687
- */
688
- private async applyFocusedHelperCameraData(
689
- activeCamera: ArcRotateCamera,
690
- helperCamera: ArcRotateCamera,
691
- settings?: AutofocusSettings
692
- ) {
693
- // limits
694
- activeCamera.minZ = helperCamera.minZ;
695
- activeCamera.maxZ = helperCamera.maxZ;
696
- activeCamera.lowerRadiusLimit = helperCamera.lowerRadiusLimit;
697
- activeCamera.upperRadiusLimit = helperCamera.upperRadiusLimit;
698
-
699
- // additional settings
700
- if (settings?.adjustWheelPrecision !== false) {
701
- activeCamera.wheelPrecision = helperCamera.wheelPrecision;
702
- }
703
- if (settings?.adjustPanningSensibility !== false) {
704
- activeCamera.panningSensibility = helperCamera.panningSensibility;
705
- }
706
- if (settings?.adjustPinchPrecision !== false) {
707
- activeCamera.pinchPrecision = helperCamera.pinchPrecision;
708
- }
709
-
710
- // finally move the camera
711
- // do this at last, so that all camera settings are already considered
712
- const newCameraPosition: PlacementDefinition = {
713
- alpha: helperCamera.alpha,
714
- beta: helperCamera.beta,
715
- radius: helperCamera.radius,
716
- target: helperCamera.target,
717
- };
718
- await this.animationManager.animateToPlacement(activeCamera, newCameraPosition, settings?.animation);
719
- }
720
686
  }