@xeokit/xeokit-sdk 2.4.0-alpha-99 → 2.4.0-alpha-101
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 +16 -11
- package/dist/xeokit-sdk.es.js +16 -11
- package/dist/xeokit-sdk.es5.js +5 -8
- package/dist/xeokit-sdk.min.cjs.js +3 -3
- package/dist/xeokit-sdk.min.es.js +3 -3
- package/dist/xeokit-sdk.min.es5.js +3 -3
- package/package.json +1 -1
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +0 -1
- package/src/plugins/NavCubePlugin/CubeTextureCanvas.js +4 -4
- package/src/viewer/scene/model/MeshClusteringManager.js +31 -0
- package/src/viewer/scene/model/dtx/triangles/renderers/TrianglesDataTextureSnapDepthBufInitRenderer.js +4 -2
- package/src/viewer/scene/model/vbo/snapBatching/SnapBatchingDepthBufInitRenderer.js +4 -2
- package/src/viewer/scene/model/vbo/snapInstancing/SnapInstancingDepthBufInitRenderer.js +4 -2
- package/src/plugins/LODCullingPlugin/LODCullingPlugin.js +0 -209
- package/src/plugins/LODCullingPlugin/LODManager.js +0 -82
- package/src/plugins/LODCullingPlugin/LODState.js +0 -130
- package/src/plugins/LODCullingPlugin/index.js +0 -1
- package/src/viewer/scene/webgl/Renderer2.js +0 -1830
package/package.json
CHANGED
|
@@ -311,7 +311,6 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
|
|
|
311
311
|
this.pointerLens.visible = false;
|
|
312
312
|
}
|
|
313
313
|
this.reset();
|
|
314
|
-
this.viewer
|
|
315
314
|
const canvas = this.scene.canvas.canvas;
|
|
316
315
|
canvas.removeEventListener("mousedown", this._onMouseDown);
|
|
317
316
|
canvas.removeEventListener("mouseup", this._onMouseUp);
|
|
@@ -15,8 +15,8 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
|
|
|
15
15
|
const facesZUp = [
|
|
16
16
|
{boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || "#55FF55"},
|
|
17
17
|
{boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || "#55FF55"},
|
|
18
|
-
{boundary: [12, 6, 6, 6], color: cfg.
|
|
19
|
-
{boundary: [0, 6, 6, 6], color: cfg.
|
|
18
|
+
{boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || "#FF5555"},
|
|
19
|
+
{boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || "#FF5555"},
|
|
20
20
|
{boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || "#7777FF"},
|
|
21
21
|
{boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || "#7777FF"}
|
|
22
22
|
];
|
|
@@ -53,8 +53,8 @@ function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
|
|
|
53
53
|
const facesYUp = [
|
|
54
54
|
{boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || "#55FF55"},
|
|
55
55
|
{boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || "#55FF55"},
|
|
56
|
-
{boundary: [12, 6, 6, 6], color: cfg.
|
|
57
|
-
{boundary: [0, 6, 6, 6], color: cfg.
|
|
56
|
+
{boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || "#FF5555"},
|
|
57
|
+
{boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || "#FF5555"},
|
|
58
58
|
{boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || "#7777FF"},
|
|
59
59
|
{boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || "#7777FF"}
|
|
60
60
|
];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class MeshClusteringManager {
|
|
2
|
+
|
|
3
|
+
constructor(sceneModel) {
|
|
4
|
+
this.sceneModel = sceneModel;
|
|
5
|
+
this.meshes = [];
|
|
6
|
+
this.entities = [];
|
|
7
|
+
this.clusteredMeshes = [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
addMeshCfg(meshCfg) {
|
|
11
|
+
this.meshes.push(meshCfg);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
addEntityCfg(entityCfg) {
|
|
15
|
+
this.entities.push(entityCfg);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
doClustering() {
|
|
19
|
+
this.clusteredMeshes = this.meshes;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
finalize() {
|
|
23
|
+
this.doClustering();
|
|
24
|
+
for (let i = 0, len = this.clusteredMeshes.length; i < len; i++) {
|
|
25
|
+
this.sceneModel.addMesh(this.clusteredMeshes[i]);
|
|
26
|
+
}
|
|
27
|
+
for (let i = 0, len = this.entities.length; i < len; i++) {
|
|
28
|
+
this.sceneModel.addEntity(this.entities[i]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -371,7 +371,6 @@ export class TrianglesDataTextureSnapDepthBufInitRenderer {
|
|
|
371
371
|
src.push("float tmp = clipPos.w;")
|
|
372
372
|
src.push("clipPos.xyzw /= tmp;")
|
|
373
373
|
src.push("clipPos.xy = remapClipPos(clipPos.xy);");
|
|
374
|
-
src.push("clipPos.z += 0.0001;"); // small Z offset
|
|
375
374
|
src.push("clipPos.xyzw *= tmp;")
|
|
376
375
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
377
376
|
src.push("vFragDepth = 1.0 + clipPos.w;");
|
|
@@ -429,7 +428,10 @@ export class TrianglesDataTextureSnapDepthBufInitRenderer {
|
|
|
429
428
|
src.push(" }");
|
|
430
429
|
}
|
|
431
430
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
432
|
-
src.push("
|
|
431
|
+
src.push(" float dx = dFdx(vFragDepth);")
|
|
432
|
+
src.push(" float dy = dFdy(vFragDepth);")
|
|
433
|
+
src.push(" float diff = sqrt(dx*dx+dy*dy);");
|
|
434
|
+
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
|
|
433
435
|
}
|
|
434
436
|
src.push("outCoords = ivec4(relativeToOriginPosition.xyz * uCoordinateScaler.xyz, - uLayerNumber);")
|
|
435
437
|
src.push("}");
|
|
@@ -217,7 +217,6 @@ export class SnapBatchingDepthBufInitRenderer extends VBOSceneModelRenderer {
|
|
|
217
217
|
src.push("float tmp = clipPos.w;")
|
|
218
218
|
src.push("clipPos.xyzw /= tmp;")
|
|
219
219
|
src.push("clipPos.xy = remapClipPos(clipPos.xy);");
|
|
220
|
-
src.push("clipPos.z += 0.0001;"); // small Z offset
|
|
221
220
|
src.push("clipPos.xyzw *= tmp;")
|
|
222
221
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
223
222
|
src.push("vFragDepth = 1.0 + clipPos.w;");
|
|
@@ -275,7 +274,10 @@ export class SnapBatchingDepthBufInitRenderer extends VBOSceneModelRenderer {
|
|
|
275
274
|
src.push(" }");
|
|
276
275
|
}
|
|
277
276
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
278
|
-
src.push("
|
|
277
|
+
src.push(" float dx = dFdx(vFragDepth);")
|
|
278
|
+
src.push(" float dy = dFdy(vFragDepth);")
|
|
279
|
+
src.push(" float diff = sqrt(dx*dx+dy*dy);");
|
|
280
|
+
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
|
|
279
281
|
}
|
|
280
282
|
src.push("outCoords = ivec4(relativeToOriginPosition.xyz*coordinateScaler.xyz, -layerNumber);")
|
|
281
283
|
src.push("}");
|
|
@@ -249,7 +249,6 @@ class SnapInstancingDepthBufInitRenderer extends VBOSceneModelRenderer {
|
|
|
249
249
|
src.push("float tmp = clipPos.w;")
|
|
250
250
|
src.push("clipPos.xyzw /= tmp;")
|
|
251
251
|
src.push("clipPos.xy = remapClipPos(clipPos.xy);");
|
|
252
|
-
src.push("clipPos.z += 0.0001;"); // small Z offset
|
|
253
252
|
src.push("clipPos.xyzw *= tmp;")
|
|
254
253
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
255
254
|
src.push("vFragDepth = 1.0 + clipPos.w;");
|
|
@@ -307,7 +306,10 @@ class SnapInstancingDepthBufInitRenderer extends VBOSceneModelRenderer {
|
|
|
307
306
|
src.push("}");
|
|
308
307
|
}
|
|
309
308
|
if (SNAPPING_LOG_DEPTH_BUF_ENABLED) {
|
|
310
|
-
src.push("
|
|
309
|
+
src.push(" float dx = dFdx(vFragDepth);")
|
|
310
|
+
src.push(" float dy = dFdy(vFragDepth);")
|
|
311
|
+
src.push(" float diff = sqrt(dx*dx+dy*dy);");
|
|
312
|
+
src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
|
|
311
313
|
}
|
|
312
314
|
src.push("outCoords = ivec4(relativeToOriginPosition.xyz*coordinateScaler.xyz, -layerNumber);")
|
|
313
315
|
src.push("}");
|
|
@@ -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";
|