@xeokit/xeokit-sdk 2.6.43 → 2.6.45

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.
Files changed (35) hide show
  1. package/dist/xeokit-sdk.cjs.js +248 -56
  2. package/dist/xeokit-sdk.es.js +248 -56
  3. package/dist/xeokit-sdk.es5.js +117 -49
  4. package/dist/xeokit-sdk.min.cjs.js +5 -5
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +4 -4
  7. package/package.json +1 -1
  8. package/src/extras/ContextMenu/ContextMenu.js +24 -0
  9. package/src/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.js +2 -1
  10. package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +1 -0
  11. package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +5 -3
  12. package/src/plugins/LASLoaderPlugin/LASLoaderPlugin.js +156 -2
  13. package/src/plugins/TreeViewPlugin/RenderService.js +3 -0
  14. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +12 -12
  15. package/src/viewer/Viewer.js +5 -1
  16. package/src/viewer/scene/input/Input.js +5 -9
  17. package/src/viewer/scene/math/rtcCoords.js +5 -1
  18. package/src/viewer/scene/model/SceneModel.js +3 -1
  19. package/src/viewer/scene/model/SceneModelMesh.js +10 -9
  20. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +1 -1
  21. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +1 -1
  22. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +1 -1
  23. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +1 -1
  24. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +1 -1
  25. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +1 -1
  26. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +1 -1
  27. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +1 -1
  28. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +1 -1
  29. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +1 -1
  30. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +2 -1
  31. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +1 -1
  32. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +1 -1
  33. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +1 -1
  34. package/src/viewer/scene/model/vbo/VBORenderer.js +1 -1
  35. package/types/plugins/LASLoaderPlugin/LASLoaderPlugin.d.ts +95 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.43",
3
+ "version": "2.6.45",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -461,6 +461,7 @@ class ContextMenu {
461
461
  this._updateItemsTitles();
462
462
  this._updateItemsEnabledStatus();
463
463
  this._showMenu(this._rootMenu.id, pageX, pageY);
464
+ this._updateSubMenuInfo();
464
465
  this._shown = true;
465
466
  this.fire("shown", {});
466
467
  }
@@ -869,6 +870,29 @@ class ContextMenu {
869
870
  }
870
871
  }
871
872
 
