@inweb/viewer-three 27.2.3 → 27.3.0

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.
@@ -3806,19 +3806,19 @@ class ModelImpl {
3806
3806
  return this;
3807
3807
  }
3808
3808
  explode(scale = 0, coeff = 4) {
3809
- const centers = new Map();
3810
- const getObjectCenter = (object, target) => {
3809
+ const centersCache = new Map();
3810
+ const calcObjectCenter = (object, target) => {
3811
3811
  const extents = new Box3().setFromObject(object);
3812
3812
  const handle = object.userData.handle;
3813
3813
  if (!handle)
3814
3814
  return extents.getCenter(target);
3815
- const center = centers.get(handle);
3815
+ const center = centersCache.get(handle);
3816
3816
  if (center)
3817
3817
  return target.copy(center);
3818
3818
  const objects = this.getObjectsByHandles(handle);
3819
3819
  objects.forEach((x) => extents.expandByObject(x));
3820
3820
  extents.getCenter(target);
3821
- centers.set(handle, target.clone());
3821
+ centersCache.set(handle, target.clone());
3822
3822
  return target;
3823
3823
  };
3824
3824
  function calcExplodeDepth(object, depth) {
@@ -3829,13 +3829,14 @@ class ModelImpl {
3829
3829
  result = objectDepth;
3830
3830
  });
3831
3831
  object.userData.originalPosition = object.position.clone();
3832
- object.userData.originalCenter = getObjectCenter(object, new Vector3());
3832
+ object.userData.originalCenter = calcObjectCenter(object, new Vector3());
3833
3833
  return result;
3834
3834
  }
3835
3835
  const explodeScale = scale / 100;
3836
3836
  const explodeRoot = this.scene;
3837
- if (!explodeRoot.userData.explodeDepth)
3837
+ if (!explodeRoot.userData.explodeDepth) {
3838
3838
  explodeRoot.userData.explodeDepth = calcExplodeDepth(explodeRoot, 1);
3839
+ }
3839
3840
  const maxDepth = explodeRoot.userData.explodeDepth;
3840
3841
  const scaledExplodeDepth = explodeScale * maxDepth + 1;
3841
3842
  const explodeDepth = 0 | scaledExplodeDepth;
@@ -3852,8 +3853,8 @@ class ModelImpl {
3852
3853
  objectScale *= currentSegmentFraction;
3853
3854
  const parentCenter = object.parent.userData.originalCenter;
3854
3855
  const objectCenter = object.userData.originalCenter;
3855
- const objectOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
3856
- object.position.add(objectOffset);
3856
+ const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
3857
+ object.position.add(localOffset);
3857
3858
  }
3858
3859
  object.children.forEach((x) => explodeObject(x, depth + 1));
3859
3860
  }
@@ -3945,67 +3946,73 @@ class DynamicModelImpl extends ModelImpl {
3945
3946
  return this;
3946
3947
  }
