@xeokit/xeokit-sdk 2.6.95 → 2.6.97
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 +1303 -179
- package/dist/xeokit-sdk.es.js +1302 -180
- package/dist/xeokit-sdk.es5.js +762 -438
- 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 +1 -1
- package/src/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellDefaultDataSource.js +74 -0
- package/src/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellLoaderPlugin.js +900 -0
- package/src/plugins/IFCOpenShellLoaderPlugin/index.js +2 -0
- package/src/plugins/index.js +1 -0
- package/src/viewer/scene/CameraControl/CameraControl.js +2 -2
- package/src/viewer/scene/math/math.js +171 -106
- package/src/viewer/scene/model/SceneModel.js +26 -23
- package/src/viewer/scene/model/SceneModelMesh.js +2 -0
- package/src/viewer/scene/model/compression.js +6 -6
- package/src/viewer/scene/model/layer/DTXLayer.js +5 -1
- package/src/viewer/scene/model/layer/Layer.js +11 -11
- package/src/viewer/scene/model/layer/VBOLayer.js +7 -3
- package/src/viewer/scene/sectionCaps/SectionCaps.js +5 -4
- package/src/viewer/scene/webgl/Renderer.js +79 -4
- package/types/plugins/IFCOpenShellLoaderPlugin/IFCOpenShellLoaderPlugin.d.ts +107 -0
- package/types/plugins/IFCOpenShellLoaderPlugin/index.d.ts +1 -0
- package/types/plugins/index.d.ts +1 -0
- package/types/viewer/scene/CameraControl/CameraControl.d.ts +5 -5
|
@@ -17,6 +17,9 @@ const vec3_0 = math.vec3([0,0,0]);
|
|
|
17
17
|
|
|
18
18
|
const iota = (n) => { const ret = [ ]; for (let i = 0; i < n; ++i) ret.push(i); return ret; };
|
|
19
19
|
|
|
20
|
+
const tempPlanes = iota(6).map(() => math.vec4());
|
|
21
|
+
const tempVec4 = math.vec4();
|
|
22
|
+
|
|
20
23
|
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]);
|
|
21
24
|
|
|
22
25
|
const pixelToInt = pix => pix[0] + (pix[1] << 8) + (pix[2] << 16) + (pix[3] << 24);
|
|
@@ -26,6 +29,66 @@ const toWorldPos = (p, origin, scale) => math.vec3([ p[0] * scale[0] + origin
|
|
|
26
29
|
p[1] * scale[1] + origin[1],
|
|
27
30
|
p[2] * scale[2] + origin[2] ]);
|
|
28
31
|
|
|
32
|
+
const makeFrustumAABBIntersectionTest = function(camera) {
|
|
33
|
+
const m = math.mat4();
|
|
34
|
+
math.mulMat4(camera.projMatrix, camera.viewMatrix, m);
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < 3; ++i) {
|
|
37
|
+
tempPlanes[i * 2 + 0][0] = m[ 3] + m[i];
|
|
38
|
+
tempPlanes[i * 2 + 0][1] = m[ 7] + m[i + 4];
|
|
39
|
+
tempPlanes[i * 2 + 0][2] = m[11] + m[i + 8];
|
|
40
|
+
tempPlanes[i * 2 + 0][3] = m[15] + m[i + 12];
|
|
41
|
+
|
|
42
|
+
tempPlanes[i * 2 + 1][0] = m[ 3] - m[i];
|
|
43
|
+
tempPlanes[i * 2 + 1][1] = m[ 7] - m[i + 4];
|
|
44
|
+
tempPlanes[i * 2 + 1][2] = m[11] - m[i + 8];
|
|
45
|
+
tempPlanes[i * 2 + 1][3] = m[15] - m[i + 12];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Normalize each plane
|
|
49
|
+
tempPlanes.forEach(p => math.divVec4Scalar(p, math.lenVec3(p), p));
|
|
50
|
+
|
|
51
|
+
return aabb => tempPlanes.every(p => {
|
|
52
|
+
// Compute the positive vertex (farthest in direction of normal)
|
|
53
|
+
tempVec4[0] = aabb[(p[0] >= 0) ? 3 : 0];
|
|
54
|
+
tempVec4[1] = aabb[(p[1] >= 0) ? 4 : 1];
|
|
55
|
+
tempVec4[2] = aabb[(p[2] >= 0) ? 5 : 2];
|
|
56
|
+
tempVec4[3] = 1;
|
|
57
|
+
return math.dotVec4(p, tempVec4) >= 0;
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const makeRayAABBIntersectionTest = (O, D) => aabb => {
|
|
62
|
+
let tmin = -Infinity;
|
|
63
|
+
let tmax = Infinity;
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < 3; i++) {
|
|
66
|
+
const origin = O[i];
|
|
67
|
+
const direction = D[i];
|
|
68
|
+
const minBound = aabb[i];
|
|
69
|
+
const maxBound = aabb[i + 3];
|
|
70
|
+
|
|
71
|
+
if (Math.abs(direction) < 1e-8) {
|
|
72
|
+
// Ray is parallel to plane
|
|
73
|
+
if ((origin < minBound) || (origin > maxBound)) {
|
|
74
|
+
return false; // No intersection
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
const t1 = (minBound - origin) / direction;
|
|
78
|
+
const t2 = (maxBound - origin) / direction;
|
|
79
|
+
|
|
80
|
+
tmin = Math.max(tmin, Math.min(t1, t2)); // near
|
|
81
|
+
tmax = Math.min(tmax, Math.max(t1, t2)); // far
|
|
82
|
+
|
|
83
|
+
if (tmin > tmax) {
|
|
84
|
+
return false; // No intersection
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return tmax >= 0; // Check if intersection is in front of ray
|
|
90
|
+
};
|
|
91
|
+
|
|
29
92
|
/**
|
|
30
93
|
* @private
|
|
31
94
|
*/
|
|
@@ -789,6 +852,8 @@ const Renderer = function (scene, options) {
|
|
|
789
852
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
790
853
|
}
|
|
791
854
|
|
|
855
|
+
frameCtx.testAABB = makeFrustumAABBIntersectionTest(scene.camera);
|
|
856
|
+
|
|
792
857
|
const renderDrawables = function(drawables) {
|
|
793
858
|
|
|
794
859
|
let normalDrawSAOBinLen = 0;
|
|
@@ -1123,6 +1188,8 @@ const Renderer = function (scene, options) {
|
|
|
1123
1188
|
renderDrawables(uiDrawableList);
|
|
1124
1189
|
}
|
|
1125
1190
|
|
|
1191
|
+
frameCtx.testAABB = null;
|
|
1192
|
+
|
|
1126
1193
|
const endTime = Date.now();
|
|
1127
1194
|
const frameStats = stats.frame;
|
|
1128
1195
|
|
|
@@ -1231,11 +1298,16 @@ const Renderer = function (scene, options) {
|
|
|
1231
1298
|
|
|
1232
1299
|
pickResult.canvasPos = params.canvasPos;
|
|
1233
1300
|
|
|
1301
|
+
math.canvasPosToWorldRay(canvas, pickViewMatrix, pickProjMatrix, projection, canvasPos, tempVec3a, tempVec3b);
|
|
1302
|
+
frameCtx.testAABB = makeRayAABBIntersectionTest(tempVec3a, tempVec3b);
|
|
1234
1303
|
} else {
|
|
1235
1304
|
|
|
1236
1305
|
// Picking with arbitrary World-space ray
|
|
1237
1306
|
// Align camera along ray and fire ray through center of canvas
|
|
1238
1307
|
|
|
1308
|
+
canvasPos[0] = canvas.clientWidth * 0.5;
|
|
1309
|
+
canvasPos[1] = canvas.clientHeight * 0.5;
|
|
1310
|
+
|
|
1239
1311
|
if (params.matrix) {
|
|
1240
1312
|
|
|
1241
1313
|
pickViewMatrix = params.matrix;
|
|
@@ -1245,6 +1317,8 @@ const Renderer = function (scene, options) {
|
|
|
1245
1317
|
nearAndFar[0] = camera.project.near;
|
|
1246
1318
|
nearAndFar[1] = camera.project.far;
|
|
1247
1319
|
|
|
1320
|
+
math.canvasPosToWorldRay(canvas, pickViewMatrix, pickProjMatrix, projection, canvasPos, tempVec3a, tempVec3b);
|
|
1321
|
+
frameCtx.testAABB = makeRayAABBIntersectionTest(tempVec3a, tempVec3b);
|
|
1248
1322
|
} else {
|
|
1249
1323
|
|
|
1250
1324
|
worldRayOrigin.set(params.origin || [0, 0, 0]);
|
|
@@ -1273,10 +1347,9 @@ const Renderer = function (scene, options) {
|
|
|
1273
1347
|
|
|
1274
1348
|
pickResult.origin = worldRayOrigin;
|
|
1275
1349
|
pickResult.direction = worldRayDir;
|
|
1276
|
-
}
|
|
1277
1350
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1351
|
+
frameCtx.testAABB = makeRayAABBIntersectionTest(pickResult.origin, pickResult.direction);
|
|
1352
|
+
}
|
|
1280
1353
|
}
|
|
1281
1354
|
|
|
1282
1355
|
pickBuffer.bind();
|
|
@@ -1313,6 +1386,8 @@ const Renderer = function (scene, options) {
|
|
|
1313
1386
|
renderDrawables(uiDrawableList);
|
|
1314
1387
|
}
|
|
1315
1388
|
|
|
1389
|
+
frameCtx.testAABB = null;
|
|
1390
|
+
|
|
1316
1391
|
const pickID = pixelToInt(pickBuffer.read(0, 0));
|
|
1317
1392
|
const pickable = (pickID >= 0) && pickIDs.items[pickID];
|
|
1318
1393
|
|
|
@@ -1844,4 +1919,4 @@ const Renderer = function (scene, options) {
|
|
|
1844
1919
|
};
|
|
1845
1920
|
};
|
|
1846
1921
|
|
|
1847
|
-
export {Renderer};
|
|
1922
|
+
export {Renderer};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Plugin, Viewer, SceneModel } from "../../viewer";
|
|
2
|
+
import { ModelStats } from "../index";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Default data source for loading IFC files in IFCOpenShellLoaderPlugin.
|
|
6
|
+
* Loads files via HTTP by default.
|
|
7
|
+
*/
|
|
8
|
+
export declare interface IFCOpenShellDefaultDataSource {
|
|
9
|
+
/**
|
|
10
|
+
* Loads the contents of the given IFC file as an ArrayBuffer.
|
|
11
|
+
* @param src Path or ID of the IFC file.
|
|
12
|
+
* @param ok Callback on success, receives the IFC file as an ArrayBuffer.
|
|
13
|
+
* @param error Callback on error, receives an Error.
|
|
14
|
+
*/
|
|
15
|
+
getIFC(src: string | number, ok: (buffer: ArrayBuffer) => void, error: (e: Error) => void): void;
|
|
16
|
+
|
|
17
|
+
/** Whether to append a cache-busting query parameter to requests. */
|
|
18
|
+
get cacheBuster(): boolean;
|
|
19
|
+
set cacheBuster(value: boolean);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration options for IFCOpenShellLoaderPlugin.
|
|
24
|
+
*/
|
|
25
|
+
export declare type IFCOpenShellLoaderPluginConfigs = {
|
|
26
|
+
/** Optional plugin ID. */
|
|
27
|
+
id?: string;
|
|
28
|
+
/** Custom data source for loading IFC files. */
|
|
29
|
+
dataSource?: IFCOpenShellDefaultDataSource;
|
|
30
|
+
/** Pyodide proxy for the ifcopenshell module. */
|
|
31
|
+
ifcopenshell: any;
|
|
32
|
+
/** Pyodide proxy for the ifcopenshell.geom module. */
|
|
33
|
+
ifcopenshell_geom: any;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parameters for loading an IFC model with IFCOpenShellLoaderPlugin.
|
|
38
|
+
*/
|
|
39
|
+
export declare type LoadIFCOpenShellModel = {
|
|
40
|
+
/** Unique ID for the loaded SceneModel. */
|
|
41
|
+
id?: string;
|
|
42
|
+
/** Path to the IFC file. */
|
|
43
|
+
src?: string;
|
|
44
|
+
/** Whether to load IFC metadata (metaobject). */
|
|
45
|
+
loadMetadata?: boolean;
|
|
46
|
+
/** Whether to load IFC metadata property sets. Only works when `loadMetadata` is `true`. */
|
|
47
|
+
loadMetadataPropertySets?: boolean;
|
|
48
|
+
/** Exclude objects with types in this list. */
|
|
49
|
+
excludeTypes?: string[];
|
|
50
|
+
/** Render the model with edges emphasized. */
|
|
51
|
+
edges?: boolean;
|
|
52
|
+
/** World-space double-precision origin for the model. */
|
|
53
|
+
origin?: number[];
|
|
54
|
+
/** Single-precision position offset, relative to origin. */
|
|
55
|
+
position?: number[];
|
|
56
|
+
/** Model scale. */
|
|
57
|
+
scale?: number[];
|
|
58
|
+
/** Model orientation as Euler angles (degrees) for X, Y, Z. */
|
|
59
|
+
rotation?: number[];
|
|
60
|
+
/** Enable Scalable Ambient Obscurance (SAO) for the model. */
|
|
61
|
+
saoEnabled?: boolean;
|
|
62
|
+
/** Force rendering of backfaces for the model. */
|
|
63
|
+
backfaces?: boolean;
|
|
64
|
+
/** Globalize Entity and MetaObject IDs to avoid clashes. */
|
|
65
|
+
globalizeObjectIds?: boolean;
|
|
66
|
+
/** Collect model statistics. */
|
|
67
|
+
stats?: ModelStats;
|
|
68
|
+
/** Indicates if compact data texture scene representation is enabled for this model. */
|
|
69
|
+
dtxEnabled?: boolean;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Viewer plugin that uses IfcOpenShell to load BIM models directly from IFC files.
|
|
74
|
+
*/
|
|
75
|
+
export declare class IFCOpenShellLoaderPlugin extends Plugin {
|
|
76
|
+
/**
|
|
77
|
+
* Creates a new IFCOpenShellLoaderPlugin.
|
|
78
|
+
* @param viewer The Viewer instance.
|
|
79
|
+
* @param cfg Plugin configuration.
|
|
80
|
+
*/
|
|
81
|
+
constructor(viewer: Viewer, cfg?: IFCOpenShellLoaderPluginConfigs);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sets a custom data source for loading IFC files.
|
|
85
|
+
* Default is IFCOpenShellDefaultDataSource, which loads via HTTP.
|
|
86
|
+
*/
|
|
87
|
+
set dataSource(arg: IFCOpenShellDefaultDataSource);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets the current data source for loading IFC files.
|
|
91
|
+
* Default is IFCOpenShellDefaultDataSource, which loads via HTTP.
|
|
92
|
+
*/
|
|
93
|
+
get dataSource(): IFCOpenShellDefaultDataSource;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets whether object and metaobject IDs are globalized to avoid clashes.
|
|
97
|
+
* Default is false.
|
|
98
|
+
*/
|
|
99
|
+
get globalizeObjectIds(): boolean;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Loads an IFC model into the Viewer's scene.
|
|
103
|
+
* @param params Loading parameters.
|
|
104
|
+
* @returns SceneModel representing the loaded model.
|
|
105
|
+
*/
|
|
106
|
+
load(params?: LoadIFCOpenShellModel): SceneModel;
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IFCOpenShellLoaderPlugin';
|
package/types/plugins/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from "./DistanceMeasurementsPlugin";
|
|
|
8
8
|
export * from "./DotBIMLoaderPlugin";
|
|
9
9
|
export * from "./FastNavPlugin";
|
|
10
10
|
export * from "./GLTFLoaderPlugin";
|
|
11
|
+
export * from "./IFCOpenShellLoaderPlugin";
|
|
11
12
|
export * from "./LASLoaderPlugin";
|
|
12
13
|
export * from "./NavCubePlugin";
|
|
13
14
|
export * from "./OBJLoaderPlugin";
|
|
@@ -170,20 +170,20 @@ export declare class CameraControl extends Component {
|
|
|
170
170
|
*
|
|
171
171
|
* See class docs for usage.
|
|
172
172
|
*
|
|
173
|
-
* @param {{Number:Number}|String} value Either a set of new key mappings, or a string to select a keyboard layout,
|
|
173
|
+
* @param {{Number:(Number | Number[])[]} | String} value Either a set of new key mappings, or a string to select a keyboard layout,
|
|
174
174
|
* which causes ````CameraControl```` to use the default key mappings for that layout.
|
|
175
175
|
*/
|
|
176
176
|
set keyMap(arg: {
|
|
177
|
-
[key: number]: number;
|
|
178
|
-
});
|
|
177
|
+
[key: number]: (number | number[])[];
|
|
178
|
+
} | string);
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
181
|
* Gets custom mappings of keys to {@link CameraControl} actions.
|
|
182
182
|
*
|
|
183
|
-
* @returns {{Number:Number}} Current key mappings.
|
|
183
|
+
* @returns {{Number:(Number | Number[])[]}} Current key mappings.
|
|
184
184
|
*/
|
|
185
185
|
get keyMap(): {
|
|
186
|
-
[key: number]: number;
|
|
186
|
+
[key: number]: (number | number[])[];
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
/**
|