bruce-cesium 7.5.9 → 7.6.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.
@@ -6420,6 +6420,22 @@
6420
6420
  return centre && half && (axes === null || axes === void 0 ? void 0 : axes.every(Boolean)) ? { centre, axes, half } : null;
6421
6421
  }
6422
6422
  EntityLabel.ReadOrientedBox = ReadOrientedBox;
6423
+ /*
6424
+ * Whether a placement turns what it places. Scale alone does not count.
6425
+ */
6426
+ function isRotated(matrix) {
6427
+ for (let column = 0; column < 3; column++) {
6428
+ const axis = [0, 1, 2].map(row => Number(matrix[row][column]));
6429
+ const length = Math.hypot(...axis);
6430
+ if (!(length > 0)) {
6431
+ return false;
6432
+ }
6433
+ if (axis.some((value, row) => Math.abs(value / length - Number(row === column)) > 1e-5)) {
6434
+ return true;
6435
+ }
6436
+ }
6437
+ return false;
6438
+ }
6423
6439
  /*
6424
6440
  * The eight padded world corners of an assembly Entity's geometry box, or null when the record cannot give one.
6425
6441
  *
@@ -6438,6 +6454,10 @@
6438
6454
  if ((matrix === null || matrix === void 0 ? void 0 : matrix.length) !== 4 || !matrix.every(row => (row === null || row === void 0 ? void 0 : row.length) === 4) || !Number.isFinite(+(root === null || root === void 0 ? void 0 : root.latitude)) || !Number.isFinite(+(root === null || root === void 0 ? void 0 : root.longitude))) {
6439
6455
  return null;
6440
6456
  }
6457
+ // A pure translation can hide a rotation baked into the vertices, which leaves the extents loose.
6458
+ if (!shape && !isRotated(matrix)) {
6459
+ return null;
6460
+ }
6441
6461
  const pivot = ((_c = bruce.GeometryPivot) === null || _c === void 0 ? void 0 : _c.length) >= 3 ? bruce.GeometryPivot.slice(0, 3).map(Number) : [0, 0, 0];
6442
6462
  // Without an oriented box the record's own extents are an axis-aligned box about the pivot.
6443
6463
  const box = shape || { centre: pivot, axes: [[1, 0, 0], [0, 1, 0], [0, 0, 1]], half: half };
@@ -7888,6 +7908,22 @@
7888
7908
  radius: Math.max(width, height) / 2
7889
7909
  };
7890
7910
  };
7911
+ /*
7912
+ * The on-screen centre and half-size of a model too small for its box, so the box is ringed like a glyph.
7913
+ */
7914
+ const measureModel = (anchor) => {
7915
+ const hull = layer.modelBoxes.Hull(this.id);
7916
+ if (!(hull === null || hull === void 0 ? void 0 : hull.length)) {
7917
+ return null;
7918
+ }
7919
+ const xs = hull.map(point => point.x), ys = hull.map(point => point.y);
7920
+ const left = Math.min(...xs), top = Math.min(...ys);
7921
+ const width = Math.max(...xs) - left, height = Math.max(...ys) - top;
7922
+ if (Math.max(width, height) >= MODEL_BOX_MIN_SIZE) {
7923
+ return null;
7924
+ }
7925
+ return { x: left + width / 2 - anchor.x, y: top + height / 2 - anchor.y, radius: Math.max(width, height) / 2 };
7926
+ };
7891
7927
  // Only CAD tilesets and model Entities are assembly parts with a geometry box; anything else stays a point.
7892
7928
  const boxable = Boolean(normalLeader && ((_r = this.rego) === null || _r === void 0 ? void 0 : _r.entityId) && ((visual instanceof Cesium.Cesium3DTileFeature && this.rego.tilesetType === BModels.Tileset.EType.Cad) ||
7893
7929
  (visual instanceof Cesium.Entity && Boolean(visual.model))));
@@ -7946,7 +7982,7 @@
7946
7982
  }
7947
7983
  let cursorMotion = this.cursorMotion;
