@xeokit/xeokit-sdk 2.6.103 → 2.6.105-XCD-439-transparent-issues

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.103",
3
+ "version": "2.6.105-XCD-439-transparent-issues",
4
4
  "description": "3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -8,7 +8,7 @@
8
8
  "scripts": {
9
9
  "build": "rollup --config rollup.config.js; rollup --config rollup.minified.config.js",
10
10
  "dev-build": "rollup --config rollup.dev.config.js",
11
- "docs": "rm -Rf ./docs/*; ./node_modules/.bin/esdoc",
11
+ "docs": "rm -Rf ./docs/*; ./node_modules/.bin/esdoc && node docs/.scripts/fix-doc-links.mjs",
12
12
  "typedocs": "rm -Rf ./docs/*; typedoc --tsconfig tsconfig.json",
13
13
  "changelog": "git fetch; auto-changelog --commit-limit false --package --template changelog-template.hbs",
14
14
  "test": "npx percy exec -- npx playwright test"
@@ -68,10 +68,11 @@
68
68
  "@types/node": "^22.10.6",
69
69
  "auto-changelog": "^2.4.0",
70
70
  "dotenv": "^16.4.7",
71
- "esdoc": "^1.1.0",
72
- "esdoc-custom-theme": "^1.4.2",
73
- "esdoc-publish-html-plugin": "^1.1.2",
74
- "esdoc-standard-plugin": "^1.0.0",
71
+ "esdoc": "1.1.0",
72
+ "esdoc-custom-theme": "1.4.2",
73
+ "esdoc-ecmascript-proposal-plugin": "1.0.0",
74
+ "esdoc-publish-html-plugin": "1.1.2",
75
+ "esdoc-standard-plugin": "1.0.0",
75
76
  "eslint": "^8.13.0",
76
77
  "parse5": "^7.0.0",
77
78
  "rollup": "^2.70.2",
@@ -322,6 +322,7 @@ class GLTFLoaderPlugin extends Plugin {
322
322
  * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.
323
323
  * @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.
324
324
  * @param {*} [params.parseOptions={}] Options to pass to loaders.gl parse method, eg. ````{ gltf: { excludeExtensions: { "KHR_texture_transform": false } } }````.
325
+ * @param {Boolean} [params.entityPerMesh=false] Create an entity for each mesh, instead of grouping leaf meshes under their common entity.
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 = {}) {
@@ -125,6 +125,7 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok, er
125
125
  numObjects: 0,
126
126
  nodes: [],
127
127
  nextId: 0,
128
+ entityPerMesh: options.entityPerMesh,
128
129
  log: (msg) => {
129
130
  plugin.log(msg);
130
131
  }
@@ -419,6 +420,49 @@ function loadDefaultScene(ctx) {
419
420
  });
420
421
  })(nodes);
421
422
 
423
+ if (ctx.entityPerMesh) {
424
+ const sceneIds = new Set();
425
+ (function createSceneMeshesAndEntities(nodes, parentId, parentMatrix, dep) {
426
+ return nodes.reduce(
427
+ (hadMesh, node) => {
428
+ const baseId = node.name ?? "Node";
429
+ const maybeGlobalize = id => ctx.globalizeObjectIds ? math.globalizeObjectId(ctx.sceneModel.id, id) : id;
430
+ let entityId = maybeGlobalize(baseId);
431
+ let nextPostfixId = 1;
432
+ while (ctx.sceneModel.objects[entityId] || sceneIds.has(entityId)) {
433
+ entityId = maybeGlobalize(`${baseId}.${(nextPostfixId++).toString().padStart(4, "0")}`);
434
+ }
435
+ sceneIds.add(entityId);
436
+ const matrix = parseNodeMatrix(node, parentMatrix);
437
+
438
+ const meshEntity = node.mesh && (function() {
439
+ const meshIds = [ ];
440
+ parseNodeMesh(node, ctx, matrix, meshIds);
441
+ return (meshIds.length > 0) && ctx.sceneModel.createEntity({
442
+ id: entityId,
443
+ meshIds: meshIds,
444
+ isObject: true
445
+ });
446
+ })();
447
+
448
+ const hasMesh = (node.children && createSceneMeshesAndEntities(node.children, entityId, matrix, dep + 1)) || meshEntity;
449
+
450
+ if (hasMesh && ctx.autoMetaModel) {
451
+ ctx.metaObjects.push({
452
+ id: entityId,
453
+ name: entityId,
454
+ type: "Default",
455
+ parent: parentId
456
+ });
457
+ }
458
+
459
+ return hadMesh || hasMesh;
460
+ },
461
+ false);
462
+ })(nodes, ctx.sceneModel.id, null, 0);
463
+ return;
464
+ }
465
+
422
466
  // Create a SceneMesh for each mesh primitive, and a SceneModelEntity for the root node and each named node.
423
467
  const meshIdsStack = [];
424
468
  let meshIds = null;
@@ -460,7 +504,7 @@ function loadDefaultScene(ctx) {
460
504
  ctx.metaObjects.push({
461
505
  id: entityId,
462
506
  type: "Default",
463
- name: entityId,
507
+ name: nodeName ? nodeName : "Node",
464
508
  parent: ctx.sceneModel.id
465
509
  });
466
510
  }
