@itwin/ecschema-rpcinterface-tests 3.6.0-dev.14 → 3.6.0-dev.22

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.
@@ -21,9 +21,9 @@
21
21
 
22
22
  /***/ }),
23
23
 
24
- /***/ "../../common/temp/node_modules/.pnpm/@itwin+certa@3.4.7/node_modules/@itwin/certa/lib/utils/CallbackUtils.js":
24
+ /***/ "../../common/temp/node_modules/.pnpm/@itwin+certa@3.5.1/node_modules/@itwin/certa/lib/utils/CallbackUtils.js":
25
25
  /*!********************************************************************************************************************!*\
26
- !*** ../../common/temp/node_modules/.pnpm/@itwin+certa@3.4.7/node_modules/@itwin/certa/lib/utils/CallbackUtils.js ***!
26
+ !*** ../../common/temp/node_modules/.pnpm/@itwin+certa@3.5.1/node_modules/@itwin/certa/lib/utils/CallbackUtils.js ***!
27
27
  \********************************************************************************************************************/
28
28
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
29
29
 
@@ -2772,7 +2772,7 @@ exports.getAccessTokenFromBackend = exports.getTokenCallbackName = void 0;
2772
2772
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
2773
2773
  * See LICENSE.md in the project root for license terms and full copyright notice.
2774
2774
  *--------------------------------------------------------------------------------------------*/
2775
- const CallbackUtils_1 = __webpack_require__(/*! @itwin/certa/lib/utils/CallbackUtils */ "../../common/temp/node_modules/.pnpm/@itwin+certa@3.4.7/node_modules/@itwin/certa/lib/utils/CallbackUtils.js");
2775
+ const CallbackUtils_1 = __webpack_require__(/*! @itwin/certa/lib/utils/CallbackUtils */ "../../common/temp/node_modules/.pnpm/@itwin+certa@3.5.1/node_modules/@itwin/certa/lib/utils/CallbackUtils.js");
2776
2776
  // Shared by both the frontend and backend side of the tests
2777
2777
  exports.getTokenCallbackName = "getToken";