7948
7984
  const project = () => {
7949
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
7985
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
7950
7986
  if (this.disposed || !this.viewer || this.viewer.isDestroyed() || ((_a = this.visible) === null || _a === void 0 ? void 0 : _a.call(this)) === false ||
7951
7987
  (presentation === "icon" && this.options.iconScale === 0)) {
7952
7988
  return null;
@@ -7989,7 +8025,8 @@
7989
8025
  const boxBlend = this.morphToBox(boxed, shownOnce ? (_f = (_e = this.options.anchorRing) === null || _e === void 0 ? void 0 : _e.transitionDuration) !== null && _f !== void 0 ? _f : 200 : 0);
7990
8026
  // Eased between the ring and where the stem meets the box, so gaining or losing a box never jumps.
7991
8027
  const boxTarget = this.boxMorph.anchor;
7992
- const ringPoint = { x: anchor.x + pixelOffset.x, y: anchor.y + pixelOffset.y };
8028
+ const model = ((_g = this.modelBox) === null || _g === void 0 ? void 0 : _g.corners) ? measureModel(anchor) : null;
8029
+ const ringPoint = { x: anchor.x + (model || pixelOffset).x, y: anchor.y + (model || pixelOffset).y };
7993
8030
  const boxAnchor = boxBlend > 0 && boxTarget ? {
7994
8031
  x: ringPoint.x + (boxTarget.x - ringPoint.x) * boxBlend,
7995
8032
  y: ringPoint.y + (boxTarget.y - ringPoint.y) * boxBlend
@@ -8000,13 +8037,13 @@
8000
8037
  return null;
8001
8038
  if (onScreen && !this.imageAsked && this.groupId && !HasIcon(this.options) && !this.options.photo) {
8002
8039
  this.imageAsked = true;
8003
- (_g = this.visualRegister) === null || _g === void 0 ? void 0 : _g.RequestLabelImage((_h = this.rego) === null || _h === void 0 ? void 0 : _h.entityId);
8040
+ (_h = this.visualRegister) === null || _h === void 0 ? void 0 : _h.RequestLabelImage((_j = this.rego) === null || _j === void 0 ? void 0 : _j.entityId);
8004
8041
  }
8005
8042
  const transientPivot = (this.Transient && !this.Persistent ?
8006
- (this.hoverFade.to === 0 ? this.retainedHoverPosition : (_j = this.visualRegister) === null || _j === void 0 ? void 0 : _j.GetLabelHoverPosition((_k = this.rego) === null || _k === void 0 ? void 0 : _k.entityId, (_l = this.rego) === null || _l === void 0 ? void 0 : _l.menuItemId)) : undefined);
8043
+ (this.hoverFade.to === 0 ? this.retainedHoverPosition : (_k = this.visualRegister) === null || _k === void 0 ? void 0 : _k.GetLabelHoverPosition((_l = this.rego) === null || _l === void 0 ? void 0 : _l.entityId, (_m = this.rego) === null || _m === void 0 ? void 0 : _m.menuItemId)) : undefined);
8007
8044
  const hover = (presentation !== "icon" ?
8008
8045
  (this.Transient && !this.Persistent && this.hoverFade.to === 0 ? this.retainedHoverPosition :
8009
- (_m = this.visualRegister) === null || _m === void 0 ? void 0 : _m.GetLabelHoverPosition((_o = this.rego) === null || _o === void 0 ? void 0 : _o.entityId, (_p = this.rego) === null || _p === void 0 ? void 0 : _p.menuItemId)) : undefined);
8046
+ (_o = this.visualRegister) === null || _o === void 0 ? void 0 : _o.GetLabelHoverPosition((_p = this.rego) === null || _p === void 0 ? void 0 : _p.entityId, (_q = this.rego) === null || _q === void 0 ? void 0 : _q.menuItemId)) : undefined);
8010
8047
  const reused = !this.Transient || this.Persistent;
8011
8048
  const now = Date.now();