@@ -532,9 +576,6 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
532
576
  if (numPrimitives > 0) {
533
577
  for (let i = 0; i < numPrimitives; i++) {
534
578
  const primitive = mesh.primitives[i];
535
- if (primitive.mode < 4) {
536
- continue;
537
- }
538
579
  const meshCfg = {
539
580
  id: ctx.sceneModel.id + "." + ctx.numObjects++
540
581
  };
@@ -65,6 +65,7 @@ class Viewer {
65
65
  * configures renderer logic for the specified number of SectionPlanes, eliminating the need for setting up logic with each SectionPlane creation and thereby enhancing
66
66
  * responsiveness. It is important to consider that each SectionPlane impacts rendering performance, so it is recommended to set this value to a quantity that aligns with
67
67
  * your expected usage.
68
+ * @param {Boolean} [cfg.sortAllTransparent=false] Whether to sort all transparent objects by their distance from the camera, before drawing on the scene.
68
69
  */
69
70
  constructor(cfg) {
70
71
 
@@ -124,7 +125,8 @@ class Viewer {
124
125
  colorTextureEnabled: (cfg.colorTextureEnabled !== false),
125
126
  dtxEnabled: (!!cfg.dtxEnabled),
126
127
  markerZOffset: cfg.markerZOffset,
127
- numCachedSectionPlanes: cfg.numCachedSectionPlanes
128
+ numCachedSectionPlanes: cfg.numCachedSectionPlanes,
129
+ sortAllTransparent: cfg.sortAllTransparent
128
130
  });
129
131
 
130
132
  /**
@@ -633,7 +633,8 @@ class Scene extends Component {
633
633
 
634
634
  this._renderer = new Renderer(this, {
635
635
  transparent: transparent,
636
- alphaDepthMask: alphaDepthMask
636
+ alphaDepthMask: alphaDepthMask,
637
+ sortAllTransparent: cfg.sortAllTransparent
637
638
  });
638
639
 
639
640
  this._sectionPlanesState = new (function () {
@@ -18,6 +18,7 @@ const vec3_0 = math.vec3([0,0,0]);
18
18
  const iota = (n) => { const ret = [ ]; for (let i = 0; i < n; ++i) ret.push(i); return ret; };
19
19
 
20
20
  const tempPlanes = iota(6).map(() => math.vec4());
21
+ const tempVec3 = math.vec3();
21
22
  const tempVec4 = math.vec4();
22
23
 
23
24
  const bitShiftScreenZ = math.vec4([1.0 / (256.0 * 256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0]);
@@ -1021,6 +1022,40 @@ const Renderer = function (scene, options) {
1021
1022
  if (normalFillTransparentBinLen > 0 || normalEdgesTransparentBinLen > 0) {
1022
1023
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
1023
1024
  }
1025
+
1026
+ if (options.sortAllTransparent) {
1027
+ const eye = frameCtx.viewParams.eye;
1028
+ normalFillTransparentBin.length = normalFillTransparentBinLen; // normalFillTransparentBin reused by renderDrawables calls, so needs to be truncated if necessary
1029
+
1030
+ const transparentDrawables = [ ];
1031
+ const appendTransparentDrawable = (d, draw) => {
1032
+ math.getAABB3Center(d.aabb, tempVec3);
1033
+ transparentDrawables.push({ draw: draw, distSq: math.distVec3(eye, math.getAABB3Center(d.aabb, tempVec3)) });
1034
+ };
1035
+ iota(normalEdgesTransparentBinLen).forEach(i => {
1036
+ const d = normalEdgesTransparentBin[i];
1037
+ appendTransparentDrawable(d, () => d.drawEdgesColorTransparent(frameCtx));
1038
+ });
1039
+
1040
+ iota(normalFillTransparentBinLen).forEach(i => {
1041
+ const d = normalFillTransparentBin[i];
1042
+ appendTransparentDrawable(d, () => d.drawColorTransparent(frameCtx));
1043
+ });
1044
+
1045
+ iota(xrayEdgesTransparentBinLen).forEach(i => {
1046
+ const d = xrayEdgesTransparentBin[i];
1047
+ appendTransparentDrawable(d, () => d.drawEdgesXRayed(frameCtx));
1048
+ });
1049
+
1050
+ iota(xrayedFillTransparentBinLen).forEach(i => {
1051
+ const d = xrayedFillTransparentBin[i];
1052
+ appendTransparentDrawable(d, () => d.drawSilhouetteXRayed(frameCtx));
1053
+ });
1054
+
1055
+ transparentDrawables.sort((a, b) => b.distSq - a.distSq).forEach(d => d.draw());
1056
+
1057
+ } else {
1058
+
1024
1059
  if (normalEdgesTransparentBinLen > 0) {
1025
1060
  for (i = 0; i < normalEdgesTransparentBinLen; i++) {
1026
1061
  drawable = normalEdgesTransparentBin[i];
@@ -1055,6 +1090,7 @@ const Renderer = function (scene, options) {
1055
1090
  xrayedFillTransparentBin[i].drawSilhouetteXRayed(frameCtx);
1056
1091
  }
1057
1092
  }
1093
+ }
1058
1094
 
1059
1095
  gl.disable(gl.BLEND);
1060
1096
  if (!alphaDepthMask) {
@@ -85,6 +85,8 @@ export declare type LoadGLTFModel = {
85
85
  autoMetaModel?: boolean;
86
86
  /** Options to pass to loaders.gl parse method, eg. ````{ gltf: { excludeExtensions: { "KHR_texture_transform": false } } }````. */
87
87
  parseOptions?: any;
88
+ /** Create an entity for each mesh, instead of grouping leaf meshes under their common entity. */
89
+ entityPerMesh?: boolean;
88
90
  };
89
91
 
90
92
  /**
@@ -67,6 +67,8 @@ export declare type ViewerConfiguration = {
67
67
  markerZOffset?: number;
68
68
  /** Enhances the efficiency of SectionPlane creation by proactively allocating Viewer resources for a specified quantity of SectionPlanes.*/
69
69
  numCachedSectionPlanes?: number;
70
+ /** Whether to sort all transparent objects by their distance from the camera, before drawing on the scene. */
71
+ sortAllTransparent?: boolean;
70
72
  };
71
73
 
72
74
  /**