2778
2778
  async function getAccessTokenFromBackend(user, oidcConfig) {
@@ -49015,8 +49015,16 @@ class TransientIdSequence {
49015
49015
  constructor() {
49016
49016
  this._localId = 0;
49017
49017
  }
49018
+ /** Generate and return the next transient Id64String in the sequence.
49019
+ * @deprecated Use [[getNext]].
49020
+ */
49021
+ get next() {
49022
+ return this.getNext();
49023
+ }
49018
49024
  /** Generate and return the next transient Id64String in the sequence. */
49019
- get next() { return Id64.fromLocalAndBriefcaseIds(++this._localId, 0xffffff); }
49025
+ getNext() {
49026
+ return Id64.fromLocalAndBriefcaseIds(++this._localId, 0xffffff);
49027
+ }
49020
49028
  }
49021
49029
  /**
49022
49030
  * The Guid namespace provides facilities for working with GUID strings using the "8-4-4-4-12" pattern.
@@ -95483,7 +95491,7 @@ class AccuDraw {
95483
95491
  if (context.viewport.viewFlags.acsTriad) {
95484
95492
  context.viewport.view.auxiliaryCoordinateSystem.display(context, (_AuxCoordSys__WEBPACK_IMPORTED_MODULE_4__.ACSDisplayOptions.CheckVisible | _AuxCoordSys__WEBPACK_IMPORTED_MODULE_4__.ACSDisplayOptions.Active));
95485
95493
  if (undefined === this._acsPickId)
95486
- this._acsPickId = context.viewport.iModel.transientIds.next;
95494
+ this._acsPickId = context.viewport.iModel.transientIds.getNext();
95487
95495
  const acsPickBuilder = context.createGraphicBuilder(_render_GraphicBuilder__WEBPACK_IMPORTED_MODULE_7__.GraphicType.WorldDecoration, undefined, this._acsPickId);
95488
95496
  const color = _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.ColorDef.blue.adjustedForContrast(context.viewport.view.backgroundColor, 50);
95489
95497
  acsPickBuilder.setSymbology(color, color, 6);
@@ -123862,7 +123870,6 @@ class RealityMeshParamsBuilder {
123862
123870
  * @returns the index of the new vertex in [[positions]].
123863
123871
  */
123864
123872
  addQuantizedVertex(position, uv, normal) {
123865
- (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(this.positions.length < 0xffff, "RealityMeshParams supports no more than 64k vertices");
123866
123873
  (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)((undefined === normal) === (undefined === this.normals), "RealityMeshParams requires all vertices to have normals, or none.");
123867
123874
  this.positions.push(position);
123868
123875
  this.uvs.push(uv);
@@ -123889,7 +123896,6 @@ class RealityMeshParamsBuilder {
123889
123896
  this.addIndex(index);
123890
123897
  }
123891
123898
  addIndex(index) {
123892
- (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(index <= 0xffff, "RealityMeshParams supports no more than 64k vertices");
123893
123899
  this.indices.push(index);
123894
123900
  }
123895
123901
  /** Extract the finished [[RealityMeshParams]]. */
@@ -130694,6 +130700,7 @@ class BranchState {
130694
130700
  get viewFlags() { return this._opts.viewFlags; }
130695
130701
  set viewFlags(vf) { this._opts.viewFlags = vf.normalize(); }
130696
130702
  get clipVolume() { return this._opts.clipVolume; }
130703
+ get forceViewCoords() { return true === this._opts.forceViewCoords; }
130697
130704
  get planarClassifier() { return this._opts.planarClassifier; }
130698
130705
  get textureDrape() { return this._opts.textureDrape; }
130699
130706
  get edgeSettings() { return this._opts.edgeSettings; }
@@ -130725,6 +130732,7 @@ class BranchState {
130725
130732
  planarClassifier: (undefined !== branch.planarClassifier && undefined !== branch.planarClassifier.texture) ? branch.planarClassifier : prev.planarClassifier,
130726
130733
  textureDrape: (_c = branch.textureDrape) !== null && _c !== void 0 ? _c : prev.textureDrape,
130727
130734
  clipVolume: branch.clips,
130735
+ forceViewCoords: prev.forceViewCoords,
130728
130736
  edgeSettings: (_d = branch.edgeSettings) !== null && _d !== void 0 ? _d : prev.edgeSettings,
130729
130737
  is3d: (_f = (_e = branch.frustum) === null || _e === void 0 ? void 0 : _e.is3d) !== null && _f !== void 0 ? _f : prev.is3d,
130730
130738
  frustumScale: (_h = (_g = branch.frustum) === null || _g === void 0 ? void 0 : _g.scale) !== null && _h !== void 0 ? _h : prev.frustumScale,
@@ -130743,6 +130751,9 @@ class BranchState {
130743
130751
  const vf = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.ViewFlags({ renderMode: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.RenderMode.SmoothShade, lighting: false, whiteOnWhiteReversal: false });
130744
130752
  return new BranchState({ viewFlags: vf, transform: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_0__.Transform.createIdentity(), symbologyOverrides: new _FeatureSymbology__WEBPACK_IMPORTED_MODULE_2__.FeatureSymbology.Overrides(), edgeSettings: _EdgeSettings__WEBPACK_IMPORTED_MODULE_3__.EdgeSettings.create(undefined), is3d: true });
130745
130753
  }
130754
+ withViewCoords() {
130755
+ return new BranchState({ ...this._opts, forceViewCoords: true });
130756
+ }
130746
130757
  }
130747
130758
 
130748
130759
 
@@ -132643,7 +132654,9 @@ class DrawParams {
132643
132654
  get target() { return this.programParams.target; }
132644
132655
  get renderPass() { return this.programParams.renderPass; }
132645
132656
  get projectionMatrix() { return this.programParams.projectionMatrix; }
132646
- get isViewCoords() { return this.programParams.isViewCoords; }
132657
+ get isViewCoords() {
132658
+ return this.programParams.isViewCoords || this.target.currentBranch.forceViewCoords;
132659
+ }
132647
132660
  get isOverlayPass() { return this.programParams.isOverlayPass; }
132648
132661
  get context() { return this.programParams.context; }
132649
132662
  init(programParams, geometry) {
@@ -139560,18 +139573,26 @@ class RenderCommands {
139560
139573
  this._commands.forEach((cmds) => cmds.splice(0));
139561
139574
  this._layers.clear();
139562
139575
  }
139563
- initForPickOverlays(sceneOverlays, overlayDecorations) {
139576
+ initForPickOverlayDecorations(overlays) {
139577
+ for (const overlay of overlays) {
139578
+ const gf = overlay;
139579
+ if (gf.isPickable)
139580
+ gf.addCommands(this);
139581
+ }
139582
+ }
139583
+ initForPickOverlays(sceneOverlays, worldOverlayDecorations, viewOverlayDecorations) {
139564
139584
  this._clearCommands();
139565
139585
  this._addTranslucentAsOpaque = true;
139566
139586
  for (const sceneGf of sceneOverlays)
139567
139587
  sceneGf.addCommands(this);
139568
- if (undefined !== overlayDecorations) {
139588
+ if (worldOverlayDecorations === null || worldOverlayDecorations === void 0 ? void 0 : worldOverlayDecorations.length) {
139569
139589
  this.pushAndPopState(this.target.decorationsState, () => {
139570
- for (const overlay of overlayDecorations) {
139571
- const gf = overlay;
139572
- if (gf.isPickable)
139573
- gf.addCommands(this);
139574
- }
139590
+ this.initForPickOverlayDecorations(worldOverlayDecorations);
139591
+ });
139592
+ }
139593
+ if (viewOverlayDecorations === null || viewOverlayDecorations === void 0 ? void 0 : viewOverlayDecorations.length) {
139594
+ this.pushAndPopState(this.target.decorationsState.withViewCoords(), () => {
139595
+ this.initForPickOverlayDecorations(viewOverlayDecorations);
139575
139596
  });
139576
139597
  }
139577
139598
  this._addTranslucentAsOpaque = false;
@@ -141154,7 +141175,7 @@ class Compositor extends SceneCompositor {
141154
141175
  this.target.popViewClip();
141155
141176
  }
141156
141177
  get fullHeight() { return this.target.viewRect.height; }
141157
- drawForReadPixels(commands, sceneOverlays, overlayDecorations) {
141178
+ drawForReadPixels(commands, sceneOverlays, worldOverlayDecorations, viewOverlayDecorations) {
141158
141179
  this.target.beginPerfMetricRecord("Render Background", true);
141159
141180
  if (!this.preDraw()) {
141160
141181
  this.target.endPerfMetricRecord(true); // End Render Background record if returning
@@ -141195,11 +141216,11 @@ class Compositor extends SceneCompositor {
141195
141216
  this.target.endPerfMetricRecord(true);
141196
141217
  this.target.popViewClip();
141197
141218
  }
141198
- if (0 === sceneOverlays.length && (undefined === overlayDecorations || 0 === overlayDecorations.length))
141219
+ if (!sceneOverlays.length && !(worldOverlayDecorations === null || worldOverlayDecorations === void 0 ? void 0 : worldOverlayDecorations.length) && !(viewOverlayDecorations === null || viewOverlayDecorations === void 0 ? void 0 : viewOverlayDecorations.length))
141199
141220
  return;
141200
141221
  // Now populate the opaque passes with any pickable world overlays
141201
141222
  this.target.beginPerfMetricRecord("Overlay Draws", true);
141202
- commands.initForPickOverlays(sceneOverlays, overlayDecorations);
141223
+ commands.initForPickOverlays(sceneOverlays, worldOverlayDecorations, viewOverlayDecorations);
141203
141224
  if (commands.isEmpty) {
141204
141225
  this.target.endPerfMetricRecord(true); // End Overlay Draws record if returning
141205
141226
  return;
@@ -146730,7 +146751,7 @@ class Target extends _RenderTarget__WEBPACK_IMPORTED_MODULE_8__.RenderTarget {
146730
146751
  get frameStatsCollector() { return this._frameStatsCollector; }
146731
146752
  assignFrameStatsCollector(collector) { this._frameStatsCollector = collector; }
146732
146753
  paintScene(sceneMilSecElapsed) {
146733
- var _a;
146754
+ var _a, _b;
146734
146755
  if (!this._dcAssigned)
146735
146756
  return;
146736
146757
  this._frameStatsCollector.beginTime("totalFrameTime");
@@ -146745,7 +146766,7 @@ class Target extends _RenderTarget__WEBPACK_IMPORTED_MODULE_8__.RenderTarget {
146745
146766
  // Set this to true to visualize the output of readPixels()...useful for debugging pick.
146746
146767
  if (this.drawForReadPixels) {
146747
146768
  this.beginReadPixels(_Pixel__WEBPACK_IMPORTED_MODULE_6__.Pixel.Selector.Feature);
146748
- this.compositor.drawForReadPixels(this._renderCommands, this.graphics.overlays, (_a = this.graphics.decorations) === null || _a === void 0 ? void 0 : _a.worldOverlay);
146769
+ this.compositor.drawForReadPixels(this._renderCommands, this.graphics.overlays, (_a = this.graphics.decorations) === null || _a === void 0 ? void 0 : _a.worldOverlay, (_b = this.graphics.decorations) === null || _b === void 0 ? void 0 : _b.viewOverlay);
146749
146770
  this.endReadPixels();
146750
146771
  }
146751
146772
  else {
@@ -146931,7 +146952,7 @@ class Target extends _RenderTarget__WEBPACK_IMPORTED_MODULE_8__.RenderTarget {
146931
146952
  this._isReadPixelsInProgress = false;
146932
146953
  }
146933
146954
  readPixelsFromFbo(rect, selector) {
146934
- var _a;
146955
+ var _a, _b;
146935
146956
  // Create a culling frustum based on the input rect. We can't do this if a screen-space effect is going to move pixels around.
146936
146957
  let rectFrust;
146937
146958
  if (!this.renderSystem.screenSpaceEffects.shouldApply(this)) {
@@ -146962,7 +146983,7 @@ class Target extends _RenderTarget__WEBPACK_IMPORTED_MODULE_8__.RenderTarget {
146962
146983
  }
146963
146984
  this.beginReadPixels(selector, rectFrust);
146964
146985
  // Draw the scene
146965
- this.compositor.drawForReadPixels(this._renderCommands, this.graphics.overlays, (_a = this.graphics.decorations) === null || _a === void 0 ? void 0 : _a.worldOverlay);
146986
+ this.compositor.drawForReadPixels(this._renderCommands, this.graphics.overlays, (_a = this.graphics.decorations) === null || _a === void 0 ? void 0 : _a.worldOverlay, (_b = this.graphics.decorations) === null || _b === void 0 ? void 0 : _b.viewOverlay);
146966
146987
  if (this.performanceMetrics && !this.performanceMetrics.gatherCurPerformanceMetrics) { // Only collect readPixels data if in disp-perf-test-app
146967
146988
  this.performanceMetrics.endOperation(); // End the 'CPU Total Time' operation
146968
146989
  if (this.performanceMetrics.gatherGlFinish && !this.renderSystem.isGLTimerSupported) {
@@ -158700,7 +158721,7 @@ class BatchedTileIdMap {
158700
158721
  const key = JSON.stringify(properties);
158701
158722
  let entry = this._featureMap.get(key);
158702
158723
  if (undefined === entry) {
158703
- const id = this._iModel.transientIds.next;
158724
+ const id = this._iModel.transientIds.getNext();
158704
158725
  entry = { id, properties };
158705
158726
  this._featureMap.set(key, entry);
158706
158727
  this._idMap.set(id, properties);
@@ -165061,7 +165082,7 @@ class RealityModelTileTree extends _internal__WEBPACK_IMPORTED_MODULE_7__.Realit
165061
165082
  constructor(props) {
165062
165083
  super();
165063
165084
  this._name = undefined !== props.name ? props.name : "";
165064
- this._modelId = props.modelId ? props.modelId : props.iModel.transientIds.next;
165085
+ this._modelId = props.modelId ? props.modelId : props.iModel.transientIds.getNext();
165065
165086
  let transform;
165066
165087
  if (undefined !== props.tilesetToDbTransform) {
165067
165088
  const tf = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Transform.fromJSON(props.tilesetToDbTransform);
@@ -172795,7 +172816,7 @@ class ImageryMapLayerTreeSupplier {
172795
172816
  if (undefined === imageryProvider)
172796
172817
  return undefined;
172797
172818
  await imageryProvider.initialize();
172798
- const modelId = iModel.transientIds.next;
172819
+ const modelId = iModel.transientIds.getNext();
172799
172820
  const tilingScheme = imageryProvider.tilingScheme;
172800
172821
  const rootLevel = (1 === tilingScheme.numberOfLevelZeroTilesX && 1 === tilingScheme.numberOfLevelZeroTilesY) ? 0 : -1;
172801
172822
  const rootTileId = new _internal__WEBPACK_IMPORTED_MODULE_4__.QuadId(rootLevel, 0, 0).contentId;
@@ -175359,7 +175380,7 @@ class MapTreeSupplier {
175359
175380
  async createTileTree(id, iModel) {
175360
175381
  let bimElevationBias = 0, terrainProvider, geodeticOffset = 0;
175361
175382
  let applyTerrain = id.applyTerrain;
175362
- const modelId = iModel.transientIds.next;
175383
+ const modelId = iModel.transientIds.getNext();
175363
175384
  const gcsConverterAvailable = await getGcsConverterAvailable(iModel);
175364
175385
  const terrainOpts = {
175365
175386
  wantSkirts: id.wantSkirts,
@@ -179409,7 +179430,7 @@ class ViewClipDecoration extends _EditManipulator__WEBPACK_IMPORTED_MODULE_8__.E
179409
179430
  this._suspendDecorator = false;
179410
179431
  if (!this.getClipData())
179411
179432
  return;
179412
- this._clipId = this.iModel.transientIds.next;
179433
+ this._clipId = this.iModel.transientIds.getNext();
179413
179434
  this.updateDecorationListener(true);
179414
179435
  this._removeViewCloseListener = _IModelApp__WEBPACK_IMPORTED_MODULE_6__.IModelApp.viewManager.onViewClose.addListener(this.onViewClose, this); // eslint-disable-line @typescript-eslint/unbound-method
179415
179436
  if (undefined !== this._clipEventHandler && this._clipEventHandler.selectOnCreate())
@@ -179491,7 +179512,7 @@ class ViewClipDecoration extends _EditManipulator__WEBPACK_IMPORTED_MODULE_8__.E
179491
179512
  if (numCurrent < numReqControls) {
179492
179513
  const transientIds = this.iModel.transientIds;
179493
179514
  for (let i = numCurrent; i < numReqControls; i++)
179494
- this._controlIds[i] = transientIds.next;
179515
+ this._controlIds[i] = transientIds.getNext();
179495
179516
  }
179496
179517
  else if (numCurrent > numReqControls) {
179497
179518
  this._controlIds.length = numReqControls;
@@ -181796,7 +181817,7 @@ class MeasureDistanceTool extends _PrimitiveTool__WEBPACK_IMPORTED_MODULE_11__.P
181796
181817
  if (undefined === snapPoints)
181797
181818
  return;
181798
181819
  if (undefined === this._snapGeomId)
181799
- this._snapGeomId = this.iModel.transientIds.next;
181820
+ this._snapGeomId = this.iModel.transientIds.getNext();
181800
181821
  const builderSnapPts = context.createGraphicBuilder(_render_GraphicBuilder__WEBPACK_IMPORTED_MODULE_10__.GraphicType.WorldOverlay, undefined, this._snapGeomId);
181801
181822
  const colorAccPts = _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.ColorDef.white.adjustedForContrast(context.viewport.view.backgroundColor);
181802
181823
  builderSnapPts.setSymbology(colorAccPts, _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.ColorDef.black, 7);
@@ -228066,11 +228087,13 @@ __webpack_require__.r(__webpack_exports__);
228066
228087
 
228067
228088
  /* cspell:word cxcz, cxsz, cxcy, cxsy, sxcz, sxsz, sxcy, sxsy, cycz, cysz, sycz, sysz */
228068
228089
  /**
228069
- * * represents a non-trivial rotation using three simple axis rotation angles and an
228070
- * order in which to apply them.
228090
+ * represents a non-trivial rotation using three simple axis rotation angles and an order in which to apply them.
228071
228091
  * * This class accommodates application-specific interpretation of "multiplying 3 rotation matrices" with regard to
228072
228092
  * * Whether a "vector" is a "row" or a "column"
228073
228093
  * * The order in which the X,Y,Z rotations are applied.
228094
+ * * This class bakes in angle rotation directions via create functions (i.e., createRadians, createDegrees, and
228095
+ * createAngles) so you can define each of the 3 rotations to be clockwise or counterclockwise. The default
228096
+ * rotation is counterclockwise.
228074
228097
  * * Within the imodel geometry library, the preferred rotation order is encapsulated in `YawPitchRollAngles`.
228075
228098
  * @alpha
228076
228099
  */
@@ -228122,7 +228145,7 @@ class OrderedRotationAngles {
228122
228145
  get zRadians() {
228123
228146
  return this._z.radians;
228124
228147
  }
228125
- /** Flag controlling whether vectors are treated as rows or as columns */
228148
+ /** the flag controlling whether vectors are treated as rows or as columns */
228126
228149
  static get treatVectorsAsColumns() {
228127
228150
  return OrderedRotationAngles._sTreatVectorsAsColumns;
228128
228151
  }
@@ -228130,68 +228153,81 @@ class OrderedRotationAngles {
228130
228153
  OrderedRotationAngles._sTreatVectorsAsColumns = value;
228131
228154
  }
228132
228155
  /**
228133
- * Create an OrderedRotationAngles from three angles and an ordering in which to apply them when rotating.
228134
- * @param xRotation rotation around x
228135
- * @param yRotation rotation around y
228136
- * @param zRotation rotation around z
228156
+ * Create an OrderedRotationAngles from three angles (in radians), an ordering in which to apply them when
228157
+ * rotating, and a flag triple controlling whether direction of x,y,z is clockwise or counterclockwise.
228158
+ * @param xRadians rotation around x
228159
+ * @param yRadians rotation around y
228160
+ * @param zRadians rotation around z
228137
228161
  * @param order left to right order of axis names identifies the order that rotations are applied.
228138
228162
  * For example XYZ means to rotate around x axis first, then y axis, and finally Z axis.
228139
228163
  * * Note that rotation order is reverse of rotation matrix multiplication so for XYZ the rotation
228140
228164
  * matrix multiplication would be zRot*yRot*xRot
228141
- */
228142
- static createAngles(xRotation, yRotation, zRotation, order, result) {
228165
+ * @param xyzRotationIsClockwise the flags controlling whether direction of x,y,z is clockwise or counterclockwise.
228166
+ * rotation direction of x,y,z: true ---> clockwise - false ---> counterclockwise.
228167
+ * * if xyzRotationIsClockwise is undefined it's set to [false, false, false].
228168
+ * @param result caller-allocated OrderedRotationAngles
228169
+ */
228170
+ static createRadians(xRadians, yRadians, zRadians, order, xyzRotationIsClockwise, result) {
228171
+ if (!xyzRotationIsClockwise) {
228172
+ xyzRotationIsClockwise = [false, false, false];
228173
+ }
228174
+ const xRadian = xyzRotationIsClockwise[0] ? -xRadians : xRadians;
228175
+ const yRadian = xyzRotationIsClockwise[1] ? -yRadians : yRadians;
228176
+ const zRadian = xyzRotationIsClockwise[2] ? -zRadians : zRadians;
228143
228177
  if (result) {
228144
- result._x.setFrom(xRotation);
228145
- result._y.setFrom(yRotation);
228146
- result._z.setFrom(zRotation);
228178
+ result._x.setRadians(xRadian);
228179
+ result._y.setRadians(yRadian);
228180
+ result._z.setRadians(zRadian);
228147
228181
  result._order = order;
228148
228182
  return result;
228149
228183
  }
228150
- return new OrderedRotationAngles(xRotation.clone(), yRotation.clone(), zRotation.clone(), order);
228184
+ return new OrderedRotationAngles(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(xRadian), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(yRadian), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(zRadian), order);
228151
228185
  }
228152
228186
  /**
228153
- * Create an OrderedRotationAngles from three angles (in radians) and an ordering in which to apply
228187
+ * Create an OrderedRotationAngles from three angles (in degrees) and an ordering in which to apply
228154
228188
  * them when rotating.
228155
- * @param xRadians rotation around x
228156
- * @param yRadians rotation around y
228157
- * @param zRadians rotation around z
228189
+ * @param xDegrees rotation around x
228190
+ * @param yDegrees rotation around y
228191
+ * @param zDegrees rotation around z
228158
228192
  * @param order left to right order of axis names identifies the order that rotations are applied.
228159
228193
  * For example XYZ means to rotate around x axis first, then y axis, and finally Z axis.
228160
228194
  * * Note that rotation order is reverse of rotation matrix multiplication so for XYZ the rotation
228161
228195
  * matrix multiplication would be zRot*yRot*xRot
228196
+ * @param xyzRotationIsClockwise the flags controlling whether direction of x,y,z is clockwise or counterclockwise.
228197
+ * rotation direction of x,y,z: true ---> clockwise - false ---> counterclockwise.
228198
+ * * if xyzRotationIsClockwise is undefined it's set to [false, false, false].
228199
+ * @param result caller-allocated OrderedRotationAngles
228162
228200
  */
228163
- static createRadians(xRadians, yRadians, zRadians, order, result) {
228164
- if (result) {
228165
- result._x.setRadians(xRadians);
228166
- result._y.setRadians(yRadians);
228167
- result._z.setRadians(zRadians);
228168
- result._order = order;
228169
- return result;
228170
- }
228171
- return new OrderedRotationAngles(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(xRadians), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(yRadians), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(zRadians), order);
228201
+ static createDegrees(xDegrees, yDegrees, zDegrees, order, xyzRotationIsClockwise, result) {
228202
+ return OrderedRotationAngles.createRadians(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.degreesToRadians(xDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.degreesToRadians(yDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.degreesToRadians(zDegrees), order, xyzRotationIsClockwise, result);
228172
228203
  }
228173
228204
  /**
228174
- * Create an OrderedRotationAngles from three angles (in degrees) and an ordering in which to apply
228175
- * them when rotating.
228176
- * @param xRadians rotation around x
228177
- * @param yRadians rotation around y
228178
- * @param zRadians rotation around z
228179
- * @param order left to right order of axis names identifies the order that rotations are applied.
228205
+ * Create an OrderedRotationAngles from three angles, an ordering in which to apply them when rotating,
228206
+ * and a flag triple controlling whether direction of x,y,z is clockwise or counterclockwise.
228207
+ * @param xRotation rotation around x
228208
+ * @param yRotation rotation around y
228209
+ * @param zRotation rotation around z
228210
+ * @param order left to right order of axis names identifies the order that rotations are applied
228180
228211
  * For example XYZ means to rotate around x axis first, then y axis, and finally Z axis.
228181
228212
  * * Note that rotation order is reverse of rotation matrix multiplication so for XYZ the rotation
228182
228213
  * matrix multiplication would be zRot*yRot*xRot
228214
+ * @param xyzRotationIsClockwise the flags controlling whether direction of x,y,z is clockwise or counterclockwise.
228215
+ * rotation direction of x,y,z: true ---> clockwise - false ---> counterclockwise.
228216
+ * * if xyzRotationIsClockwise is undefined it's set to [false, false, false].
228217
+ * @param result caller-allocated OrderedRotationAngles
228183
228218
  */
228184
- static createDegrees(xDegrees, yDegrees, zDegrees, order, result) {
228185
- if (result) {
228186
- result._x.setDegrees(xDegrees);
228187
- result._y.setDegrees(yDegrees);
228188
- result._z.setDegrees(zDegrees);
228189
- result._order = order;
228190
- return result;
228191
- }
228192
- return new OrderedRotationAngles(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(xDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(yDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(zDegrees), order);
228219
+ static createAngles(xRotation, yRotation, zRotation, order, xyzRotationIsClockwise, result) {
228220
+ return OrderedRotationAngles.createRadians(xRotation.radians, yRotation.radians, zRotation.radians, order, xyzRotationIsClockwise, result);
228193
228221
  }
228194
- /** Create an OrderedRotationAngles from a 3x3 rotational matrix, given the ordering of axis rotations that the matrix derives from. */
228222
+ /**
228223
+ * Create an OrderedRotationAngles from a 3x3 rotational matrix, given the ordering of axis rotations
228224
+ * that the matrix derives from.
228225
+ * * This function creates an OrderedRotationAngles with default angle rotation directions, i.e.,
228226
+ * it assumes all x, y, and z rotations are counterclockwise.
228227
+ * * In the failure case the method's return value is `undefined`.
228228
+ * * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
228229
+ * a set of angles.
228230
+ * */
228195
228231
  static createFromMatrix3d(matrix, order, result) {
228196
228232
  // treat vector as columns
228197
228233
  let m11 = matrix.coffs[0], m12 = matrix.coffs[1], m13 = matrix.coffs[2];
@@ -228214,13 +228250,19 @@ class OrderedRotationAngles {
228214
228250
  zRad = Math.atan2(m21, m11);
228215
228251
  }
228216
228252
  else {
228217
- /*
228218
- * If Math.abs(m31) = 1 then yRad = 90 degrees and therefore, we have a gimbal lock.
228219
- * This means xRad and zRad can be anything as long as their sum xRad + zRad is constant.
228220
- * so we can pick zRad = 0 and calculate xRad (or pick xRad = 0 and calculate zRad).
228221
- * Math details can be found
228222
- * https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles
228223
- */
228253
+ /**
228254
+ * If Math.abs(m31) = 1 then yRad = +-90 degrees and therefore, we have a gimbal lock.
228255
+ * This means xRad and zRad can be anything as long as their sum xRad + zRad is constant.
228256
+ * so we can pick zRad = 0 and calculate xRad (or pick xRad = 0 and calculate zRad).
228257
+ * Therefore, rotation matrix becomes
228258
+ * Matrix3d.createRowValues(
228259
+ * 0, +-sx, +-cx,
228260
+ * 0, cx, -sx,
228261
+ * -+1, 0, 0
228262
+ * );
228263
+ * Math details can be found
228264
+ * https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles
228265
+ */
228224
228266
  xRad = Math.atan2(-m23, m22);
228225
228267
  zRad = 0;
228226
228268
  }
@@ -228290,7 +228332,21 @@ class OrderedRotationAngles {
228290
228332
  xRad = yRad = zRad = 0;
228291
228333
  }
228292
228334
  }
228293
- return OrderedRotationAngles.createRadians(xRad, yRad, zRad, order, result);
228335
+ const xyzRotationIsClockwise = [false, false, false];
228336
+ const angles = OrderedRotationAngles.createRadians(xRad, yRad, zRad, order, xyzRotationIsClockwise, result);
228337
+ // sanity check
228338
+ const matrix1 = angles.toMatrix3d();
228339
+ /**
228340
+ * Below tolerance loosened to allow sanity check to pass for
228341
+ *
228342
+ * OrderedRotationAngles.createFromMatrix3d(
228343
+ * OrderedRotationAngles.createDegrees(0, 89.999, 0.001, AxisOrder.XYZ).toMatrix3d(),
228344
+ * AxisOrder.XYZ
228345
+ * );
228346
+ *
228347
+ * with treatVectorsAsColumns = true.
228348
+ */
228349
+ return (matrix.maxDiff(matrix1) < 10 * _Geometry__WEBPACK_IMPORTED_MODULE_1__.Geometry.smallFraction) ? angles : undefined;
228294
228350
  }
228295
228351
  /**
228296
228352
  * Create a 3x3 rotational matrix from this OrderedRotationAngles.
@@ -237385,39 +237441,62 @@ __webpack_require__.r(__webpack_exports__);
237385
237441
 
237386
237442
 
237387
237443
 
237388
- // cspell:word Tait
237389
- /** Three angles that determine the orientation of an object in space. Sometimes referred to as [Tait–Bryan angles](https://en.wikipedia.org/wiki/Euler_angles).
237444
+ /**
237445
+ * Three angles that determine the orientation of an object in space, sometimes referred to as [Tait–Bryan angles]
237446
+ * (https://en.wikipedia.org/wiki/Euler_angles).
237390
237447
  * * The matrix construction can be replicated by this logic:
237391
237448
  * * xyz coordinates have
237392
237449
  * * x forward
237393
237450
  * * y to left
237394
237451
  * * z up
237395
- * * Note that this is a right handed coordinate system.
237396
- * * yaw is a rotation of x towards y, i.e. around positive z:
237452
+ * * Note that this is a right handed coordinate system.
237453
+ * * yaw is a rotation of x towards y, i.e. around positive z (counterclockwise):
237397
237454
  * * `yawMatrix = Matrix3d.createRotationAroundAxisIndex(2, Angle.createDegrees(yawDegrees));`
237398
- * * pitch is a rotation that raises x towards z, i.e. rotation around negative y:
237455
+ * * pitch is a rotation that raises x towards z, i.e. rotation around **negative y** (**clockwise**):
237399
237456
  * * `pitchMatrix = Matrix3d.createRotationAroundAxisIndex(1, Angle.createDegrees(-pitchDegrees));`
237400
- * * roll is rotation of y towards z, i.e. rotation around positive x:
237457
+ * * roll is rotation of y towards z, i.e. rotation around positive x (counterclockwise):
237401
237458
  * * `rollMatrix = Matrix3d.createRotationAroundAxisIndex(0, Angle.createDegrees(rollDegrees));`
237402
- * * The YPR matrix is the product
237459
+ * * The YPR matrix is the product
237403
237460
  * * `result = yawMatrix.multiplyMatrixMatrix(pitchMatrix.multiplyMatrixMatrix(rollMatrix));`
237404
- * * Note that this is for "column based" matrix, with vectors appearing to the right
237405
- * * Hence a vector is first rotated by roll, then the pitch, finally yaw.
237461
+ * * Note that this is for "column based" matrix with vectors multiplying on the right of the matrix.
237462
+ * Hence a vector is first rotated by roll, then the pitch, finally yaw. So multiplication order in
237463
+ * the sense of AxisOrder is `RPY` (i.e., XYZ), in contrast to the familiar name `YPR`.
237406
237464
  * @public
237407
237465
  */
237408
237466
  class YawPitchRollAngles {
237467
+ /**
237468
+ * constructor
237469
+ * @param yaw counterclockwise rotation angle around z
237470
+ * @param pitch **clockwise** rotation angle around y
237471
+ * @param roll counterclockwise rotation angle around x
237472
+ * */
237409
237473
  constructor(yaw = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.zero(), pitch = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.zero(), roll = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.zero()) {
237410
237474
  this.yaw = yaw;
237411
237475
  this.pitch = pitch;
237412
237476
  this.roll = roll;
237413
237477
  }
237414
237478
  /** Freeze this YawPitchRollAngles */
237415
- freeze() { this.yaw.freeze(); this.pitch.freeze(); this.roll.freeze(); return Object.freeze(this); }
237416
- /** constructor for YawPitchRollAngles with angles in degrees. */
237479
+ freeze() {
237480
+ this.yaw.freeze();
237481
+ this.pitch.freeze();
237482
+ this.roll.freeze();
237483
+ return Object.freeze(this);
237484
+ }
237485
+ /**
237486
+ * constructor for YawPitchRollAngles with angles in degrees.
237487
+ * @param yawDegrees counterclockwise rotation angle (in degrees) around z
237488
+ * @param pitchDegrees **clockwise** rotation angle (in degrees) around y
237489
+ * @param rollDegrees counterclockwise rotation angle (in degrees) around x
237490
+ * */
237417
237491
  static createDegrees(yawDegrees, pitchDegrees, rollDegrees) {
237418
237492
  return new YawPitchRollAngles(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(yawDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(pitchDegrees), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createDegrees(rollDegrees));
237419
237493
  }
237420
- /** constructor for YawPitchRollAngles with angles in radians. */
237494
+ /**
237495
+ * constructor for YawPitchRollAngles with angles in radians.
237496
+ * @param yawRadians counterclockwise rotation angle (in radians) around z
237497
+ * @param pitchRadians **clockwise** rotation angle (in radians) around y
237498
+ * @param rollRadians counterclockwise rotation angle (in radians) around x
237499
+ * */
237421
237500
  static createRadians(yawRadians, pitchRadians, rollRadians) {
237422
237501
  return new YawPitchRollAngles(_Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(yawRadians), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(pitchRadians), _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(rollRadians));
237423
237502
  }
@@ -237433,7 +237512,10 @@ class YawPitchRollAngles {
237433
237512
  this.pitch = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.fromJSON(json.pitch);
237434
237513
  this.roll = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.fromJSON(json.roll);
237435
237514
  }
237436
- /** Convert to a JSON object of form { pitch: 20 , roll: 29.999999999999996 , yaw: 10 }. Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted. */
237515
+ /**
237516
+ * Convert to a JSON object of form { pitch: 20 , roll: 30 , yaw: 10 }. Angles are in degrees.
237517
+ * Any values that are exactly zero (with tolerance `Geometry.smallAngleRadians`) are omitted.
237518
+ **/
237437
237519
  toJSON() {
237438
237520
  const val = {};
237439
237521
  if (!this.pitch.isAlmostZero)
@@ -237454,7 +237536,7 @@ class YawPitchRollAngles {
237454
237536
  this.roll.setFrom(other.roll);
237455
237537
  }
237456
237538
  /**
237457
- * * Compare angles between `this` and `other`.
237539
+ * Compare angles between `this` and `other`.
237458
237540
  * * Comparisons are via `isAlmostEqualAllowPeriodShift`.
237459
237541
  * @param other YawPitchRollAngles source
237460
237542
  */
@@ -237466,30 +237548,47 @@ class YawPitchRollAngles {
237466
237548
  /**
237467
237549
  * Make a copy of this YawPitchRollAngles.
237468
237550
  */
237469
- clone() { return new YawPitchRollAngles(this.yaw.clone(), this.pitch.clone(), this.roll.clone()); }
237551
+ clone() {
237552
+ return new YawPitchRollAngles(this.yaw.clone(), this.pitch.clone(), this.roll.clone());
237553
+ }
237470
237554
  /**
237471
237555
  * Expand the angles into a (rigid rotation) matrix.
237472
237556
  *
237473
- * * The returned matrix is "rigid" -- unit length rows and columns, and its transpose is its inverse.
237474
- * * The "rigid" matrix is always a right handed coordinate system.
237557
+ * * The returned matrix is "rigid" (i.e., it has unit length rows and columns, and its transpose is its inverse).
237558
+ * * The rigid matrix is always a right handed coordinate system.
237475
237559
  * @param result optional pre-allocated `Matrix3d`
237476
237560
  */
237477
237561
  toMatrix3d(result) {
237478
- const c0 = Math.cos(this.yaw.radians);
237479
- const s0 = Math.sin(this.yaw.radians);
237480
- const c1 = Math.cos(this.pitch.radians);
237481
- const s1 = Math.sin(this.pitch.radians);
237482
- const c2 = Math.cos(this.roll.radians);
237483
- const s2 = Math.sin(this.roll.radians);
237484
- return _Matrix3d__WEBPACK_IMPORTED_MODULE_1__.Matrix3d.createRowValues(c0 * c1, -(s0 * c2 + c0 * s1 * s2), (s0 * s2 - c0 * s1 * c2), s0 * c1, (c0 * c2 - s0 * s1 * s2), -(c0 * s2 + s0 * s1 * c2), s1, c1 * s2, c1 * c2, result);
237485
- }
237486
- /** Return the largest angle in radians */
237487
- maxAbsRadians() {
237488
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.maxAbsXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
237489
- }
237490
- /** Return the sum of the angles in squared radians */
237491
- sumSquaredRadians() {
237492
- return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.hypotenuseSquaredXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
237562
+ const cz = Math.cos(this.yaw.radians);
237563
+ const sz = Math.sin(this.yaw.radians);
237564
+ const cy = Math.cos(this.pitch.radians);
237565
+ const sy = Math.sin(this.pitch.radians);
237566
+ const cx = Math.cos(this.roll.radians);
237567
+ const sx = Math.sin(this.roll.radians);
237568
+ /**
237569
+ * The axis order is XYZ (i.e., RPY) so the rotation matrix is calculated via rZ*rY*rX where
237570
+ * rX, rY, and rZ are base rotation matrixes:
237571
+ *
237572
+ * const rX = Matrix3d.createRowValues(
237573
+ * 1, 0, 0,
237574
+ * 0, Math.cos(x), -Math.sin(x),
237575
+ * 0, Math.sin(x), Math.cos(x),
237576
+ * );
237577
+ * const rY = Matrix3d.createRowValues(
237578
+ * Math.cos(y), 0, Math.sin(y),
237579
+ * 0, 1, 0,
237580
+ * -Math.sin(y), 0, Math.cos(y),
237581
+ * );
237582
+ * const rZ = Matrix3d.createRowValues(
237583
+ * Math.cos(z), -Math.sin(z), 0,
237584
+ * Math.sin(z), Math.cos(z), 0,
237585
+ * 0, 0, 1,
237586
+ * );
237587
+ *
237588
+ * Then we replace sin(y) with -sin(y) because y rotation (i.e., pitch) is clockwise (alternatively, you
237589
+ * can use transpose of rY in the matrix multiplication to get the same result)
237590
+ */
237591
+ return _Matrix3d__WEBPACK_IMPORTED_MODULE_1__.Matrix3d.createRowValues(cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx), sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx), sy, cy * sx, cy * cx, result);
237493
237592
  }
237494
237593
  /** Returns true if this rotation does nothing.
237495
237594
  * * If allowPeriodShift is false, any nonzero angle is considered a non-identity
@@ -237505,52 +237604,104 @@ class YawPitchRollAngles {
237505
237604
  && _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.pitch.radians)
237506
237605
  && _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.isAlmostEqualRadiansNoPeriodShift(0.0, this.roll.radians);
237507
237606
  }
237607
+ /** Return the largest angle in radians */
237608
+ maxAbsRadians() {
237609
+ return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.maxAbsXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
237610
+ }
237611
+ /** Return the sum of the angles in squared radians */
237612
+ sumSquaredRadians() {
237613
+ return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.hypotenuseSquaredXYZ(this.yaw.radians, this.pitch.radians, this.roll.radians);
237614
+ }
237508
237615
  /** Return the largest difference of angles (in radians) between this and other */
237509
237616
  maxDiffRadians(other) {
237510
237617
  return Math.max(this.yaw.radians - other.yaw.radians, this.pitch.radians - other.pitch.radians, this.roll.radians - other.roll.radians);
237511
237618
  }
237512
237619
  /** Return the largest angle in degrees. */
237513
- maxAbsDegrees() { return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.maxAbsXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees); }
237620
+ maxAbsDegrees() {
237621
+ return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.maxAbsXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);
237622
+ }
237514
237623
  /** Return the sum of squared angles in degrees. */
237515
- sumSquaredDegrees() { return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.hypotenuseSquaredXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees); }
237624
+ sumSquaredDegrees() {
237625
+ return _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.hypotenuseSquaredXYZ(this.yaw.degrees, this.pitch.degrees, this.roll.degrees);
237626
+ }
237627
+ /** Return the largest difference of angles (in degrees) between this and other */
237628
+ maxDiffDegrees(other) {
237629
+ return Math.max(this.yaw.degrees - other.yaw.degrees, this.pitch.degrees - other.pitch.degrees, this.roll.degrees - other.roll.degrees);
237630
+ }
237516
237631
  /** Return an object from a Transform as an origin and YawPitchRollAngles. */
237517
237632
  static tryFromTransform(transform) {
237518
- // bundle up the transform's origin with the angle data extracted from the transform
237519
237633
  return {
237520
- angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),
237521
237634
  origin: _Point3dVector3d__WEBPACK_IMPORTED_MODULE_3__.Point3d.createFrom(transform.origin),
237635
+ angles: YawPitchRollAngles.createFromMatrix3d(transform.matrix),
237522
237636
  };
237523
237637
  }
237524
- /** Attempts to create a YawPitchRollAngles object from an Matrix3d
237525
- * * This conversion fails if the matrix is not rigid (unit rows and columns, transpose is inverse)
237638
+ /** Attempts to create a YawPitchRollAngles object from a Matrix3d
237639
+ * * This conversion fails if the matrix is not rigid (unit rows and columns, and transpose is inverse)
237526
237640
  * * In the failure case the method's return value is `undefined`.
237527
- * * In the failure case, if the optional result was supplied, that result will nonetheless be filled with a set of angles.
237641
+ * * In the failure case, if the optional result was supplied, that result will nonetheless be filled with
237642
+ * a set of angles.
237528
237643
  */
237529
237644
  static createFromMatrix3d(matrix, result) {
237530
- const s1 = matrix.at(2, 0);
237531
- const c1 = Math.sqrt(matrix.at(2, 1) * matrix.at(2, 1) + matrix.at(2, 2) * matrix.at(2, 2));
237532
- const pitchA = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(s1, c1); // with positive cosine
237533
- const pitchB = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(s1, -c1); // with negative cosine
237534
- const angles = result ? result : new YawPitchRollAngles(); // default undefined . . .
237535
- if (c1 < _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) { // This is a radians test !!!
237645
+ /**
237646
+ * The rotation matrix for is
237647
+ *
237648
+ * Matrix3d.createRowValues(
237649
+ * cz * cy, -(sz * cx + cz * sy * sx), (sz * sx - cz * sy * cx),
237650
+ * sz * cy, (cz * cx - sz * sy * sx), -(cz * sx + sz * sy * cx),
237651
+ * sy, cy * sx, cy * cx
237652
+ * );
237653
+ *
237654
+ * where cx = cos(x), sx = sin(x), cy = cos(y), sy = sin(y), cz = cos(z), and sz = sin(z)
237655
+ */
237656
+ const sy = matrix.at(2, 0); // sin(y)
237657
+ const cy = Math.sqrt(matrix.at(2, 1) * matrix.at(2, 1) + matrix.at(2, 2) * matrix.at(2, 2)); // |cos(y)|
237658
+ const pitchA = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(sy, cy); // with positive cosine
237659
+ const pitchB = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(sy, -cy); // with negative cosine
237660
+ const angles = result ? result : new YawPitchRollAngles();
237661
+ /**
237662
+ * If cos(y) = 0 then y = +-90 degrees so we have a gimbal lock.
237663
+ * This means x and z can be anything as long as their sum x + z is constant.
237664
+ * so we can pick z = 0 and calculate x (or pick x = 0 and calculate z).
237665
+ * Math details can be found
237666
+ * https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles
237667
+ *
237668
+ * The rotation matrix for y = +-90 degrees and x = 0 becomes
237669
+ *
237670
+ * Matrix3d.createRowValues(
237671
+ * 0, -sz, -+cz,
237672
+ * 0, cz, -+sz,
237673
+ * +-1, 0, 0
237674
+ * );
237675
+ *
237676
+ * so z = atan(sz/cz) = atan(-matrix.at(0, 1), matrix.at(1, 1))
237677
+ */
237678
+ if (cy < _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians) {
237536
237679
  angles.yaw = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(-matrix.at(0, 1), matrix.at(1, 1));
237537
- angles.pitch = pitchA;
237680
+ angles.pitch = pitchA; // this is an arbitrary choice. can pick pitchB instead.
237538
237681
  angles.roll = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createRadians(0.0);
237539
237682
  }
237540
237683
  else {
237684
+ /**
237685
+ * positive cosine
237686
+ * z = atan(sz/cz) = atan(matrix.at(1, 0), matrix.at(0, 0))
237687
+ * x = atan(sx/cx) = atan(matrix.at(2, 1), matrix.at(2, 2))
237688
+ */
237541
237689
  const yawA = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(matrix.at(1, 0), matrix.at(0, 0));
237542
237690
  const rollA = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(matrix.at(2, 1), matrix.at(2, 2));
237691
+ // similar with negative cosine
237543
237692
  const yawB = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(-matrix.at(1, 0), -matrix.at(0, 0));
237544
237693
  const rollB = _Angle__WEBPACK_IMPORTED_MODULE_0__.Angle.createAtan2(-matrix.at(2, 1), -matrix.at(2, 2));
237694
+ // create YPR
237545
237695
  const yprA = new YawPitchRollAngles(yawA, pitchA, rollA);
237546
237696
  const yprB = new YawPitchRollAngles(yawB, pitchB, rollB);
237697
+ // decide to pick yprA or yprB with smallest magnitude angles
237547
237698
  const absFactor = 0.95;
237548
- const radiansA = yprA.maxAbsRadians();
237549
- const radiansB = yprB.maxAbsRadians();
237550
- if (radiansA < absFactor * radiansB) {
237699
+ const maxRadiansA = yprA.maxAbsRadians();
237700
+ const maxRadiansB = yprB.maxAbsRadians();
237701
+ if (maxRadiansA < absFactor * maxRadiansB) {
237551
237702
  angles.setFrom(yprA);
237552
237703
  }
237553
- else if (radiansB < absFactor * radiansA) {
237704
+ else if (maxRadiansB < absFactor * maxRadiansA) {
237554
237705
  angles.setFrom(yprB);
237555
237706
  }
237556
237707
  else {
@@ -237564,6 +237715,7 @@ class YawPitchRollAngles {
237564
237715
  }
237565
237716
  }
237566
237717
  }
237718
+ // sanity check
237567
237719
  const matrix1 = angles.toMatrix3d();
237568
237720
  return matrix.maxDiff(matrix1) < _Geometry__WEBPACK_IMPORTED_MODULE_2__.Geometry.smallAngleRadians ? angles : undefined;
237569
237721
  }
@@ -250531,6 +250683,85 @@ class PolyfaceQuery {
250531
250683
  const inertiaProducts = PolyfaceQuery.sumFacetSecondVolumeMomentProducts(source, origin);
250532
250684
  return _geometry4d_MomentData__WEBPACK_IMPORTED_MODULE_7__.MomentData.inertiaProductsToPrincipalAxes(origin, inertiaProducts);
250533
250685
  }
250686
+ /**
250687
+ * Test for convex volume by dihedral angle tests on all edges.
250688
+ * * This tests if all dihedral angles are positive.
250689
+ * * In a closed solid, this is a strong test for overall convexity.
250690
+ * * With `ignoreBoundaries` true, this may be a useful test when all the facets are in a single edge-connected component, such as a pyramid with no underside.
250691
+ * * It is not a correct test if there are multiple, disjoint components.
250692
+ * * Take the above-mentioned pyramid with no underside.
250693
+ * * Within the same mesh, have a second pyramid placed to the side, still facing upward.
250694
+ * * The angles will pass the dihedral convexity test, but the composite thing surely is not convex.
250695
+ * @param source mesh to examine
250696
+ * @param ignoreBoundaries if true, ignore simple boundary edges, i.e. allow unclosed meshes.
250697
+ * @returns true if the mesh is closed and has all dihedral angles (angle across edge) positive
250698
+ */
250699
+ static isConvexByDihedralAngleCount(source, ignoreBoundaries = false) {
250700
+ return this.dihedralAngleSummary(source, ignoreBoundaries) > 0;
250701
+ }
250702
+ /**
250703
+ * Compute a number summarizing the dihedral angles in the mesh.
250704
+ * @see [[isConvexByDihedralAngleCount]] for comments about ignoreBoundaries===true when there are multiple connected components.
250705
+ * @param source mesh to examine
250706
+ * @param ignoreBoundaries if true, ignore simple boundary edges, i.e. allow unclosed meshes.
250707
+ * @returns a number summarizing the dihedral angles in the mesh.
250708
+ * * Return 1 if all angles are positive or planar. The mesh is probably convex with outward normals.
250709
+ * * Return -1 if all angles are negative or planar. The mesh is probably convex with inward normals.
250710
+ * * Return 0 if
250711
+ * * angles area mixed
250712
+ * * any edge has other than 1 incident facet or more than 2 incident facets.
250713
+ * * (but null edges are permitted -- These occur naturally at edges of quads at north or south pole)
250714
+ */
250715
+ static dihedralAngleSummary(source, ignoreBoundaries = false) {
250716
+ const edges = new _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.IndexedEdgeMatcher();
250717
+ const visitor = source.createVisitor(1);
250718
+ visitor.reset();
250719
+ const centroidNormal = [];
250720
+ let normalCounter = 0;
250721
+ while (visitor.moveToNextFacet()) {
250722
+ const numEdges = visitor.pointCount - 1;
250723
+ const normal = _geometry3d_PolygonOps__WEBPACK_IMPORTED_MODULE_4__.PolygonOps.centroidAreaNormal(visitor.point);
250724
+ if (normal === undefined)
250725
+ return 0;
250726
+ centroidNormal.push(normal);
250727
+ for (let i = 0; i < numEdges; i++) {
250728
+ edges.addEdge(visitor.clientPointIndex(i), visitor.clientPointIndex(i + 1), normalCounter);
250729
+ }
250730
+ normalCounter++;
250731
+ }
250732
+ const badClusters = [];
250733
+ const manifoldClusters = [];
250734
+ edges.sortAndCollectClusters(manifoldClusters, ignoreBoundaries ? undefined : badClusters, undefined, badClusters);
250735
+ if (badClusters.length > 0)
250736
+ return 0;
250737
+ let numPositive = 0;
250738
+ let numPlanar = 0;
250739
+ let numNegative = 0;
250740
+ const edgeVector = _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_6__.Vector3d.create();
250741
+ for (const cluster of manifoldClusters) {
250742
+ const sideA = cluster.at(0);
250743
+ const sideB = cluster.at(1);
250744
+ if (sideA instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
250745
+ && sideB instanceof _IndexedEdgeMatcher__WEBPACK_IMPORTED_MODULE_9__.SortableEdge
250746
+ && source.data.point.vectorIndexIndex(sideA.vertexIndexA, sideA.vertexIndexB, edgeVector)) {
250747
+ const dihedralAngle = centroidNormal[sideA.facetIndex].direction.signedAngleTo(centroidNormal[sideB.facetIndex].direction, edgeVector);
250748
+ if (dihedralAngle.isAlmostZero)
250749
+ numPlanar++;
250750
+ else if (dihedralAngle.radians > 0.0)
250751
+ numPositive++;
250752
+ else
250753
+ numNegative++;
250754
+ }
250755
+ }
250756
+ if (numPositive > 0 && numNegative === 0)
250757
+ return 1;
250758
+ if (numNegative > 0 && numPositive === 0)
250759
+ return -1;
250760
+ // problem case: if all edges have zero dihedral angle, record it as convex.
250761
+ if (numPlanar > 0 && numPositive === 0 && numNegative === 0)
250762
+ return 1;
250763
+ return 0;
250764
+ }
250534
250765
  /**
250535
250766
  * Test if the facets in `source` occur in perfectly mated pairs, as is required for a closed manifold volume.
250536
250767
  */
@@ -302349,7 +302580,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
302349
302580
  /***/ ((module) => {
302350
302581
 
302351
302582
  "use strict";
302352
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"3.6.0-dev.14","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^3.6.0-dev.14","@itwin/core-bentley":"workspace:^3.6.0-dev.14","@itwin/core-common":"workspace:^3.6.0-dev.14","@itwin/core-geometry":"workspace:^3.6.0-dev.14","@itwin/core-orbitgt":"workspace:^3.6.0-dev.14","@itwin/core-quantity":"workspace:^3.6.0-dev.14","@itwin/webgl-compatibility":"workspace:^3.6.0-dev.14"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
302583
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"3.6.0-dev.22","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^3.6.0-dev.22","@itwin/core-bentley":"workspace:^3.6.0-dev.22","@itwin/core-common":"workspace:^3.6.0-dev.22","@itwin/core-geometry":"workspace:^3.6.0-dev.22","@itwin/core-orbitgt":"workspace:^3.6.0-dev.22","@itwin/core-quantity":"workspace:^3.6.0-dev.22","@itwin/webgl-compatibility":"workspace:^3.6.0-dev.22"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/lodash":"^4.14.0","@types/mocha":"^8.2.2","@types/node":"18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"~1.4.0","@itwin/cloud-agnostic-core":"~1.4.0","@itwin/object-storage-core":"~1.4.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","lodash":"^4.17.10","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
302353
302584
 
302354
302585
  /***/ })
302355
302586