8012
8049
  const animateCursor = () => {
@@ -8030,13 +8067,13 @@
8030
8067
  const cursorAmount = cursorMotion.amount;
8031
8068
  leader = normalLeader || cursorAmount > 0;
8032
8069
  // An icon keeps its callout centred on the glyph rather than following the cursor across it.
8033
- const icon = boxAnchor ? null : measureIcon();
8070
+ const icon = boxAnchor ? null : measureIcon() || model;
8034
8071
  const iconRing = icon ? Math.max(ICON_RING_MIN, icon.radius + ICON_RING_PADDING) : 0;
8035
8072
  // A boxed model is pinned the same way, with its stem leaving the top of the box outline.
8036
8073
  const pinned = Boolean(icon || boxAnchor);
8037
8074
  const pivot = pinned ? undefined : transientPivot;
8038
- let x = boxAnchor ? boxAnchor.x : ((_q = pivot === null || pivot === void 0 ? void 0 : pivot.x) !== null && _q !== void 0 ? _q : anchor.x) + (icon || pixelOffset).x;
8039
- let y = boxAnchor ? boxAnchor.y : ((_r = pivot === null || pivot === void 0 ? void 0 : pivot.y) !== null && _r !== void 0 ? _r : anchor.y) + (icon || pixelOffset).y;
8075
+ let x = boxAnchor ? boxAnchor.x : ((_r = pivot === null || pivot === void 0 ? void 0 : pivot.x) !== null && _r !== void 0 ? _r : anchor.x) + (icon || pixelOffset).x;
8076
+ let y = boxAnchor ? boxAnchor.y : ((_s = pivot === null || pivot === void 0 ? void 0 : pivot.y) !== null && _s !== void 0 ? _s : anchor.y) + (icon || pixelOffset).y;
8040
8077
  if (cursorAmount > 0 && !pinned) {
8041
8078
  // A leader-less label starts centred on its anchor; preserve that box as it lifts away.
8042
8079
  if (!normalLeader) {
@@ -8091,7 +8128,7 @@
8091
8128
  const width = ele.offsetWidth / coordinates.scaleX;
8092
8129
  const height = ele.offsetHeight / coordinates.scaleY;
8093
8130
  let clusterBounds;
8094
- if ((_s = this.options.cluster) === null || _s === void 0 ? void 0 : _s.enabled) {
8131
+ if ((_t = this.options.cluster) === null || _t === void 0 ? void 0 : _t.enabled) {
8095
8132
  const textWidth = (sourceText === null || sourceText === void 0 ? void 0 : sourceText.offsetWidth) || 0;
8096
8133
  const textHeight = (sourceText === null || sourceText === void 0 ? void 0 : sourceText.offsetHeight) || 0;
8097
8134
  // A photo is never part of the footprint, so its arrival cannot change which cluster a label joins.
@@ -8125,7 +8162,7 @@
8125
8162
  if (!leader && (bounds.x + bounds.width < 0 || bounds.y + bounds.height < 0 || bounds.x > this.viewer.canvas.clientWidth || bounds.y > this.viewer.canvas.clientHeight)) {
8126
8163
  return null;
8127
8164
  }
8128
- const state = (_t = this.visualRegister) === null || _t === void 0 ? void 0 : _t.GetState({ entityId: (_u = this.rego) === null || _u === void 0 ? void 0 : _u.entityId, menuItemId: (_v = this.rego) === null || _v === void 0 ? void 0 : _v.menuItemId });
8165
+ const state = (_u = this.visualRegister) === null || _u === void 0 ? void 0 : _u.GetState({ entityId: (_v = this.rego) === null || _v === void 0 ? void 0 : _v.entityId, menuItemId: (_w = this.rego) === null || _w === void 0 ? void 0 : _w.menuItemId });
8129
8166
  const opacity = this.prePositioned || hoverOnly || MAX_DISTANCE === Infinity ? 1 : 1 - distance / MAX_DISTANCE;
8130
8167
  return {
8131
8168
  canFlip: leader && presentation !== "icon", hasLeader: leader,
@@ -8133,9 +8170,9 @@
8133
8170
  transient: this.Transient || Boolean(hover) || cursorAmount > 0,
8134
8171
  extendedGeometry: visual instanceof Cesium.Entity && Boolean(visual.polygon || visual.polyline || visual.corridor),
8135
8172
  viewportWidth: this.viewer.canvas.clientWidth,
8136
- id: this.id, entityKey: ((_w = this.rego) === null || _w === void 0 ? void 0 : _w.entityId) ? JSON.stringify([this.rego.entityId, this.rego.menuItemId || "", this.Transient && !this.Persistent ? "hover" : ""]) : undefined,
8137
- entityId: (_x = this.rego) === null || _x === void 0 ? void 0 : _x.entityId, group: this.groupId, x, y, width, height, anchorX, anchorY, depth, leaderLength, leaderRun, leaderSide, distance,
8138
- iconRadius: icon === null || icon === void 0 ? void 0 : icon.radius, modelBox: boxed || undefined, boxBlend,
8173
+ id: this.id, entityKey: ((_x = this.rego) === null || _x === void 0 ? void 0 : _x.entityId) ? JSON.stringify([this.rego.entityId, this.rego.menuItemId || "", this.Transient && !this.Persistent ? "hover" : ""]) : undefined,
8174
+ entityId: (_y = this.rego) === null || _y === void 0 ? void 0 : _y.entityId, group: this.groupId, x, y, width, height, anchorX, anchorY, depth, leaderLength, leaderRun, leaderSide, distance,
8175
+ iconRadius: icon === null || icon === void 0 ? void 0 : icon.radius, modelBox: boxed || undefined, boxBlend, follows: !pinned && Boolean(transientPivot || cursorMotion.target),
8139
8176
  // Priority shows the hovered member individually without dragging its cluster along.
8140
8177
  opacity: waiting ? 0 : opacity, priority: hover || cursorAmount > 0 || (state === null || state === void 0 ? void 0 : state.highlighted) ? 1 : 0, options: this.options, text: originalText, clusterBounds
8141
8178
  };
@@ -8262,15 +8299,16 @@
8262
8299
  const normalRadius = (!leader || (ring === null || ring === void 0 ? void 0 : ring.enabled) === false ? 0 : Math.max(frame.distance <= ((_l = ring === null || ring === void 0 ? void 0 : ring.nearDistance) !== null && _l !== void 0 ? _l : 100) ? ((_m = ring === null || ring === void 0 ? void 0 : ring.nearRadius) !== null && _m !== void 0 ? _m : 10) : 0, hovered ? ((_o = ring === null || ring === void 0 ? void 0 : ring.hoverRadius) !== null && _o !== void 0 ? _o : (this.Transient && !this.Persistent ? 15.4 : 22)) : 0));
8263
8300
  const targetRadius = normalRadius + (15.4 - normalRadius) * cursorMotion.amount;
8264
8301
  // Around a glyph the ring keeps the glyph's size and only fades its stroke in, so it never covers the icon.
8265
- const targetOuter = iconRing || targetRadius || 2.5;
8266
- const targetInner = iconRing ? (targetRadius > 0 ? iconRing - 2 : iconRing) : Math.max(0, targetRadius - 2);
8302
+ // A ring around the cursor marks nothing, so a riding label keeps only its leader.
8303
+ const targetOuter = frame.follows ? 0 : iconRing || targetRadius || 2.5;
8304
+ const targetInner = frame.follows ? 0 : iconRing ? (targetRadius > 0 ? iconRing - 2 : iconRing) : Math.max(0, targetRadius - 2);
8267
8305
  const now = Date.now();
8268
8306
  const duration = (_p = ring === null || ring === void 0 ? void 0 : ring.transitionDuration) !== null && _p !== void 0 ? _p : 200;
8269
8307
  const sharedRing = this.Transient && !this.Persistent && this.hoverFade.to === 1 ? this.hoverRingState : undefined;
8270
8308
  let ringAnimation = sharedRing ? sharedRing.animation : this.ringAnimation;
8271
8309
  if (!ringAnimation) {
8272
- const outer = iconRing || 2.5;
8273
- const inner = iconRing;
8310
+ const outer = frame.follows ? 0 : iconRing || 2.5;
8311
+ const inner = frame.follows ? 0 : iconRing;
8274
8312
  ringAnimation = { target: outer, targetInner: inner, start: now, outer, inner, fromOuter: outer, fromInner: inner };
8275
8313
  }
8276
8314
  const animateRing = () => {
@@ -53256,7 +53294,7 @@ void main() {
53256
53294
  StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
53257
53295
  })(exports.StyleUtils || (exports.StyleUtils = {}));
53258
53296
 
53259
- const VERSION = "7.5.9";
53297
+ const VERSION = "7.6.1";
53260
53298
  /**
53261
53299
  * Updates the environment instance used by bruce-cesium to one specified.
53262
53300
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.