873
+ _updateSubMenuInfo() {
874
+ if (!this._context) return;
875
+ let itemElement, itemRect, subMenuElement, initialStyles, showOnLeft, subMenuWidth;
876
+ this._itemList.forEach((item) => {
877
+ if (item.subMenu) {
878
+ itemElement = item.itemElement;
879
+ itemRect = itemElement.getBoundingClientRect();
880
+ subMenuElement = item.subMenu.menuElement;
881
+ initialStyles = {
882
+ visibility: subMenuElement.style.visibility,
883
+ display: subMenuElement.style.display,
884
+ }
885
+ subMenuElement.style.display = "block";
886
+ subMenuElement.style.visibility = "hidden";
887
+ subMenuWidth = item.subMenu.menuElement.getBoundingClientRect().width;
888
+ subMenuElement.style.visibility = initialStyles.visibility;
889
+ subMenuElement.style.display = initialStyles.display;
890
+ showOnLeft = ((itemRect.right + subMenuWidth) > window.innerWidth);
891
+ itemElement.setAttribute("data-submenuposition", showOnLeft ? "left" : "right");
892
+ }
893
+ })
894
+ }
895
+
872
896
  _showMenu(menuId, pageX, pageY) { // Shows the given menu, at the specified page coordinates
873
897
  const menu = this._menuMap[menuId];
874
898
  if (!menu) {
@@ -554,7 +554,8 @@ export class DotBIMLoaderPlugin extends Plugin {
554
554
  }
555
555
  metaModelData.propertySets.push({
556
556
  id: objectId,
557
- properties
557
+ name: "Properties",
558
+ properties: properties
558
559
  });
559
560
 
560
561
  metaModelData.metaObjects.push({
@@ -322,6 +322,7 @@ class GLTFLoaderPlugin extends Plugin {
322
322
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
323
323
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
324
324
  * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.
325
+ * @param {Boolean} [params.globalizeObjectIds=false] Indicates whether to globalize each {@link Entity#id} and {@link MetaObject#id}, in case you need to prevent ID clashes with other models.
325
326
  * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
326
327
  */
327
328
  load(params = {}) {
@@ -109,6 +109,7 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
109
109
  entityId: options.entityId,
110
110
  metaModelJSON,
111
111
  autoMetaModel: options.autoMetaModel,
112
+ globalizeObjectIds: options.globalizeObjectIds,
112
113
  metaObjects: [],
113
114
  loadBuffer: options.loadBuffer,
114
115
  basePath: options.basePath,
@@ -444,16 +445,17 @@ function loadDefaultScene(ctx) {
444
445
 
445
446
  if (entityId) {
446
447
  if (meshIds.length > 0) {
448
+ const globalId = ctx.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, entityId) : entityId;
447
449
  ctx.sceneModel.createEntity({
448
- id: entityId,
450
+ id: globalId,
449
451
  meshIds: meshIds,
450
452
  isObject: true
451
453
  });
452
454
  if (ctx.autoMetaModel) {
453
455
  ctx.metaObjects.push({
454
- id: entityId,
456
+ id: globalId,
455
457
  type: "Default",
456
- name: entityId,
458
+ name: globalId,
457
459
  parent: ctx.sceneModel.id
458
460
  });
459
461
  }
@@ -212,6 +212,10 @@ class LASLoaderPlugin extends Plugin {
212
212
  * @param {Number} [cfg.skip=1] Configures LASLoaderPlugin to load every **n** points.
213
213
  * @param {Number} [cfg.fp64=false] Configures if LASLoaderPlugin assumes that LAS positions are stored in 64-bit floats instead of 32-bit.
214
214
  * @param {Number} [cfg.colorDepth=8] Configures whether LASLoaderPlugin assumes that LAS colors are encoded using 8 or 16 bits. Accepted values are 8, 16 an "auto".
215
+ * @param {Boolean} [cfg.center=false] Whether to center the LAS points. Applied before "rotateX", "rotate" and "transform".
216
+ * @param {Boolean} [cfg.rotateX=false] Whether to rotate the LAS point positions 90 degrees. Applied after "center".
217
+ * @param {Number[]} [cfg.rotate=[0,0,0]] Rotations to immediately apply to the LAS points, given as Euler angles in degrees, for each of the X, Y and Z axis. Rotation is applied after "center" and "rotateX".
218
+ * @param {Number[]} [cfg.transform] 4x4 transform matrix to immediately apply to the LAS points. This is applied after "center", "rotateX" and "rotate". Typically used instead of "rotateX" and "rotate".
215
219
  */
216
220
  constructor(viewer, cfg = {}) {
217
221
 
@@ -221,6 +225,10 @@ class LASLoaderPlugin extends Plugin {
221
225
  this.skip = cfg.skip;
222
226
  this.fp64 = cfg.fp64;
223
227
  this.colorDepth = cfg.colorDepth;
228
+ this.center = cfg.center;
229
+ this.rotate = cfg.rotate;
230
+ this.rotateX = cfg.rotateX;
231
+ this.transform = cfg.transform;
224
232
  }
225
233
 
226
234
  /**
@@ -315,6 +323,106 @@ class LASLoaderPlugin extends Plugin {
315
323
  this._colorDepth = value || "auto";
316
324
  }
317
325
 
326
+ /**
327
+ * Gets if LASLoaderPlugin immediately centers LAS positions.
328
+ *
329
+ * If this is ````true```` then centering is the first thing that happens to LAS positions as they are loaded.
330
+ *
331
+ * Default value is ````false````.
332
+ *
333
+ * @returns {Boolean} True if LASLoaderPlugin immediately centers LAS positions.
334
+ */
335
+ get center() {
336
+ return this._center;
337
+ }
338
+
339
+ /**
340
+ * Configures if LASLoaderPlugin immediately centers LAS positions.
341
+ *
342
+ * If this is ````true```` then centering is the first thing that happens to LAS positions as they are loaded.
343
+ *
344
+ * Default value is ````false````.
345
+ *
346
+ * @param {Boolean} value True if LASLoaderPlugin immediately centers LAS positions.
347
+ */
348
+ set center(value) {
349
+ this._center = !!value;
350
+ }
351
+
352
+ /**
353
+ * Gets the current transformation to apply to LAS positions as they are loaded.
354
+ *
355
+ * If this is ````true````, then LAS positions will be transformed after they are centered and rotated.
356
+ *
357
+ * Default value is null.
358
+ *
359
+ * @returns {Number[]|null} A 16-element array containing a 4x4 transformation matrix.
360
+ */
361
+ get transform() {
362
+ return this._transform;
363
+ }
364
+
365
+ /**
366
+ * Sets the current transformation to apply to LAS positions as they are loaded.
367
+ *
368
+ * If this is ````true````, then LAS positions will be transformed after they are centered and rotated.
369
+ *
370
+ * Default value is null.
371
+ *
372
+ * @param {Number[]|null} transform A 16-element array containing a 4x4 transformation matrix.
373
+ */
374
+ set transform(transform) {
375
+ this._transform = transform;
376
+ }
377
+
378
+ /**
379
+ * Gets the current rotations to apply to LAS positions as they are loaded.
380
+ *
381
+ * Rotations are an array of three Euler angles in degrees, for each of the X, Y and Z axis, applied in that order.
382
+ *
383
+ * Default value is null.
384
+ *
385
+ * @returns {Number[]|null} If defined, an array of three Euler angles in degrees, for each of the X, Y and Z axis. Null if undefined.
386
+ */
387
+ get rotate() {
388
+ return this._rotate;
389
+ }
390
+
391
+ /**
392
+ * Sets the current rotations to apply to LAS positions as they are loaded.
393
+ *
394
+ * Rotations are an array of three Euler angles in degrees, for each of the X, Y and Z axis, applied in that order.
395
+ *
396
+ * Default value is null.
397
+ *
398
+ * @param {Number[]|null} rotate Array of three Euler angles in degrees, for each of the X, Y and Z axis.
399
+ */
400
+ set rotate(rotate) {
401
+ this._rotate = rotate;
402
+ }
403
+
404
+ /**
405
+ * Gets if LAS positions are rotated 90 degrees about X as they are loaded.
406
+ *
407
+ * Default value is ````false````.
408
+ *
409
+ * @returns {*}
410
+ */
411
+ get rotateX() {
412
+ return this._rotateX;
413
+ }
414
+
415
+ /**
416
+ * Sets if LAS positions are rotated 90 degrees about X as they are loaded.
417
+ *
418
+ * Default value is ````false````.
419
+ *
420
+ * @param rotateX
421
+ */
422
+ set rotateX(rotateX) {
423
+ this._rotateX = rotateX;
424
+ }
425
+
318
426
  /**
319
427
  * Loads an ````LAS```` model into this LASLoaderPlugin's {@link Viewer}.
320
428
  *
@@ -394,9 +502,26 @@ class LASLoaderPlugin extends Plugin {
394
502
 
395
503
  _parseModel(arrayBuffer, params, options, sceneModel) {
396
504
 
397
- function readPositions(attributesPosition) {
505
+ const readPositions = (attributesPosition) => {
398
506
  const positionsValue = attributesPosition.value;
399
- if (params.rotateX) {
507
+ if (this._center) {
508
+ const centerPos = math.vec3();
509
+ const numPoints = positionsValue.length;
510
+ for (let i = 0, len = positionsValue.length; i < len; i += 3) {
511
+ centerPos[0] += positionsValue[i + 0];
512
+ centerPos[1] += positionsValue[i + 1];
513
+ centerPos[2] += positionsValue[i + 2];
514
+ }
515
+ centerPos[0] /= numPoints;
516
+ centerPos[1] /= numPoints;
517
+ centerPos[2] /= numPoints;
518
+ for (let i = 0, len = positionsValue.length; i < len; i += 3) {
519
+ positionsValue[i + 0] -= centerPos[0];
520
+ positionsValue[i + 1] -= centerPos[1];
521
+ positionsValue[i + 2] -= centerPos[2];
522
+ }
523
+ }
524
+ if (this._rotateX) {
400
525
  if (positionsValue) {
401
526
  for (let i = 0, len = positionsValue.length; i < len; i += 3) {
402
527
  const temp = positionsValue[i + 1];
@@ -405,6 +530,35 @@ class LASLoaderPlugin extends Plugin {
405
530
  }
406
531
  }
407
532
  }
533
+ if (this._rotate) {
534
+ const quaternion = math.identityQuaternion();
535
+ const mat = math.mat4();
536
+ math.eulerToQuaternion(this._rotate, "XYZ", quaternion);
537
+ math.quaternionToRotationMat4(quaternion, mat);
538
+ const pos = math.vec3();
539
+ for (let i = 0, len = positionsValue.length; i < len; i += 3) {
540
+ pos[0] = positionsValue[i + 0];
541
+ pos[1] = positionsValue[i + 1];
542
+ pos[2] = positionsValue[i + 2];
543
+ math.transformPoint3(mat, pos, pos);
544
+ positionsValue[i + 0] = pos[0];
545
+ positionsValue[i + 1] = pos[1];
546
+ positionsValue[i + 2] = pos[2];
547
+ }
548
+ }
549
+ if (this._transform) {
550
+ const mat = math.mat4(this._transform);
551
+ const pos = math.vec3();
552
+ for (let i = 0, len = positionsValue.length; i < len; i += 3) {
553
+ pos[0] = positionsValue[i + 0];
554
+ pos[1] = positionsValue[i + 1];
555
+ pos[2] = positionsValue[i + 2];
556
+ math.transformPoint3(mat, pos, pos);
557
+ positionsValue[i + 0] = pos[0];
558
+ positionsValue[i + 1] = pos[1];
559
+ positionsValue[i + 2] = pos[2];
560
+ }
561
+ }
408
562
  return positionsValue;
409
563
  }
410
564
 
@@ -143,6 +143,9 @@ export class RenderService {
143
143
  }
144
144
  if (indeterminate !== checkbox.indeterminate) {
145
145
  checkbox.indeterminate = indeterminate;
146
+ if (indeterminate) {
147
+ checkbox.checked = false;
148
+ }
146
149
  }
147
150
  }
148
151
  }
@@ -996,9 +996,9 @@ class XKTLoaderPlugin extends Plugin {
996
996
  globalizeObjectIds: options.globalizeObjectIds
997
997
  });
998
998
  if (params.src) {
999
- this._loadModel(params.src, params, options, sceneModel, null, manifestCtx, finish, error);
999
+ this._loadModel(params.src, options, sceneModel, null, manifestCtx, finish, error);
1000
1000
  } else {
1001
- this._parseModel(params.xkt, params, options, sceneModel, null, manifestCtx);
1001
+ this._parseModel(params.xkt, options, sceneModel, null, manifestCtx);
1002
1002
  finish();
1003
1003
  }
1004
1004
  }, (errMsg) => {
@@ -1012,9 +1012,9 @@ class XKTLoaderPlugin extends Plugin {
1012
1012
  globalizeObjectIds: options.globalizeObjectIds
1013
1013
  });
1014
1014
  if (params.src) {
1015
- this._loadModel(params.src, params, options, sceneModel, null, manifestCtx, finish, error);
1015
+ this._loadModel(params.src, options, sceneModel, null, manifestCtx, finish, error);
1016
1016
  } else {
1017
- this._parseModel(params.xkt, params, options, sceneModel, null, manifestCtx);
1017
+ this._parseModel(params.xkt, options, sceneModel, null, manifestCtx);
1018
1018
  finish();
1019
1019
  }
1020
1020
  }
@@ -1023,9 +1023,9 @@ class XKTLoaderPlugin extends Plugin {
1023
1023
  } else {
1024
1024
 
1025
1025
  if (params.src) {
1026
- this._loadModel(params.src, params, options, sceneModel, metaModel, manifestCtx, finish, error);
1026
+ this._loadModel(params.src, options, sceneModel, metaModel, manifestCtx, finish, error);
1027
1027
  } else if (params.xkt) {
1028
- this._parseModel(params.xkt, params, options, sceneModel, metaModel, manifestCtx);
1028
+ this._parseModel(params.xkt, options, sceneModel, metaModel, manifestCtx);
1029
1029
  finish();
1030
1030
  } else if (params.manifestSrc || params.manifest) {
1031
1031
  const baseDir = params.manifestSrc ? getBaseDirectory(params.manifestSrc) : "";
@@ -1059,7 +1059,7 @@ class XKTLoaderPlugin extends Plugin {
1059
1059
  done();
1060
1060
  } else {
1061
1061
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
1062
- this._parseModel(arrayBuffer, params, options, sceneModel, null /* Ignore metamodel in XKT */, manifestCtx);
1062
+ this._parseModel(arrayBuffer, options, sceneModel, null /* Ignore metamodel in XKT */, manifestCtx);
1063
1063
  sceneModel.preFinalize();
1064
1064
  i++;
1065
1065
  this.scheduleTask(loadNext, 200);
@@ -1077,7 +1077,7 @@ class XKTLoaderPlugin extends Plugin {
1077
1077
  done();
1078
1078
  } else {
1079
1079
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
1080
- this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
1080
+ this._parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx);
1081
1081
  sceneModel.preFinalize();
1082
1082
  i++;
1083
1083
  this.scheduleTask(loadNext, 200);
@@ -1127,15 +1127,15 @@ class XKTLoaderPlugin extends Plugin {
1127
1127
  return sceneModel;
1128
1128
  }
1129
1129
 
1130
- _loadModel(src, params, options, sceneModel, metaModel, manifestCtx, done, error) {
1131
- this._dataSource.getXKT(params.src, (arrayBuffer) => {
1132
- this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
1130
+ _loadModel(src, options, sceneModel, metaModel, manifestCtx, done, error) {
1131
+ this._dataSource.getXKT(src, (arrayBuffer) => {
1132
+ this._parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx);
1133
1133
  sceneModel.preFinalize();
1134
1134
  done();
1135
1135
  }, error);
1136
1136
  }
1137
1137
 
1138
- async _parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx) {
1138
+ async _parseModel(arrayBuffer, options, sceneModel, metaModel, manifestCtx) {
1139
1139
  if (sceneModel.destroyed) {
1140
1140
  return;
1141
1141
  }
@@ -491,10 +491,14 @@ class Viewer {
491
491
 
492
492
  for (let i = 0, len = pluginContainerElements.length; i < len; i++) {
493
493
  const containerElement = pluginContainerElements[i];
494
+ //only calculate the scale for first plugin
495
+ //for all others keep the scale 1 otherwise it will keep multiplying the scale with the base scale of canvas
496
+ //resulting in increase/decreased size for the the canvas that is being overlapped
497
+ const scale = i == 0 ? snapshotCanvas.width / containerElement.clientWidth : 1;
494
498
  await html2canvas(containerElement, {
495
499
  canvas: snapshotCanvas,
496
500
  backgroundColor: null,
497
- scale: snapshotCanvas.width / containerElement.clientWidth
501
+ scale
498
502
  });
499
503
  }
500
504
  if (!params.includeGizmos) {
@@ -1300,15 +1300,11 @@ class Input extends Component {
1300
1300
  this.mouseCanvasPos[1] = event.y;
1301
1301
  } else {
1302
1302
  let element = event.target;
1303
- let totalOffsetLeft = 0;
1304
- let totalOffsetTop = 0;
1305
- while (element.offsetParent) {
1306
- totalOffsetLeft += element.offsetLeft;
1307
- totalOffsetTop += element.offsetTop;
1308
- element = element.offsetParent;
1309
- }
1310
- this.mouseCanvasPos[0] = event.pageX - totalOffsetLeft;
1311
- this.mouseCanvasPos[1] = event.pageY - totalOffsetTop;
1303
+
1304
+ const rect = element.getBoundingClientRect();
1305
+
1306
+ this.mouseCanvasPos[0] = event.clientX - rect.left;
1307
+ this.mouseCanvasPos[1] = event.clientY - rect.top;
1312
1308
  }
1313
1309
  }
1314
1310
 
@@ -1,6 +1,7 @@
1
1
  import {math} from './math.js';
2
2
 
3
3
  const tempVec3a = math.vec3();
4
+ const tempVec4 = math.vec4();
4
5
 
5
6
  /**
6
7
  * Given a view matrix and a relative-to-center (RTC) coordinate origin, returns a view matrix
@@ -129,7 +130,10 @@ function rtcToWorldPos(rtcCenter, rtcPos, worldPos) {
129
130
  * @param rtcPlanePos
130
131
  * @returns {*}
131
132
  */
132
- function getPlaneRTCPos(dist, dir, rtcCenter, rtcPlanePos) {
133
+ function getPlaneRTCPos(dist, dir, rtcOrigin, rtcPlanePos, rotationMatrixConjugate) {
134
+ const rtcCenter = (rotationMatrixConjugate
135
+ ? (tempVec4.set(rtcOrigin, 0), tempVec4[3] = 1, math.mulMat4v4(rotationMatrixConjugate, tempVec4, tempVec4))
136
+ : rtcOrigin);
133
137
  const rtcCenterToPlaneDist = math.dotVec3(dir, rtcCenter) + dist;
134
138
  const dirNormalized = math.normalizeVec3(dir, tempVec3a);
135
139
  math.mulVec3Scalar(dirNormalized, -rtcCenterToPlaneDist, rtcPlanePos);
@@ -3129,6 +3129,7 @@ export class SceneModel extends Component {
3129
3129
  cfg.meshMatrix = cfg.transform.worldMatrix;
3130
3130
  }
3131
3131
  mesh.portionId = mesh.layer.createPortion(mesh, cfg);
3132
+ mesh.numPrimitives = cfg.numPrimitives;
3132
3133
  this._meshes[cfg.id] = mesh;
3133
3134
  this._unusedMeshes[cfg.id] = mesh;
3134
3135
  this._meshList.push(mesh);
@@ -3492,7 +3493,7 @@ export class SceneModel extends Component {
3492
3493
  flags = flags | ENTITY_FLAGS.SELECTED;
3493
3494
  }
3494
3495
  cfg.flags = flags;
3495
- this._createEntity(cfg);
3496
+ return this._createEntity(cfg);
3496
3497
  }
3497
3498
 
3498
3499
  _createEntity(cfg) {
@@ -3523,6 +3524,7 @@ export class SceneModel extends Component {
3523
3524
  this._entities[cfg.id] = entity;
3524
3525
  this._entitiesToFinalize.push(entity);
3525
3526
  this.numEntities++;
3527
+ return entity;
3526
3528
  }
3527
3529
 
3528
3530
  /**
@@ -375,6 +375,16 @@ export class SceneModelMesh {
375
375
  */
376
376
  set aabb(aabb) { // Called by SceneModel
377
377
  this._aabbLocal = aabb;
378
+ if (this.origin) {
379
+ this._aabbLocal = aabb.slice(0);
380
+ const origin = this.origin;
381
+ this._aabbLocal[0] += origin[0];
382
+ this._aabbLocal[1] += origin[1];
383
+ this._aabbLocal[2] += origin[2];
384
+ this._aabbLocal[3] += origin[0];
385
+ this._aabbLocal[4] += origin[1];
386
+ this._aabbLocal[5] += origin[2];
387
+ }
378
388
  }
379
389
 
380
390
  /**
@@ -391,15 +401,6 @@ export class SceneModelMesh {
391
401
  math.transformOBB3(this.model.worldMatrix, tempOBB3, tempOBB3b);
392
402
  math.OBB3ToAABB3(tempOBB3b, this._aabbWorld);
393
403
  }
394
- if (this.origin) {
395
- const origin = this.origin;
396
- this._aabbWorld[0] += origin[0];
397
- this._aabbWorld[1] += origin[1];
398
- this._aabbWorld[2] += origin[2];
399
- this._aabbWorld[3] += origin[0];
400
- this._aabbWorld[4] += origin[1];
401
- this._aabbWorld[5] += origin[2];
402
- }
403
404
  this._aabbWorldDirty = false;
404
405
  }
405
406
  return this._aabbWorld;
@@ -106,7 +106,7 @@ export class DTXLinesColorRenderer {
106
106
  if (active) {
107
107
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
108
108
  if (origin) {
109
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
109
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
110
110
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
111
111
  } else {
112
112
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -119,7 +119,7 @@ export class DTXTrianglesColorRenderer {
119
119
  if (active) {
120
120
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
121
121
  if (origin) {
122
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
122
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
123
123
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
124
124
  } else {
125
125
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -114,7 +114,7 @@ export class DTXTrianglesDepthRenderer {
114
114
  if (active) {
115
115
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
116
116
  if (origin) {
117
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
117
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
118
118
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
119
119
  } else {
120
120
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -100,7 +100,7 @@ export class DTXTrianglesEdgesColorRenderer {
100
100
  if (active) {
101
101
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
102
102
  if (origin) {
103
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
103
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
104
104
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
105
105
  } else {
106
106
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -127,7 +127,7 @@ export class DTXTrianglesEdgesRenderer {
127
127
  if (active) {
128
128
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
129
129
  if (origin) {
130
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
130
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
131
131
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
132
132
  } else {
133
133
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -106,7 +106,7 @@ export class DTXTrianglesNormalsRenderer {
106
106
  if (active) {
107
107
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
108
108
  if (origin) {
109
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
109
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
110
110
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
111
111
  } else {
112
112
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -121,7 +121,7 @@ export class DTXTrianglesOcclusionRenderer {
121
121
  if (active) {
122
122
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
123
123
  if (origin) {
124
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
124
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
125
125
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
126
126
  } else {
127
127
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -125,7 +125,7 @@ export class DTXTrianglesPickDepthRenderer {
125
125
  if (active) {
126
126
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
127
127
  if (origin) {
128
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
128
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
129
129
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
130
130
  } else {
131
131
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -112,7 +112,7 @@ export class DTXTrianglesPickMeshRenderer {
112
112
  if (active) {
113
113
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
114
114
  if (origin) {
115
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
115
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
116
116
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
117
117
  } else {
118
118
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -123,7 +123,7 @@ export class DTXTrianglesPickNormalsFlatRenderer {
123
123
  if (active) {
124
124
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
125
125
  if (origin) {
126
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
126
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
127
127
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
128
128
  } else {
129
129
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -32,6 +32,7 @@ export class DTXTrianglesPickNormalsRenderer {
32
32
  const state = dataTextureLayer._state;
33
33
  const textureState = state.textureState;
34
34
  const origin = dataTextureLayer._state.origin;
35
+ const {rotationMatrixConjugate} = model;
35
36
 
36
37
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
37
38
  const projMatrix = frameCtx.pickProjMatrix || camera.projMatrix;
@@ -93,7 +94,7 @@ export class DTXTrianglesPickNormalsRenderer {
93
94
  if (active) {
94
95
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
95
96
  if (origin) {
96
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
97
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
97
98
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
98
99
  } else {
99
100
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -138,7 +138,7 @@ export class DTXTrianglesSilhouetteRenderer {
138
138
  if (active) {
139
139
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
140
140
  if (origin) {
141
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
141
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
142
142
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
143
143
  } else {
144
144
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -132,7 +132,7 @@ export class DTXTrianglesSnapInitRenderer {
132
132
  if (active) {
133
133
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
134
134
  if (origin) {
135
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
135
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
136
136
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
137
137
  } else {
138
138
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);
@@ -137,7 +137,7 @@ export class DTXTrianglesSnapRenderer {
137
137
  if (active) {
138
138
  const sectionPlane = sectionPlanes[sectionPlaneIndex];
139
139
  if (origin) {
140
- const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a);
140
+ const rtcSectionPlanePos = getPlaneRTCPos(sectionPlane.dist, sectionPlane.dir, origin, tempVec3a, rotationMatrixConjugate);
141
141
  gl.uniform3fv(sectionPlaneUniforms.pos, rtcSectionPlanePos);
142
142
  } else {
143
143
  gl.uniform3fv(sectionPlaneUniforms.pos, sectionPlane.pos);