@xeokit/xeokit-sdk 2.4.0-alpha-99 → 2.4.0-alpha-100

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.4.0-alpha-99",
3
+ "version": "2.4.0-alpha-100",
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",
@@ -1,209 +0,0 @@
1
-
2
- import {LODManager} from "./LODManager.js";
3
- import {Plugin} from "../../viewer";
4
-
5
- /**
6
- * Manages LOD culling for {@link SceneModel} implementations.
7
- */
8
- export class LODCullingPlugin extends Plugin {
9
-
10
- constructor(viewer, cfg = {}) {
11
-
12
- super("LODCulling", viewer);
13
-
14
- this._scene = viewer.scene;
15
- this._lodLevels = [2000, 600, 150, 80, 20];
16
- this._neverCullTypes = [];
17
- this._neverCullTypesMap = {};
18
- this._lodManagers = {};
19
- this._lodManagerList = [];
20
-
21
- this.enabled = cfg.enabled;
22
- this.targetFPS = cfg.targetFPS;
23
-
24
- this._init();
25
- }
26
-
27
- _init() {
28
-
29
- const MAX_NUM_TICKS = 4;
30
- const tickTimeArray = new Array(MAX_NUM_TICKS);
31
-
32
- let numTick = 0;
33
- let currentFPS = -1;
34
- let preRenderTime = Date.now();
35
- let deltaTime = 0;
36
- let sceneTick = 0;
37
- let lastTickCameraMoved = sceneTick;
38
-
39
- this._scene.on("rendering", () => { // Apply LOD-culling before rendering the scene
40
- if (currentFPS === -1) {
41
- return;
42
- }
43
- for (let i = 0, len = this._lodManagerList.length; i < len; i++) {
44
- this._lodManagerList[i].applyLodCulling(currentFPS);
45
- }
46
- });
47
-
48
- this._scene.on("rendered", () => {
49
- preRenderTime = Date.now();
50
- window.requestAnimationFrame(() => {
51
- numTick++;
52
- const newTime = Date.now();
53
- deltaTime = newTime - preRenderTime;
54
- preRenderTime = newTime;
55
- tickTimeArray[numTick % MAX_NUM_TICKS] = deltaTime;
56
- let sumTickTimes = 0;
57
- if (numTick > MAX_NUM_TICKS) {
58
- for (let i = 0; i < MAX_NUM_TICKS; i++) {
59
- sumTickTimes += tickTimeArray[i];
60
- }
61
- currentFPS = MAX_NUM_TICKS / sumTickTimes * 1000;
62
- }
63
- });
64
- });
65
-
66
- this._scene.camera.on("matrix", () => {
67
- lastTickCameraMoved = sceneTick;
68
- });
69
-
70
- this._scene.on("tick", () => {
71
- if ((sceneTick - lastTickCameraMoved) > 3) {
72
- for (let i = 0, len = this._lodManagerList.length; i < len; i++) { // Call LOD-culling tasks
73
- this._lodManagerList[i].resetLodCulling();
74
- }
75
- }
76
- sceneTick++;
77
- });
78
-
79
- this._onModelLoaded = viewer.scene.on("modelLoaded", (modelId) => {
80
- const sceneModel = this.viewer.scene.models[modelId];
81
- if (sceneModel) {
82
- this._getLODManager(sceneModel);
83
- }
84
- });
85
- }
86
-
87
- /**
88
- * Sets whether LOD is enabled for the {@link Scene}.
89
- *
90
- * Default value is ````false````.
91
- *
92
- * @type {Boolean}
93
- */
94
- set enabled(value) {
95
- value = !!value;
96
- if (this._enabled === value) {
97
- return;
98
- }
99
- this._enabled = value;
100
- this.glRedraw();
101
- }
102
-
103
- /**
104
- * Gets whether LOD is enabled for the {@link Scene}.
105
- *
106
- * Default value is ````false````.
107
- *
108
- * @type {Boolean}
109
- */
110
- get enabled() {
111
- return this._enabled;
112
- }
113
-
114
- /**
115
- * Sets the maximum area that LOD takes into account when checking for possible occlusion for each fragment.
116
- *
117
- * Default value is ````30.0````.
118
- *
119
- * @type {Number}
120
- */
121
- set targetFPS(value) {
122
- if (value === undefined || value === null) {
123
- value = 30.0;
124
- }
125
- if (this._targetFPS === value) {
126
- return;
127
- }
128
- this._targetFPS = value;
129
- this.glRedraw();
130
- }
131
-
132
- /**
133
- * Gets the maximum area that LOD takes into account when checking for possible occlusion for each fragment.
134
- *
135
- * Default value is ````30.0````.
136
- *
137
- * @type {Number}
138
- */
139
- get targetFPS() {
140
- return this._targetFPS;
141
- }
142
-
143
- /**
144
- * Sets the {@link MetaObject} types that are never culled.
145
- *
146
- * Default value is ````[]````.
147
- *
148
- * @type {string[]}
149
- */
150
- set neverCullTypes(value) {
151
- if (value === undefined || value === null) {
152
- value = [];
153
- }
154
- this._neverCullTypes = value;
155
- this._neverCullTypesMap = {};
156
- for (let i = 0, len = this._neverCullTypes.length; i < len; i++) {
157
- this._neverCullTypesMap[this._neverCullTypes[i]] = true;
158
- }
159
- // this.glRedraw();
160
- }
161
-
162
- /**
163
- * Gets the {@link MetaObject} types that are never culled.
164
- *
165
- * Default value is ````[]````.
166
- *
167
- * @type {string[]}
168
- */
169
- get neverCullTypes() {
170
- return this._neverCullTypes;
171
- }
172
-
173
- /**
174
- * @private
175
- * @returns {*|{}}
176
- */
177
- get neverCullTypesMap() {
178
- return this._neverCullTypesMap;
179
- }
180
-
181
- /**
182
- * Called within SceneModel constructors
183
- * @private
184
- */
185
- _getLODManager(sceneModel) {
186
- const lodManager = new LODManager(this.scene, sceneModel, this._lodLevels, this._targetFPS);
187
- this._lodManagers[lodManager.id] = lodManager;
188
- this._lodManagerList = Object.values(this._lodManagers);
189
- return lodManager;
190
- }
191
-
192
- /**
193
- * Called within SceneModel destructors
194
- * @private
195
- */
196
- _putLODManager(lodManager) {
197
- delete this._lodManagers[lodManager.id];
198
- this._lodManagerList = Object.values(this._lodManagers);
199
- }
200
-
201
- /**
202
- * Destroys this component.
203
- *
204
- * @private
205
- */
206
- destroy() {
207
- super.destroy();
208
- }
209
- }
@@ -1,82 +0,0 @@
1
- import {LODState} from "./LODState.js";
2
-
3
- /**
4
- * @private
5
- */
6
- export class LODManager {
7
-
8
- constructor(scene, sceneModel, lodLevels, targetFps) {
9
- this.id = sceneModel.id;
10
- this.scene = scene;
11
- this.sceneModel = sceneModel;
12
- this.lodState = new LODState(lodLevels, targetFps);
13
- this.lodState.initializeLodState(sceneModel);
14
- }
15
-
16
- /**
17
- * Cull any objects belonging to the current `LOD` level, and increase the `LOD` level.
18
- */
19
- _increaseLODLevelIndex() {
20
- const lodState = this.lodState;
21
- if (lodState.lodLevelIndex === lodState.primLODLevels.length) {
22
- return false;
23
- }
24
- const entitiesInLOD = lodState.entitiesInLOD [lodState.primLODLevels[lodState.lodLevelIndex]] || [];
25
- for (let i = 0, len = entitiesInLOD.length; i < len; i++) {
26
- entitiesInLOD[i].culledLOD = true;
27
- }
28
- lodState.lodLevelIndex++;
29
- return true;
30
- }
31
-
32
- /**
33
- * Un-cull any objects belonging to the current `LOD` level, and decrease the `LOD` level.
34
- */
35
- _decreaseLODLevelIndex() {
36
- const lodState = this.lodState;
37
- if (lodState.lodLevelIndex === 0) {
38
- return false;
39
- }
40
- const entitiesInLOD = lodState.entitiesInLOD [lodState.primLODLevels[lodState.lodLevelIndex - 1]] || [];
41
- for (let i = 0, len = entitiesInLOD.length; i < len; i++) {
42
- entitiesInLOD[i].culledLOD = false;
43
- }
44
- lodState.lodLevelIndex--;
45
- return true;
46
- }
47
-
48
- /**
49
- * Apply LOD culling.
50
- *
51
- * Will update LOD level, if needed, based on current FPS and target FPS,
52
- * and then will cull/uncull the needed objects according to the LOD level.
53
- *
54
- * @param {number} currentFPS The current FPS (frames per second)
55
- * @returns {boolean} Whether the LOD level was changed. This is, if some object was culled/unculled.
56
- */
57
- applyLodCulling(currentFPS) {
58
- let lodState = this.lodState;
59
- let retVal = false;
60
- if (currentFPS < lodState.targetFps) {
61
- if (++lodState.consecutiveFramesWithoutTargetFps > 2) {
62
- lodState.consecutiveFramesWithoutTargetFps = 0;
63
- retVal = this._increaseLODLevelIndex();
64
- }
65
- } else if (currentFPS > (lodState.targetFps + 4)) {
66
- if (++lodState.consecutiveFramesWithTargetFps > 2) {
67
- lodState.consecutiveFramesWithTargetFps = 0;
68
- retVal = this._decreaseLODLevelIndex();
69
- }
70
- }
71
- return retVal;
72
- }
73
-
74
- resetLodCulling() {
75
- let retVal = false;
76
- let decreasedLevel = false;
77
- do {
78
- retVal |= (decreasedLevel = this._decreaseLODLevelIndex());
79
- } while (decreasedLevel);
80
- return retVal;
81
- }
82
- }
@@ -1,130 +0,0 @@
1
- import {math} from "../math/math.js";
2
-
3
- /**
4
- * Data structure containing pre-initialized `LOD` data.
5
- *
6
- * Will be used by the rest of `LOD` related code.
7
- *
8
- * @private
9
- */
10
-
11
- export class LODState {
12
-
13
- /**
14
- * @param {Array<number>} primLODLevels The primtive counts for the LOD levels, for example ```[ 2000, 600, 150, 80, 20 ]```
15
- * @param {number} targetFps The target FPS (_Frames Per Second_) for the dynamic culling of objects in the different LOD levels.
16
- */
17
- constructor(primLODLevels, targetFps) {
18
-
19
- /**
20
- * An array ordered DESC with the number of primtives allowed in each LOD bucket.
21
- *
22
- * @type {Array<number>}
23
- */
24
- this.primLODLevels = primLODLevels;
25
-
26
- /**
27
- * A computed dictionary for `primtive-number-buckets` where:
28
- * - key: the number of primtives allowed for the objects in the bucket.
29
- * - value: all PerformanceNodes that have the number of primtives or more.
30
- *
31
- * @type {Map<number, Array<DataTextureSceneModelNode>>}
32
- */
33
- this.entitiesInLOD = {};
34
-
35
- /**
36
- * A computed dictionary for `primtive-number-buckets` where:
37
- * - key: the number of primtives allowed for the objects in the bucket.
38
- * - value: the sum of primtives counts for all PeformanceNodes in the bucket.
39
- *
40
- * @type {Map<number, number>}
41
- */
42
- this.primCountInLOD = {};
43
-
44
- /**
45
- * The target FPS for the `LOD` mechanism:
46
- * - if real FPS are below this number, the next `LOD` level will be applied.
47
- *
48
- * - if real FPS are...
49
- * - above this number plus a margin
50
- * - and for some consecutive frames
51
- * ... then the previous `LOD` level will be applied.
52
- *
53
- * @type {number}
54
- */
55
- this.targetFps = targetFps;
56
-
57
- // /**
58
- // * Not used at the moment.
59
- // */
60
- // this.restoreTime = LOD_RESTORE_TIME;
61
-
62
- /**
63
- * Current `LOD` level. Starts at 0.
64
- *
65
- * @type {number}
66
- */
67
- this.lodLevelIndex = 0;
68
-
69
- /**
70
- * Number of consecutive frames in current `LOD` level where FPS was above `targetFps`
71
- *
72
- * @type {number}
73
- */
74
- this.consecutiveFramesWithTargetFps = 0;
75
-
76
- /**
77
- * Number of consecutive frames in current `LOD` level where FPS was below `targetFps`
78
- *
79
- * @type {number}
80
- */
81
- this.consecutiveFramesWithoutTargetFps = 0;
82
- }
83
-
84
- /**
85
- * @param {SceneModel} sceneModel
86
- */
87
- initializeLodState(sceneModel) {
88
- const entityList = Object.values(sceneModel.objects);
89
- if (entityList.length === 0) {
90
- return;
91
- }
92
- const neverCullTypesMap = sceneModel.scene.lod.neverCullTypesMap;
93
- const metaScene = sceneModel.scene.viewer.metaScene;
94
- const entitiesInLOD = {};
95
- const primCountInLOD = {};
96
- const maxSize = 20;
97
- const minComplexity = 25;
98
-
99
- for (let i = 0, len = entityList.length; i < len; i++) {
100
- const entity = entityList[i];
101
- const metaObject = metaScene.metaObjects[entity.id];
102
- if (metaObject && neverCullTypesMap[metaObject.type]) {
103
- continue;
104
- }
105
- const entityComplexity = entity.numPrimitives;
106
- const entitySize = math.getAABB3Diag(entity.aabb);
107
- // const isCullable = ((minComplexity <= entityComplexity) && (entitySize <= maxSize));
108
- // if (!isCullable) {
109
- // continue;
110
- // }
111
- let lodLevel = 0, len;
112
- for (lodLevel = 0, len = this.primLODLevels.length; lodLevel < len; lodLevel++) {
113
- if (entity.numPrimitives >= this.primLODLevels [lodLevel]) {
114
- break;
115
- }
116
- }
117
- const lodPrims = this.primLODLevels [lodLevel] || 0;
118
- if (!(lodPrims in entitiesInLOD)) {
119
- entitiesInLOD [lodPrims] = [];
120
- }
121
- entitiesInLOD [lodPrims].push(entity);
122
- if (!(lodPrims in primCountInLOD)) {
123
- primCountInLOD [lodPrims] = 0;
124
- }
125
- primCountInLOD [lodPrims] += entity.numPrimitives;
126
- }
127
- this.entitiesInLOD = entitiesInLOD;
128
- this.primCountInLOD = primCountInLOD;
129
- }
130
- }
@@ -1 +0,0 @@
1
- export * from "./LOD.js";