@xeokit/xeokit-sdk 2.6.30 → 2.6.31
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 +127 -41
- package/dist/xeokit-sdk.es.js +127 -41
- package/dist/xeokit-sdk.es5.js +15 -14
- package/dist/xeokit-sdk.min.cjs.js +4 -4
- package/dist/xeokit-sdk.min.es.js +5 -5
- package/dist/xeokit-sdk.min.es5.js +2 -2
- package/package.json +1 -1
- package/src/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.js +110 -33
- package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +7 -2
- package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +1 -1
- package/src/viewer/scene/webgl/Renderer.js +6 -3
- package/types/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.d.ts +5 -3
- package/types/plugins/LASLoaderPlugin/LASLoaderPlugin.d.ts +2 -2
- package/types/plugins/OBJLoaderPlugin/OBJLoaderPlugin.d.ts +3 -3
package/package.json
CHANGED
|
@@ -426,50 +426,127 @@ export class DotBIMLoaderPlugin extends Plugin {
|
|
|
426
426
|
|
|
427
427
|
const dbMeshId = element.mesh_id;
|
|
428
428
|
|
|
429
|
-
parseDBMesh(dbMeshId);
|
|
430
|
-
|
|
431
|
-
const meshId = `${objectId}-mesh`;
|
|
432
429
|
const vector = element.vector;
|
|
433
430
|
const rotation = element.rotation;
|
|
434
431
|
const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
|
|
435
|
-
|
|
436
432
|
let visible = true;
|
|
437
433
|
let pickable = true;
|
|
438
|
-
let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
|
|
439
|
-
let opacity = element.color ? element.color.a / 255 : 1.0;
|
|
440
434
|
|
|
441
|
-
if (
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
435
|
+
if (element.face_colors === undefined) {
|
|
436
|
+
|
|
437
|
+
parseDBMesh(dbMeshId);
|
|
438
|
+
|
|
439
|
+
const meshId = `${objectId}-mesh`;
|
|
440
|
+
|
|
441
|
+
let color = element.color ? [element.color.r / 255.0, element.color.g / 255.0, element.color.b / 255.0] : [1, 1, 1];
|
|
442
|
+
let opacity = element.color ? element.color.a / 255.0 : 1.0;
|
|
443
|
+
|
|
444
|
+
if (props) {
|
|
445
|
+
if (props.visible === false) {
|
|
446
|
+
visible = false;
|
|
447
|
+
}
|
|
448
|
+
if (props.pickable === false) {
|
|
449
|
+
pickable = false;
|
|
450
|
+
}
|
|
451
|
+
if (props.colorize) {
|
|
452
|
+
color = props.colorize;
|
|
453
|
+
}
|
|
454
|
+
if (props.opacity !== undefined && props.opacity !== null) {
|
|
455
|
+
opacity = props.opacity;
|
|
456
|
+
}
|
|
447
457
|
}
|
|
448
|
-
|
|
449
|
-
|
|
458
|
+
|
|
459
|
+
sceneModel.createMesh({
|
|
460
|
+
id: meshId,
|
|
461
|
+
geometryId: dbMeshId,
|
|
462
|
+
color: color,
|
|
463
|
+
opacity: opacity,
|
|
464
|
+
quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
|
|
465
|
+
position: vector ? [vector.x, vector.y, vector.z] : undefined
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
sceneModel.createEntity({
|
|
469
|
+
id: objectId,
|
|
470
|
+
meshIds: [meshId],
|
|
471
|
+
visible: visible,
|
|
472
|
+
pickable: pickable,
|
|
473
|
+
isObject: true
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
let faceColors = element.face_colors;
|
|
478
|
+
let coloredTrianglesDictionary = {};
|
|
479
|
+
let currentTriangleIndicesCount = 0;
|
|
480
|
+
let dbMesh = fileData.meshes[element.mesh_id];
|
|
481
|
+
for (let i = 0, len = faceColors.length; i < len; i+=4) {
|
|
482
|
+
let faceColor = [faceColors[i], faceColors[i+1], faceColors[i+2], faceColors[i+3]];
|
|
483
|
+
if (coloredTrianglesDictionary[faceColor] === undefined) {
|
|
484
|
+
coloredTrianglesDictionary[faceColor] = [];
|
|
485
|
+
}
|
|
486
|
+
let indexForPoint0 = dbMesh.indices[currentTriangleIndicesCount];
|
|
487
|
+
let x0 = dbMesh.coordinates[indexForPoint0*3];
|
|
488
|
+
let y0 = dbMesh.coordinates[indexForPoint0*3+1];
|
|
489
|
+
let z0 = dbMesh.coordinates[indexForPoint0*3+2];
|
|
490
|
+
let indexForPoint1 = dbMesh.indices[currentTriangleIndicesCount+1];
|
|
491
|
+
let x1 = dbMesh.coordinates[indexForPoint1*3];
|
|
492
|
+
let y1 = dbMesh.coordinates[indexForPoint1*3+1];
|
|
493
|
+
let z1 = dbMesh.coordinates[indexForPoint1*3+2];
|
|
494
|
+
let indexForPoint2 = dbMesh.indices[currentTriangleIndicesCount+2];
|
|
495
|
+
let x2 = dbMesh.coordinates[indexForPoint2*3];
|
|
496
|
+
let y2 = dbMesh.coordinates[indexForPoint2*3+1];
|
|
497
|
+
let z2 = dbMesh.coordinates[indexForPoint2*3+2];
|
|
498
|
+
coloredTrianglesDictionary[faceColor].push(x0, y0, z0, x1, y1, z1, x2, y2, z2);
|
|
499
|
+
|
|
500
|
+
currentTriangleIndicesCount += 3;
|
|
450
501
|
}
|
|
451
|
-
|
|
452
|
-
|
|
502
|
+
let meshIds = [];
|
|
503
|
+
for (const [faceColor, trianglesCoordinates] of Object.entries(coloredTrianglesDictionary)) {
|
|
504
|
+
sceneModel.createGeometry({
|
|
505
|
+
id: `${dbMeshId}-${faceColor}`,
|
|
506
|
+
primitive: "triangles",
|
|
507
|
+
positions: trianglesCoordinates,
|
|
508
|
+
indices: [...Array(trianglesCoordinates.length).keys()]
|
|
509
|
+
});
|
|
510
|
+
const meshId = `${objectId}-mesh-${faceColor}`;
|
|
511
|
+
const faceColorArray = faceColor.split(',').map(Number);
|
|
512
|
+
|
|
513
|
+
let color = [faceColorArray[0] / 255.0, faceColorArray[1] / 255.0, faceColorArray[2] / 255.0];
|
|
514
|
+
let opacity = faceColorArray[3] / 255.0;
|
|
515
|
+
|
|
516
|
+
if (props) {
|
|
517
|
+
if (props.visible === false) {
|
|
518
|
+
visible = false;
|
|
519
|
+
}
|
|
520
|
+
if (props.pickable === false) {
|
|
521
|
+
pickable = false;
|
|
522
|
+
}
|
|
523
|
+
if (props.colorize) {
|
|
524
|
+
color = props.colorize;
|
|
525
|
+
}
|
|
526
|
+
if (props.opacity !== undefined && props.opacity !== null) {
|
|
527
|
+
opacity = props.opacity;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
sceneModel.createMesh({
|
|
532
|
+
id: meshId,
|
|
533
|
+
geometryId: `${dbMeshId}-${faceColor}`,
|
|
534
|
+
color: color,
|
|
535
|
+
opacity: opacity,
|
|
536
|
+
quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
|
|
537
|
+
position: vector ? [vector.x, vector.y, vector.z] : undefined
|
|
538
|
+
});
|
|
539
|
+
meshIds.push(meshId);
|
|
453
540
|
}
|
|
541
|
+
sceneModel.createEntity({
|
|
542
|
+
id: objectId,
|
|
543
|
+
meshIds: meshIds,
|
|
544
|
+
visible: visible,
|
|
545
|
+
pickable: pickable,
|
|
546
|
+
isObject: true
|
|
547
|
+
});
|
|
454
548
|
}
|
|
455
549
|
|
|
456
|
-
sceneModel.createMesh({
|
|
457
|
-
id: meshId,
|
|
458
|
-
geometryId: dbMeshId,
|
|
459
|
-
color,
|
|
460
|
-
opacity,
|
|
461
|
-
quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
|
|
462
|
-
position: vector ? [vector.x, vector.y, vector.z] : undefined
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
sceneModel.createEntity({
|
|
466
|
-
id: objectId,
|
|
467
|
-
meshIds: [meshId],
|
|
468
|
-
visible,
|
|
469
|
-
pickable,
|
|
470
|
-
isObject: true
|
|
471
|
-
});
|
|
472
|
-
|
|
473
550
|
for (let infoKey in info) {
|
|
474
551
|
let properties;
|
|
475
552
|
if (infoKey.startsWith("IFC_Pset_")) {
|
|
@@ -5,6 +5,7 @@ import {sRGBEncoding} from "../../viewer/scene/constants/constants.js";
|
|
|
5
5
|
import {worldToRTCPositions} from "../../viewer/scene/math/rtcCoords.js";
|
|
6
6
|
import {parse} from '@loaders.gl/core';
|
|
7
7
|
import {GLTFLoader} from '@loaders.gl/gltf/dist/esm/gltf-loader.js';
|
|
8
|
+
|
|
8
9
|
import {
|
|
9
10
|
ClampToEdgeWrapping,
|
|
10
11
|
LinearFilter,
|
|
@@ -503,7 +504,7 @@ const parseNodesWithNames = (function () {
|
|
|
503
504
|
|
|
504
505
|
const objectIdStack = [];
|
|
505
506
|
const meshIdsStack = [];
|
|
506
|
-
let meshIds =
|
|
507
|
+
let meshIds = [];
|
|
507
508
|
|
|
508
509
|
return function (ctx, node, depth, matrix) {
|
|
509
510
|
matrix = parseNodeMatrix(node, matrix);
|
|
@@ -681,7 +682,11 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
|
|
|
681
682
|
if (primitive.indices) {
|
|
682
683
|
meshCfg.indices = primitive.indices.value;
|
|
683
684
|
}
|
|
684
|
-
|
|
685
|
+
if (matrix) {
|
|
686
|
+
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
|
|
687
|
+
} else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
|
|
688
|
+
meshCfg.positions.set(meshCfg.localPositions);
|
|
689
|
+
}
|
|
685
690
|
const origin = math.vec3();
|
|
686
691
|
const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
|
|
687
692
|
if (rtcNeeded) {
|
|
@@ -990,7 +990,7 @@ export class TreeViewPlugin extends Plugin {
|
|
|
990
990
|
this._nodeNodes[buildingNode.nodeId] = buildingNode;
|
|
991
991
|
} else if (metaObjectType === "IfcBuildingStorey") {
|
|
992
992
|
if (!buildingNode) {
|
|
993
|
-
this.error("Failed to build storeys hierarchy for model
|
|
993
|
+
this.error("Failed to build storeys hierarchy for model - model does not have an IfcBuilding object, or is not an IFC model");
|
|
994
994
|
return;
|
|
995
995
|
}
|
|
996
996
|
storeyNode = {
|
|
@@ -1539,13 +1539,16 @@ const Renderer = function (scene, options) {
|
|
|
1539
1539
|
}
|
|
1540
1540
|
|
|
1541
1541
|
const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
|
|
1542
|
+
if (!snappedEntity && pickable) {
|
|
1543
|
+
pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
|
|
1544
|
+
}
|
|
1542
1545
|
|
|
1543
1546
|
pickResult.reset();
|
|
1544
1547
|
pickResult.snappedToEdge = (snapType === "edge");
|
|
1545
1548
|
pickResult.snappedToVertex = (snapType === "vertex");
|
|
1546
|
-
pickResult.worldPos = snappedWorldPos;
|
|
1547
|
-
pickResult.worldNormal = snappedWorldNormal;
|
|
1548
|
-
pickResult.entity = snappedEntity;
|
|
1549
|
+
pickResult.worldPos = snappedWorldPos || worldPos;
|
|
1550
|
+
pickResult.worldNormal = snappedWorldNormal || worldNormal;
|
|
1551
|
+
pickResult.entity = snappedEntity || pickable;
|
|
1549
1552
|
pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
|
|
1550
1553
|
pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
|
|
1551
1554
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Entity, IFCObjectDefaults, Plugin, SceneModel, Viewer } from "../../viewer";
|
|
2
2
|
|
|
3
3
|
export declare interface IGLTFDefaultDataSource {
|
|
4
4
|
/**
|
|
@@ -77,6 +77,8 @@ export declare type LoadGLTFModel = {
|
|
|
77
77
|
edgeThreshold?: number[]
|
|
78
78
|
/** Set ````false```` to load all the materials and textures provided by the glTF file, otherwise leave ````true```` to load the default high-performance representation optimized for low memory usage and efficient rendering. */
|
|
79
79
|
performance?: boolean;
|
|
80
|
+
/** When true, generate a single MetaObject that represents the entire glTF model, and a MetaObject for each entity within it. */
|
|
81
|
+
autoMetaModel?: boolean;
|
|
80
82
|
};
|
|
81
83
|
|
|
82
84
|
/**
|
|
@@ -134,7 +136,7 @@ export declare class GLTFLoaderPlugin extends Plugin {
|
|
|
134
136
|
* Loads a glTF model from a file into this GLTFLoaderPlugin's {@link Viewer}.
|
|
135
137
|
*
|
|
136
138
|
* @param {LoadGLTFModel} params Loading parameters.
|
|
137
|
-
* @returns {
|
|
139
|
+
* @returns {SceneModel} SceneModel representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}.
|
|
138
140
|
*/
|
|
139
|
-
load(params: LoadGLTFModel):
|
|
141
|
+
load(params: LoadGLTFModel): SceneModel;
|
|
140
142
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Entity, Plugin, Viewer } from "../../viewer";
|
|
1
|
+
import { Entity, Plugin, SceneModel, Viewer } from "../../viewer";
|
|
2
2
|
import { ModelStats } from "../index";
|
|
3
3
|
|
|
4
4
|
export declare interface ILASDefaultDataSource {
|
|
@@ -142,5 +142,5 @@ export declare class LASLoaderPlugin extends Plugin {
|
|
|
142
142
|
* @param {LoadLASModel} params Loading parameters.
|
|
143
143
|
* @returns {SceneModel} SceneModel representing the model, which will have {@link Entity.isModel} set ````true```` and will be registered by {@link Entity.id} in {@link Scene.models}.
|
|
144
144
|
*/
|
|
145
|
-
load(params?: LoadLASModel):
|
|
145
|
+
load(params?: LoadLASModel): SceneModel;
|
|
146
146
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Plugin, Viewer
|
|
1
|
+
import { Entity, Node, Plugin, Viewer } from "../../viewer";
|
|
2
2
|
|
|
3
3
|
export declare type LoadOBJModel = {
|
|
4
4
|
/** ID to assign to the model's root {@link Entity}, unique among all components in the Viewer's {@link Scene}. */
|
|
@@ -38,7 +38,7 @@ export declare class OBJLoaderPlugin extends Plugin {
|
|
|
38
38
|
* Loads an OBJ model from a file into this OBJLoader's {@link Viewer}.
|
|
39
39
|
*
|
|
40
40
|
* @param {LoadOBJModel} params Loading parameters.
|
|
41
|
-
* @returns {
|
|
41
|
+
* @returns {Node} An {@link Entity} that is a scene graph node that can have child Nodes and {@link Mesh}es.
|
|
42
42
|
*/
|
|
43
|
-
load(params: LoadOBJModel):
|
|
43
|
+
load(params: LoadOBJModel): Node;
|
|
44
44
|
}
|