3947
3948
  explode(scale = 0, coeff = 4) {
3948
- const centers = new Map();
3949
+ const centersCache = new Map();
3949
3950
  const calcObjectCenter = (object, target) => {
3950
3951
  const extents = new Box3().setFromObject(object);
3951
3952
  const handle = object.userData.handle;
3952
3953
  if (!handle)
3953
3954
  return extents.getCenter(target);
3954
- const center = centers.get(handle);
3955
+ const center = centersCache.get(handle);
3955
3956
  if (center)
3956
3957
  return target.copy(center);
3957
3958
  const objects = this.getObjectsByHandles(handle);
3958
3959
  objects.forEach((x) => extents.expandByObject(x));
3959
3960
  extents.getCenter(target);
3960
- centers.set(handle, target.clone());
3961
+ centersCache.set(handle, target.clone());
3961
3962
  return target;
3962
3963
  };
3963
- function calcExplodeDepth(object, depth) {
3964
- let result = depth;
3965
- object.children
3966
- .filter((x) => !x.userData.isOptimized)
3967
- .forEach((x) => {
3968
- const objectDepth = calcExplodeDepth(x, depth + 1);
3969
- if (result < objectDepth)
3970
- result = objectDepth;
3971
- });
3964
+ const calcObjectDepth = (object) => {
3965
+ if (object.userData.depth !== undefined)
3966
+ return object.userData.depth;
3967
+ const parent = object.parent;
3968
+ const depth = parent && object !== explodeRoot ? calcObjectDepth(parent) + 1 : 0;
3969
+ object.userData.depth = depth;
3972
3970
  object.userData.originalPosition = object.position.clone();
3973
3971
  object.userData.originalCenter = calcObjectCenter(object, new Vector3());
3974
- return result;
3975
- }
3972
+ return depth;
3973
+ };
3976
3974
  const explodeScale = scale / 100;
3977
3975
  const explodeRoot = this.scene.children[0];
3978
- if (!explodeRoot.userData.explodeDepth)
3979
- explodeRoot.userData.explodeDepth = calcExplodeDepth(explodeRoot, 1);
3976
+ if (!explodeRoot.userData.explodeDepth) {
3977
+ let maxDepth = 0;
3978
+ this.gltfLoader.originalObjects.forEach((object) => {
3979
+ const depth = calcObjectDepth(object);
3980
+ if (depth > maxDepth)
3981
+ maxDepth = depth;
3982
+ });
3983
+ explodeRoot.userData.explodeDepth = maxDepth;
3984
+ }
3980
3985
  const maxDepth = explodeRoot.userData.explodeDepth;
3981
3986
  const scaledExplodeDepth = explodeScale * maxDepth + 1;
3982
3987
  const explodeDepth = 0 | scaledExplodeDepth;
3983
3988
  const currentSegmentFraction = scaledExplodeDepth - explodeDepth;
3984
- const transformMap = new Map();
3985
- function explodeObject(object, depth) {
3986
- if (object.isCamera)
3987
- return;
3988
- if (object.userData.isHighlightWireframe)
3989
- return;
3990
- object.position.copy(object.userData.originalPosition);
3991
- if (depth > 0 && depth <= explodeDepth && !object.userData.isExplodeLocked) {
3989
+ const offsetCache = new Map();
3990
+ const calcObjectOffset = (object, target) => {
3991
+ if (offsetCache.has(object))
3992
+ return target.copy(offsetCache.get(object));
3993
+ const parent = object.parent;
3994
+ if (parent && object !== explodeRoot)
3995
+ calcObjectOffset(parent, target);
3996
+ const depth = object.userData.depth;
3997
+ if (depth > 0 && depth <= explodeDepth) {
3992
3998
  let objectScale = explodeScale * coeff;
3993
3999
  if (depth === explodeDepth)
3994
4000
  objectScale *= currentSegmentFraction;
3995
- const parentCenter = object.parent.userData.originalCenter;
4001
+ const parentCenter = parent.userData.originalCenter;
3996
4002
  const objectCenter = object.userData.originalCenter;
3997
- const objectOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
3998
- object.position.add(objectOffset);
3999
- const matrix = new Matrix4().makeTranslation(objectOffset.x, objectOffset.y, objectOffset.z);
4000
- transformMap.set(object, matrix);
4003
+ const localOffset = objectCenter.clone().sub(parentCenter).multiplyScalar(objectScale);
4004
+ target.add(localOffset);
4001
4005
  }
4002
- object.children
4003
- .filter((x) => !x.userData.isOptimized)
4004
- .forEach((x) => explodeObject(x, depth + 1));
4005
- }
4006
- explodeObject(explodeRoot, 0);
4007
- this.scene.updateMatrixWorld();
4006
+ offsetCache.set(object, target.clone());
4007
+ return target;
4008
+ };
4009
+ const transformMap = new Map();
4010
+ this.gltfLoader.originalObjects.forEach((object) => {
4011
+ const globalOffset = calcObjectOffset(object, new Vector3());
4012
+ transformMap.set(object, new Matrix4().makeTranslation(globalOffset));
4013
+ });
4008
4014
  this.gltfLoader.applyObjectTransforms(transformMap);
4015
+ this.scene.updateMatrixWorld();
4009
4016
  return this;
4010
4017
  }
4011
4018
  }
