@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/dist/xeokit-sdk.cjs.js +102 -21
- package/dist/xeokit-sdk.es.js +102 -21
- package/dist/xeokit-sdk.es5.js +28 -25
- package/dist/xeokit-sdk.min.cjs.js +7 -7
- package/dist/xeokit-sdk.min.es.js +7 -7
- package/dist/xeokit-sdk.min.es5.js +6 -6
- package/package.json +7 -6
- package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +1 -0
- package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +45 -4
- package/src/viewer/Viewer.js +3 -1
- package/src/viewer/scene/scene/Scene.js +2 -1
- package/src/viewer/scene/webgl/Renderer.js +36 -0
- package/types/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.d.ts +2 -0
- package/types/viewer/Viewer.d.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xeokit/xeokit-sdk",
|
|
3
|
-
"version": "2.6.
|
|
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": "
|
|
72
|
-
"esdoc-custom-theme": "
|
|
73
|
-
"esdoc-
|
|
74
|
-
"esdoc-
|
|
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:
|
|
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
|
};
|
package/src/viewer/Viewer.js
CHANGED
|
@@ -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
|
/**
|
package/types/viewer/Viewer.d.ts
CHANGED
|
@@ -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
|
/**
|