@@ -4582,6 +4589,8 @@ class DynamicGltfLoader {
4582
4589
  this.oldOptimizeObjects = new Set();
4583
4590
  this.objectTransforms = new Map();
4584
4591
  this.transformedGeometries = new Map();
4592
+ this.syncTransformsToOriginalObjects = true;
4593
+ this._originalObjectMatrices = new Map();
4585
4594
  this.activeChunkLoads = 0;
4586
4595
  this.chunkQueue = [];
4587
4596
  this.objectIdToIndex = new Map();
@@ -5736,6 +5745,7 @@ class DynamicGltfLoader {
5736
5745
  this.isolatedObjects = [];
5737
5746
  this.objectTransforms.clear();
5738
5747
  this.transformedGeometries.clear();
5748
+ this._originalObjectMatrices.clear();
5739
5749
  this.totalLoadedObjects = 0;
5740
5750
  this.currentMemoryUsage = 0;
5741
5751
  this.pendingMemoryUsage = 0;
@@ -6581,6 +6591,47 @@ class DynamicGltfLoader {
6581
6591
  this.updateMaterialUniforms();
6582
6592
  }
6583
6593
  }
6594
+ if (this.syncTransformsToOriginalObjects) {
6595
+ this._syncOriginalObjectTransforms(objectTransformMap);
6596
+ }
6597
+ }
6598
+ _syncOriginalObjectTransforms(objectTransformMap) {
6599
+ for (const [obj, savedPos] of this._originalObjectMatrices) {
6600
+ obj.position.copy(savedPos);
6601
+ if (obj.userData.highlight) {
6602
+ obj.userData.highlight.position.copy(savedPos);
6603
+ }
6604
+ }
6605
+ this._originalObjectMatrices.clear();
6606
+ const _offset = new Vector3();
6607
+ const _parentInverse = new Matrix4();
6608
+ if (objectTransformMap instanceof Map) {
6609
+ for (const [object, matrix] of objectTransformMap.entries()) {
6610
+ if (!object.userData?.handle) continue;
6611
+ if (!this._originalObjectMatrices.has(object)) {
6612
+ this._originalObjectMatrices.set(object, object.position.clone());
6613
+ }
6614
+ _offset.setFromMatrixPosition(matrix);
6615
+ if (object.userData.structureId) {
6616
+ const rootGroup = this.structureRoots.get(object.userData.structureId);
6617
+ if (rootGroup && object.parent && object.parent !== rootGroup) {
6618
+ const origin = new Vector3(0, 0, 0);
6619
+ origin.applyMatrix4(rootGroup.matrixWorld);
6620
+ _offset.applyMatrix4(rootGroup.matrixWorld);
6621
+ _offset.sub(origin);
6622
+ const parentOrigin = new Vector3(0, 0, 0);
6623
+ _parentInverse.copy(object.parent.matrixWorld).invert();
6624
+ parentOrigin.applyMatrix4(_parentInverse);
6625
+ _offset.applyMatrix4(_parentInverse);
6626
+ _offset.sub(parentOrigin);
6627
+ }
6628
+ }
6629
+ object.position.add(_offset);
6630
+ if (object.userData.highlight) {
6631
+ object.userData.highlight.position.copy(object.position);
6632
+ }
6633
+ }
6634
+ }
6584
6635
  }
6585
6636
  createExplodeTransforms(objects = null, explodeCenter = null, explodeFactor = 1.5) {
6586
6637
  const transformMap = new Map();
@@ -6664,6 +6715,15 @@ class DynamicGltfLoader {
6664
6715
  clearTransforms() {
6665
6716
  this.objectTransforms.clear();
6666
6717
  this._resetTransformData(true);
6718
+ if (this.syncTransformsToOriginalObjects) {
6719
+ for (const [obj, savedPos] of this._originalObjectMatrices) {
6720
+ obj.position.copy(savedPos);
6721
+ if (obj.userData.highlight) {
6722
+ obj.userData.highlight.position.copy(savedPos);
6723
+ }
6724
+ }
6725
+ this._originalObjectMatrices.clear();
6726
+ }
6667
6727
  }
6668
6728
  clearHandleTransforms() {
6669
6729
  this.clearTransforms();