@shapediver/viewer.rendering-engine.rendering-engine-threejs 3.3.4 → 3.3.6
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 +19 -20
- package/src/RenderingEngine.ts +0 -1336
- package/src/index.ts +0 -81
- package/src/injectors/Tag3dGeometryCreationInjector.ts +0 -154
- package/src/injectors/TextureUnifierInjector.ts +0 -214
- package/src/interfaces/ILoader.ts +0 -3
- package/src/interfaces/IPostProcessingEffectDefinitions.ts +0 -402
- package/src/interfaces/IRenderingEngine.ts +0 -48
- package/src/loaders/EnvironmentMapLoader.ts +0 -357
- package/src/loaders/GeometryLoader.ts +0 -585
- package/src/loaders/HTMLElementAnchorLoader.ts +0 -107
- package/src/loaders/LightLoader.ts +0 -171
- package/src/loaders/MaterialLoader.ts +0 -1413
- package/src/managers/CameraManager.ts +0 -178
- package/src/managers/EnvironmentGeometryManager.ts +0 -224
- package/src/managers/PostProcessingManager.ts +0 -1181
- package/src/managers/RenderingManager.ts +0 -657
- package/src/managers/SceneTracingManager.ts +0 -127
- package/src/managers/SceneTreeManager.ts +0 -576
- package/src/managers/postprocessing/GodRaysManager.ts +0 -52
- package/src/managers/postprocessing/OutlineManager.ts +0 -58
- package/src/managers/postprocessing/SSAARenderPass.ts +0 -339
- package/src/managers/postprocessing/SelectiveBloomManager.ts +0 -58
- package/src/managers/postprocessing/ao/ao/AOEffect.ts +0 -180
- package/src/managers/postprocessing/ao/ao/AOPass.ts +0 -128
- package/src/managers/postprocessing/ao/ao/shader/ao_compose.glsl +0 -17
- package/src/managers/postprocessing/ao/ao/shader/ao_compose.ts +0 -19
- package/src/managers/postprocessing/ao/hbao/HBAOEffect.ts +0 -41
- package/src/managers/postprocessing/ao/hbao/shader/hbao.glsl +0 -96
- package/src/managers/postprocessing/ao/hbao/shader/hbao.ts +0 -98
- package/src/managers/postprocessing/ao/hbao/shader/hbao_utils.glsl +0 -92
- package/src/managers/postprocessing/ao/hbao/shader/hbao_utils.ts +0 -95
- package/src/managers/postprocessing/ao/poissionDenoise/PoissionDenoisePass.ts +0 -259
- package/src/managers/postprocessing/ao/poissionDenoise/shader/poissionDenoise.glsl +0 -125
- package/src/managers/postprocessing/ao/poissionDenoise/shader/poissionDenoise.ts +0 -127
- package/src/managers/postprocessing/ao/ssao/SSAOEffect.ts +0 -106
- package/src/managers/postprocessing/ao/ssao/shader/ssao.glsl +0 -128
- package/src/managers/postprocessing/ao/ssao/shader/ssao.ts +0 -130
- package/src/managers/postprocessing/ao/utils/shader/basic.glsl +0 -6
- package/src/managers/postprocessing/ao/utils/shader/basic.ts +0 -8
- package/src/managers/postprocessing/ao/utils/shader/sampleBlueNoise.glsl +0 -36
- package/src/managers/postprocessing/ao/utils/shader/sampleBlueNoise.ts +0 -38
- package/src/managers/postprocessing/utils/CopyMaterial.ts +0 -130
- package/src/managers/postprocessing/utils/CopyShader.ts +0 -39
- package/src/managers/postprocessing/utils/FullScreenQuad.ts +0 -47
- package/src/managers/postprocessing/utils/NormalPass.ts +0 -222
- package/src/managers/postprocessing/utils/RenderPass.ts +0 -366
- package/src/materials/GemMaterial.ts +0 -268
- package/src/materials/MeshUnlitMaterialParameters.ts +0 -4
- package/src/materials/MultiPointsMaterial.ts +0 -646
- package/src/materials/SpecularGlossinessMaterial.ts +0 -182
- package/src/objects/SDBone.ts +0 -51
- package/src/objects/SDColor.ts +0 -54
- package/src/objects/SDData.ts +0 -44
- package/src/objects/SDObject.ts +0 -58
- package/src/shaders/PCSS.ts +0 -124
- package/src/shaders/gem.ts +0 -579
- package/src/shaders/gem_frag.glsl +0 -522
- package/src/shaders/gem_vert.glsl +0 -53
- package/src/shaders/multi_points.ts +0 -291
- package/src/shaders/multi_points_frag.glsl +0 -166
- package/src/shaders/multi_points_vert.glsl +0 -120
- package/src/styling/viewport-css.ts +0 -113
- package/src/styling/viewport.css +0 -111
- package/src/three/font.ts +0 -2
- package/src/three/geometries/TextGeometry.ts +0 -58
- package/src/three/loaders/FontLoader.ts +0 -205
- package/src/three/loaders/RGBELoader.ts +0 -496
- package/src/types/IThreejsData.ts +0 -16
- package/src/types/ThreejsData.ts +0 -43
- package/tsconfig.json +0 -20
|
@@ -1,657 +0,0 @@
|
|
|
1
|
-
import * as Stats from 'stats.js';
|
|
2
|
-
import * as THREE from 'three';
|
|
3
|
-
import { AnimationEngine } from '@shapediver/viewer.rendering-engine.animation-engine';
|
|
4
|
-
import { AnimationFrameEngine } from '@shapediver/viewer.rendering-engine.animation-frame-engine';
|
|
5
|
-
import {
|
|
6
|
-
BUSY_MODE_DISPLAY,
|
|
7
|
-
IManager,
|
|
8
|
-
RENDERER_TYPE,
|
|
9
|
-
SPINNER_POSITIONING
|
|
10
|
-
} from '@shapediver/viewer.rendering-engine.rendering-engine';
|
|
11
|
-
import { ICameraEvent, IViewportEvent } from '@shapediver/viewer.shared.types';
|
|
12
|
-
import { ITree, Tree } from '@shapediver/viewer.shared.node-tree';
|
|
13
|
-
import { RenderingEngine } from '../RenderingEngine';
|
|
14
|
-
import { SceneTreeManager } from './SceneTreeManager';
|
|
15
|
-
import {
|
|
16
|
-
CAMERA_TYPE,
|
|
17
|
-
PerspectiveCamera,
|
|
18
|
-
PerspectiveCameraControls,
|
|
19
|
-
} from '@shapediver/viewer.rendering-engine.camera-engine';
|
|
20
|
-
import {
|
|
21
|
-
Converter,
|
|
22
|
-
EventEngine,
|
|
23
|
-
EVENTTYPE,
|
|
24
|
-
EVENTTYPE_VIEWPORT,
|
|
25
|
-
Logger,
|
|
26
|
-
SystemInfo,
|
|
27
|
-
} from '@shapediver/viewer.shared.services';
|
|
28
|
-
|
|
29
|
-
export class RenderingManager implements IManager {
|
|
30
|
-
// #region Properties (30)
|
|
31
|
-
|
|
32
|
-
private readonly _animationEngine: AnimationEngine = AnimationEngine.instance;
|
|
33
|
-
private readonly _animationFrameEngine: AnimationFrameEngine = AnimationFrameEngine.instance;
|
|
34
|
-
private readonly _converter: Converter = Converter.instance;
|
|
35
|
-
private readonly _eventEngine: EventEngine = EventEngine.instance;
|
|
36
|
-
private readonly _logger: Logger = Logger.instance;
|
|
37
|
-
private readonly _systemInfo: SystemInfo = SystemInfo.instance;
|
|
38
|
-
private readonly _tree: ITree = Tree.instance;
|
|
39
|
-
|
|
40
|
-
private _activeRendering: boolean = true;
|
|
41
|
-
private _cameraChanged: boolean = false;
|
|
42
|
-
private _continuousRendering: boolean = false;
|
|
43
|
-
private _continuousShadowMapUpdate: boolean = false;
|
|
44
|
-
private _height: number = 0;
|
|
45
|
-
private _hidden: boolean = true;
|
|
46
|
-
private _hiddenCamera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera();
|
|
47
|
-
private _hiddenRenderTarget: THREE.WebGLRenderTarget = new THREE.WebGLRenderTarget();
|
|
48
|
-
private _hideLogo: boolean = false;
|
|
49
|
-
private _lastSize: {
|
|
50
|
-
adjustedWidth: number,
|
|
51
|
-
adjustedHeight: number,
|
|
52
|
-
width: number,
|
|
53
|
-
height: number
|
|
54
|
-
} = {
|
|
55
|
-
adjustedWidth: 0,
|
|
56
|
-
adjustedHeight: 0,
|
|
57
|
-
width: 0,
|
|
58
|
-
height: 0
|
|
59
|
-
};
|
|
60
|
-
private _lightSizeUVEnd = 0.15;
|
|
61
|
-
private _lightSizeUVStart = 0.025;
|
|
62
|
-
private _maxTextureUnits: number = 0;
|
|
63
|
-
private _minimalRendering: boolean = false;
|
|
64
|
-
private _noWebGL: boolean = false;
|
|
65
|
-
private _runningAnimation: boolean = false;
|
|
66
|
-
private _sizeChanged: boolean = false;
|
|
67
|
-
private _softShadowRenderingActive: boolean = false;
|
|
68
|
-
private _softShadowRenderingDurationActive: number = 0;
|
|
69
|
-
private _softShadowRenderingTimeout: NodeJS.Timeout | null = null;
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
-
private _stats: any;
|
|
72
|
-
private _usingSwiftShader: boolean = false;
|
|
73
|
-
private _width: number = 0;
|
|
74
|
-
|
|
75
|
-
// #endregion Properties (30)
|
|
76
|
-
|
|
77
|
-
// #region Constructors (1)
|
|
78
|
-
|
|
79
|
-
constructor(private readonly _renderingEngine: RenderingEngine) { }
|
|
80
|
-
|
|
81
|
-
// #endregion Constructors (1)
|
|
82
|
-
|
|
83
|
-
// #region Public Getters And Setters (6)
|
|
84
|
-
|
|
85
|
-
public get continuousRendering(): boolean {
|
|
86
|
-
return this._continuousRendering;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
public set continuousRendering(value: boolean) {
|
|
90
|
-
this._continuousRendering = value;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public get continuousShadowMapUpdate(): boolean {
|
|
94
|
-
return this._continuousShadowMapUpdate;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public set continuousShadowMapUpdate(value: boolean) {
|
|
98
|
-
this._continuousShadowMapUpdate = value;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public get minimalRendering(): boolean {
|
|
102
|
-
return this._minimalRendering;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public get usingSwiftShader(): boolean {
|
|
106
|
-
return this._usingSwiftShader;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// #endregion Public Getters And Setters (6)
|
|
110
|
-
|
|
111
|
-
// #region Public Methods (10)
|
|
112
|
-
|
|
113
|
-
public addLogo(canvas: HTMLCanvasElement, branding: {
|
|
114
|
-
logo: string | null;
|
|
115
|
-
backgroundColor: string;
|
|
116
|
-
busyModeSpinner: string;
|
|
117
|
-
busyModeDisplay: BUSY_MODE_DISPLAY;
|
|
118
|
-
spinnerPositioning: SPINNER_POSITIONING
|
|
119
|
-
}): HTMLDivElement {
|
|
120
|
-
const logoDivElement = document.createElement('div');
|
|
121
|
-
logoDivElement.style.backgroundColor = branding.backgroundColor;
|
|
122
|
-
logoDivElement.classList.add('sdv-logo-container');
|
|
123
|
-
canvas.parentElement?.insertBefore(logoDivElement, canvas.parentElement?.firstChild);
|
|
124
|
-
|
|
125
|
-
if (branding.logo) {
|
|
126
|
-
const img = new Image();
|
|
127
|
-
img.classList.add('sdv-logo');
|
|
128
|
-
img.src = branding.logo;
|
|
129
|
-
logoDivElement.appendChild(img);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return logoDivElement;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
public addSpinner(canvas: HTMLCanvasElement, branding: {
|
|
136
|
-
logo: string | null;
|
|
137
|
-
backgroundColor: string;
|
|
138
|
-
busyModeSpinner: string;
|
|
139
|
-
busyModeDisplay: BUSY_MODE_DISPLAY;
|
|
140
|
-
spinnerPositioning: SPINNER_POSITIONING
|
|
141
|
-
}): HTMLDivElement {
|
|
142
|
-
const spinnerDivElement = document.createElement('div');
|
|
143
|
-
spinnerDivElement.classList.add('sdv-spinner-container');
|
|
144
|
-
|
|
145
|
-
spinnerDivElement.style.visibility = 'hidden';
|
|
146
|
-
canvas.parentElement?.insertBefore(spinnerDivElement, canvas.parentElement?.firstChild);
|
|
147
|
-
|
|
148
|
-
if (branding.busyModeSpinner) {
|
|
149
|
-
const img = new Image();
|
|
150
|
-
img.src = branding.busyModeSpinner;
|
|
151
|
-
img.classList.add('sdv-spinner');
|
|
152
|
-
img.classList.add('sdv-spinner-' + branding.spinnerPositioning.replace('_', '-').toLowerCase());
|
|
153
|
-
spinnerDivElement.appendChild(img);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return spinnerDivElement;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
public createRenderer(canvas: HTMLCanvasElement): THREE.WebGLRenderer {
|
|
160
|
-
const renderingProperties = {
|
|
161
|
-
alpha: true,
|
|
162
|
-
depth: true,
|
|
163
|
-
antialias: true,
|
|
164
|
-
preserveDrawingBuffer: true,
|
|
165
|
-
stencil: true,
|
|
166
|
-
premultipliedAlpha: true,
|
|
167
|
-
canvas
|
|
168
|
-
};
|
|
169
|
-
const renderer = new THREE.WebGLRenderer(renderingProperties);
|
|
170
|
-
renderer.setPixelRatio(window.devicePixelRatio);
|
|
171
|
-
|
|
172
|
-
const context = renderer.getContext();
|
|
173
|
-
|
|
174
|
-
if (renderer.extensions.has('WEBGL_debug_renderer_info')) {
|
|
175
|
-
const debugInfo = renderer.extensions.get('WEBGL_debug_renderer_info');
|
|
176
|
-
// const vendor = context.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
|
|
177
|
-
const rendererInfo = context.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
|
|
178
|
-
if (rendererInfo === 'Google SwiftShader') {
|
|
179
|
-
this._usingSwiftShader = true;
|
|
180
|
-
this._logger.warn('RenderingLogic.createWebGLContext: The current device is using Google SwiftShader, a CPU-based renderer. To achieve better rendering results, please enable GPU-rendering in your settings.');
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (!renderer.extensions.has('EXT_shader_texture_lod'))
|
|
185
|
-
this._minimalRendering = true;
|
|
186
|
-
|
|
187
|
-
renderer.useLegacyLights = true;
|
|
188
|
-
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
189
|
-
renderer.toneMapping = THREE.NoToneMapping;
|
|
190
|
-
renderer.shadowMap.enabled = true;
|
|
191
|
-
renderer.shadowMap.needsUpdate = true;
|
|
192
|
-
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
193
|
-
renderer.shadowMap.autoUpdate = false;
|
|
194
|
-
renderer.localClippingEnabled = true;
|
|
195
|
-
renderer.setSize(canvas.width, canvas.height);
|
|
196
|
-
renderer.setClearColor(new THREE.Color('#ffffff'), 1);
|
|
197
|
-
this._maxTextureUnits = renderer.getContext().getParameter(renderer.getContext().MAX_TEXTURE_IMAGE_UNITS);
|
|
198
|
-
return renderer;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
public evaluateTextureUnitCount(value: number) {
|
|
202
|
-
if (value > this._maxTextureUnits) {
|
|
203
|
-
this._logger.warn('RenderingManager.evaluateTextureUnitCount: Maximum number of texture units exceeded. Disabling shadows.');
|
|
204
|
-
this._renderingEngine.lightLoader.forceDisabledShadows = true;
|
|
205
|
-
this._renderingEngine.update('RenderingManager.evaluateTextureUnitCount');
|
|
206
|
-
} else {
|
|
207
|
-
this._renderingEngine.lightLoader.forceDisabledShadows = false;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
public getScreenshot(type: string = 'image/png', encoderOptions: number = 1): string {
|
|
212
|
-
return this._renderingEngine.renderer.domElement.toDataURL(type, encoderOptions);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public init(): void {
|
|
216
|
-
try {
|
|
217
|
-
this._renderingEngine.materialLoader.updateSoftShadow(this._lightSizeUVEnd, 1.0);
|
|
218
|
-
|
|
219
|
-
this._renderingEngine.renderer.shadowMap.type = THREE.PCFShadowMap;
|
|
220
|
-
this._renderingEngine.renderer.shadowMap.needsUpdate = true;
|
|
221
|
-
this._renderingEngine.materialLoader.updateMaterials();
|
|
222
|
-
|
|
223
|
-
this._eventEngine.addListener(EVENTTYPE.CAMERA.CAMERA_START, (e) => {
|
|
224
|
-
const viewerEvent = <ICameraEvent>e;
|
|
225
|
-
if (viewerEvent.viewportId === this._renderingEngine.id)
|
|
226
|
-
this.startRendering();
|
|
227
|
-
});
|
|
228
|
-
this._eventEngine.addListener(EVENTTYPE.CAMERA.CAMERA_END, (e) => {
|
|
229
|
-
const viewerEvent = <ICameraEvent>e;
|
|
230
|
-
if (viewerEvent.viewportId === this._renderingEngine.id)
|
|
231
|
-
this.stopRendering();
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
window.onresize = () => { this.render(); };
|
|
235
|
-
this._renderingEngine.canvas.onresize = () => { this.render(); };
|
|
236
|
-
this._renderingEngine.canvas.parentElement!.onresize = () => { this.render(); };
|
|
237
|
-
|
|
238
|
-
const stats1 = new Stats.default();
|
|
239
|
-
stats1.showPanel(0); // Panel 0 = fps
|
|
240
|
-
stats1.dom.style.cssText = 'position:absolute;top:0px;left:0px;display:none;';
|
|
241
|
-
this._renderingEngine.canvas.parentElement!.appendChild(stats1.dom);
|
|
242
|
-
|
|
243
|
-
const stats2 = new Stats.default();
|
|
244
|
-
stats2.showPanel(1); // Panel 1 = ms
|
|
245
|
-
stats2.dom.style.cssText = 'position:absolute;top:0px;left:80px;display:none;';
|
|
246
|
-
this._renderingEngine.canvas.parentElement!.appendChild(stats2.dom);
|
|
247
|
-
|
|
248
|
-
const stats3 = new Stats.default();
|
|
249
|
-
stats3.showPanel(2); // Panel 2 = ms
|
|
250
|
-
stats3.dom.style.cssText = 'position:absolute;top:0px;left:160px;display:none;';
|
|
251
|
-
this._renderingEngine.canvas.parentElement!.appendChild(stats3.dom);
|
|
252
|
-
|
|
253
|
-
this._stats = {
|
|
254
|
-
stats: [stats1, stats2, stats3],
|
|
255
|
-
begin: () => {
|
|
256
|
-
stats1.begin();
|
|
257
|
-
stats2.begin();
|
|
258
|
-
stats3.begin();
|
|
259
|
-
},
|
|
260
|
-
end: () => {
|
|
261
|
-
stats1.end();
|
|
262
|
-
stats2.end();
|
|
263
|
-
stats3.end();
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
} catch (e) {
|
|
267
|
-
this._noWebGL = true;
|
|
268
|
-
throw e;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
public render() {
|
|
273
|
-
this.startAndStopRendering();
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
public resize(width: number, height: number) {
|
|
277
|
-
this._width = width, this._height = height;
|
|
278
|
-
this._renderingEngine.materialLoader.assignPointSize(this._renderingEngine.pointSize);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Must only be called once by the RenderingEngine!
|
|
283
|
-
*/
|
|
284
|
-
public start() {
|
|
285
|
-
this._animationFrameEngine.addAnimationFrameCallback(this.animate.bind(this));
|
|
286
|
-
this.startAndStopRendering();
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
public updateShadowMap() {
|
|
290
|
-
this._renderingEngine.renderer.shadowMap.needsUpdate = true;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// #endregion Public Methods (10)
|
|
294
|
-
|
|
295
|
-
// #region Private Methods (14)
|
|
296
|
-
|
|
297
|
-
private activateBeautyRenderShaders() {
|
|
298
|
-
this._renderingEngine.renderer.shadowMap.type = THREE.PCFShadowMap;
|
|
299
|
-
this._renderingEngine.renderer.shadowMap.needsUpdate = true;
|
|
300
|
-
this._renderingEngine.materialLoader.updateMaterials();
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
private animate(time: number, deltaTime: number, runningAnimation: boolean): void {
|
|
304
|
-
// animation loop - part 1: initial discarding
|
|
305
|
-
if (this._renderingEngine.closed || this._noWebGL) return;
|
|
306
|
-
|
|
307
|
-
this._renderingEngine.evaluateFlagState();
|
|
308
|
-
|
|
309
|
-
// update if needed
|
|
310
|
-
if (this._renderingEngine.show === true && this._tree.root.version !== this._renderingEngine.sceneTreeManager.lastRootVersion) {
|
|
311
|
-
this._renderingEngine.sceneTreeManager.updateSceneTree(this._tree.root);
|
|
312
|
-
this.updateShadowMap();
|
|
313
|
-
this._animationEngine.updateAnimationData();
|
|
314
|
-
this.render();
|
|
315
|
-
this._eventEngine.emitEvent(EVENTTYPE_VIEWPORT.VIEWPORT_UPDATED, <IViewportEvent>{ viewportId: this._renderingEngine.id });
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (this._renderingEngine.preRenderingCallback)
|
|
319
|
-
this._renderingEngine.preRenderingCallback(this._renderingEngine.renderer);
|
|
320
|
-
|
|
321
|
-
if (runningAnimation !== this._runningAnimation) this.render();
|
|
322
|
-
this._runningAnimation = runningAnimation;
|
|
323
|
-
if (this._runningAnimation) this._renderingEngine.sceneTreeManager.updateNode(undefined, undefined, { transformationOnly: true });
|
|
324
|
-
if (this._runningAnimation) this._renderingEngine.sceneTreeManager.updateMorphWeights();
|
|
325
|
-
|
|
326
|
-
// get the current size
|
|
327
|
-
const { width, height, adjustedWidth, adjustedHeight } = this.calculateSize();
|
|
328
|
-
const aspect = width / height;
|
|
329
|
-
this._sizeChanged = this._lastSize.adjustedHeight !== adjustedHeight || this._lastSize.adjustedWidth !== adjustedWidth || this._lastSize.height !== height || this._lastSize.width !== width;
|
|
330
|
-
this._lastSize = { width, height, adjustedWidth, adjustedHeight };
|
|
331
|
-
|
|
332
|
-
// animation loop - part 3: update the camera, if there are new movements, they will start / continue the rendering
|
|
333
|
-
this._cameraChanged = this._renderingEngine.cameraEngine.camera ? this._renderingEngine.cameraManager.updateCamera(deltaTime, aspect) : false;
|
|
334
|
-
|
|
335
|
-
// animation loop - part 4: evaluating state
|
|
336
|
-
const states = this.evaluateRenderingState();
|
|
337
|
-
|
|
338
|
-
// toggle the blurring
|
|
339
|
-
this.toggleBusyMode(states.busyMode);
|
|
340
|
-
|
|
341
|
-
// animation loop - part 5: the scene is not even shown
|
|
342
|
-
if (states.showScene === false) {
|
|
343
|
-
// toggle on logo
|
|
344
|
-
this.toggleLogo(true);
|
|
345
|
-
|
|
346
|
-
if (this._hidden === false)
|
|
347
|
-
this._eventEngine.emitEvent(EVENTTYPE.VIEWPORT.VIEWPORT_HIDDEN, { viewportId: this._renderingEngine.id });
|
|
348
|
-
|
|
349
|
-
this._hidden = true;
|
|
350
|
-
return;
|
|
351
|
-
} else {
|
|
352
|
-
// we delay for one render call as some of the postprocessing effects have artefacts in the first call
|
|
353
|
-
if (this._hideLogo === true && this._hidden === true) {
|
|
354
|
-
this.toggleLogo(false);
|
|
355
|
-
this._hideLogo = false;
|
|
356
|
-
|
|
357
|
-
if (this._hidden === true)
|
|
358
|
-
this._eventEngine.emitEvent(EVENTTYPE.VIEWPORT.VIEWPORT_VISIBLE, { viewportId: this._renderingEngine.id });
|
|
359
|
-
|
|
360
|
-
this._hidden = false;
|
|
361
|
-
} else {
|
|
362
|
-
this._hideLogo = true;
|
|
363
|
-
if (this._hidden === true)
|
|
364
|
-
this._renderingEngine.postProcessingManager.changeEffectPass();
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// animation loop - part 6: the scene is shown, but there is no active rendering happening
|
|
369
|
-
if (states.rendering === false || this._renderingEngine.pause === true) return;
|
|
370
|
-
|
|
371
|
-
// animation loop - part 7: there is actual rendering happening
|
|
372
|
-
// do the things that have to be done for standard and beauty rendering in the same way
|
|
373
|
-
this._stats.begin();
|
|
374
|
-
this.showStatistics();
|
|
375
|
-
|
|
376
|
-
// animation loop - part 8: calculate the current size
|
|
377
|
-
const currentSize = new THREE.Vector2();
|
|
378
|
-
this._renderingEngine.renderer.getSize(currentSize);
|
|
379
|
-
if (!currentSize.equals(new THREE.Vector2(adjustedWidth, adjustedHeight))) {
|
|
380
|
-
this._renderingEngine.renderer.setSize(adjustedWidth, adjustedHeight);
|
|
381
|
-
this._renderingEngine.postProcessingManager.resize(adjustedWidth, adjustedHeight);
|
|
382
|
-
this._renderingEngine.renderer.domElement.style.width = width + 'px';
|
|
383
|
-
this._renderingEngine.renderer.domElement.style.height = height + 'px';
|
|
384
|
-
this._renderingEngine.materialLoader.assignPointSize(this._renderingEngine.pointSize);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// animation loop - part 9: adjust the camera (the rendering state would be false if we didn't have a camera)
|
|
388
|
-
const { camera, matrix } = this._renderingEngine.cameraManager.adjustCamera(aspect);
|
|
389
|
-
|
|
390
|
-
// if a matrix is provided after a camera adjustment
|
|
391
|
-
// that means that the turntable controls or the object controls are activated
|
|
392
|
-
if (matrix) {
|
|
393
|
-
for (let i = 0; i < this._tree.root.children.length; i++) {
|
|
394
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
395
|
-
if (!(<any>this._tree.root.children[i]).sessionNode || this._tree.root.children[i].excludeViewports.includes(this._renderingEngine.id)) continue;
|
|
396
|
-
const transform = this._tree.root.children[i].transformations.find(t => t.id === 'objectRotation');
|
|
397
|
-
if (transform) {
|
|
398
|
-
transform.matrix = matrix;
|
|
399
|
-
} else {
|
|
400
|
-
this._tree.root.children[i].addTransformation({
|
|
401
|
-
id: 'objectRotation',
|
|
402
|
-
matrix
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
states.updateShadowMap = true;
|
|
407
|
-
this._renderingEngine.sceneTreeManager.updateNode(undefined, undefined, { transformationOnly: true });
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// animation loop - part 10: adjust the anchor elements
|
|
411
|
-
this._renderingEngine.htmlElementAnchorLoader.adjustPositions(adjustedWidth / width, adjustedHeight / height);
|
|
412
|
-
|
|
413
|
-
// animation loop - part 11: adjust some scene settings
|
|
414
|
-
// enable / disable the shadow map
|
|
415
|
-
const enabled = this._renderingEngine.renderer.shadowMap.enabled;
|
|
416
|
-
this._renderingEngine.renderer.shadowMap.enabled = this._renderingEngine.usingSwiftShader || this._renderingEngine.type === RENDERER_TYPE.ATTRIBUTES ? false : this._renderingEngine.shadows;
|
|
417
|
-
if (enabled !== this._renderingEngine.renderer.shadowMap.enabled) this._renderingEngine.materialLoader.updateMaterials();
|
|
418
|
-
let threeJsLightObject, oldLightVisibility = true;
|
|
419
|
-
// enable / disable lights
|
|
420
|
-
if (this._renderingEngine.lights === false) {
|
|
421
|
-
const ls = this._renderingEngine.lightEngine.lightScene;
|
|
422
|
-
if (ls) {
|
|
423
|
-
threeJsLightObject = ls.node.convertedObject[this._renderingEngine.id] as THREE.Object3D;
|
|
424
|
-
if (threeJsLightObject) {
|
|
425
|
-
oldLightVisibility = threeJsLightObject.visible;
|
|
426
|
-
threeJsLightObject.visible = false;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// update shadowMap if need
|
|
432
|
-
if (states.updateShadowMap && this._renderingEngine.renderer.shadowMap.enabled) this._renderingEngine.renderer.shadowMap.needsUpdate = true;
|
|
433
|
-
|
|
434
|
-
// enable / disable the background
|
|
435
|
-
this._renderingEngine.sceneTreeManager.scene.background = this._renderingEngine.environmentMapAsBackground ? this._renderingEngine.environmentMapLoader.environmentMap : null;
|
|
436
|
-
// set the background color / alpha
|
|
437
|
-
this._renderingEngine.renderer.setClearColor(new THREE.Color(this._converter.toThreeJsColorInput(this._renderingEngine.clearColor)), this._renderingEngine.clearAlpha);
|
|
438
|
-
|
|
439
|
-
// check if we should render with post-processing
|
|
440
|
-
const renderPostProcessing = (this._renderingEngine.postProcessingManager.effects.length > 0 || this._renderingEngine.postProcessingManager.manualPostProcessing) &&
|
|
441
|
-
!(this._renderingEngine.postProcessingManager.enablePostProcessingOnMobile === false && this._systemInfo.isMobile === true);
|
|
442
|
-
|
|
443
|
-
// animation loop - part 12: actual rendering separation
|
|
444
|
-
if (states.softShadowRendering === true) {
|
|
445
|
-
this.setShaderProperties();
|
|
446
|
-
|
|
447
|
-
if (renderPostProcessing) {
|
|
448
|
-
this._renderingEngine.postProcessingManager.render(deltaTime, camera);
|
|
449
|
-
} else {
|
|
450
|
-
this._renderingEngine.renderer.render((<SceneTreeManager>this._renderingEngine.sceneTreeManager).scene, camera);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// if the duration was long enough, disable the beauty rendering
|
|
454
|
-
if (this._softShadowRenderingDurationActive >= this._renderingEngine.beautyRenderBlendingDuration) {
|
|
455
|
-
this._eventEngine.emitEvent(EVENTTYPE.RENDERING.BEAUTY_RENDERING_FINISHED, { viewportId: this._renderingEngine.id });
|
|
456
|
-
this.deactivateBeautyRenderShaders();
|
|
457
|
-
this._activeRendering = false;
|
|
458
|
-
} else {
|
|
459
|
-
this._softShadowRenderingDurationActive += deltaTime;
|
|
460
|
-
}
|
|
461
|
-
} else {
|
|
462
|
-
if (renderPostProcessing) {
|
|
463
|
-
this._renderingEngine.postProcessingManager.render(deltaTime, camera);
|
|
464
|
-
} else {
|
|
465
|
-
this._renderingEngine.renderer.render((<SceneTreeManager>this._renderingEngine.sceneTreeManager).scene, camera);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
// if the beauty rendering was active, disable it
|
|
469
|
-
if (this._softShadowRenderingActive) {
|
|
470
|
-
this._eventEngine.emitEvent(EVENTTYPE.RENDERING.BEAUTY_RENDERING_FINISHED, { viewportId: this._renderingEngine.id });
|
|
471
|
-
this.deactivateBeautyRenderShaders();
|
|
472
|
-
this._activeRendering = false;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// reset the visibility of the threeJs light object
|
|
477
|
-
if (threeJsLightObject)
|
|
478
|
-
threeJsLightObject.visible = oldLightVisibility;
|
|
479
|
-
|
|
480
|
-
if (this._renderingEngine.postRenderingCallback)
|
|
481
|
-
this._renderingEngine.postRenderingCallback(this._renderingEngine.renderer, this._renderingEngine.scene, this._renderingEngine.camera);
|
|
482
|
-
|
|
483
|
-
this._stats.end();
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
private calculateSize(): { adjustedWidth: number, adjustedHeight: number, width: number, height: number } {
|
|
487
|
-
let width = this._width, height = this._height;
|
|
488
|
-
if (this._renderingEngine.automaticResizing) {
|
|
489
|
-
width = (<HTMLDivElement>this._renderingEngine.canvas.parentNode).clientWidth;
|
|
490
|
-
height = (<HTMLDivElement>this._renderingEngine.canvas.parentNode).clientHeight;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const aspect = width / height;
|
|
494
|
-
let adjustedWidth = width,
|
|
495
|
-
adjustedHeight = height;
|
|
496
|
-
|
|
497
|
-
if (width > this._renderingEngine.maximumRenderingSize.width || height > this._renderingEngine.maximumRenderingSize.height) {
|
|
498
|
-
if ((width - this._renderingEngine.maximumRenderingSize.width) / aspect > (height - this._renderingEngine.maximumRenderingSize.height)) {
|
|
499
|
-
adjustedWidth = this._renderingEngine.maximumRenderingSize.width;
|
|
500
|
-
adjustedHeight = this._renderingEngine.maximumRenderingSize.width / aspect;
|
|
501
|
-
} else {
|
|
502
|
-
adjustedWidth = this._renderingEngine.maximumRenderingSize.height * aspect;
|
|
503
|
-
adjustedHeight = this._renderingEngine.maximumRenderingSize.height;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
width, adjustedWidth,
|
|
508
|
-
height, adjustedHeight
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
private deactivateBeautyRenderShaders() {
|
|
513
|
-
this._softShadowRenderingTimeout = null;
|
|
514
|
-
this._softShadowRenderingActive = false;
|
|
515
|
-
this._softShadowRenderingDurationActive = 0;
|
|
516
|
-
this._renderingEngine.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
517
|
-
this._renderingEngine.renderer.shadowMap.needsUpdate = true;
|
|
518
|
-
this._renderingEngine.materialLoader.updateSoftShadow(this._lightSizeUVStart, 0.1);
|
|
519
|
-
this._renderingEngine.materialLoader.updateMaterials();
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
private evaluateRenderingState(): {
|
|
523
|
-
showScene: boolean,
|
|
524
|
-
rendering: boolean,
|
|
525
|
-
busyMode: boolean,
|
|
526
|
-
updateShadowMap: boolean,
|
|
527
|
-
softShadowRendering: boolean
|
|
528
|
-
} {
|
|
529
|
-
// If there is a camera to show the scene and the setting for it is set to true, we show the scene
|
|
530
|
-
let showScene = false;
|
|
531
|
-
if (this._renderingEngine.cameraEngine.camera && this._renderingEngine.show === true)
|
|
532
|
-
showScene = true;
|
|
533
|
-
|
|
534
|
-
// If we should render at all
|
|
535
|
-
let rendering = false;
|
|
536
|
-
if (this._activeRendering === true || this._cameraChanged === true || this._sizeChanged === true || this._runningAnimation === true || this._continuousRendering === true)
|
|
537
|
-
rendering = true;
|
|
538
|
-
|
|
539
|
-
let updateShadowMap = false;
|
|
540
|
-
if (this._runningAnimation === true || this._continuousShadowMapUpdate === true)
|
|
541
|
-
updateShadowMap = true;
|
|
542
|
-
|
|
543
|
-
// special case, autorotation
|
|
544
|
-
if (this._renderingEngine.cameraEngine.camera) {
|
|
545
|
-
const camera = this._renderingEngine.cameraEngine.camera!;
|
|
546
|
-
if (camera.type === CAMERA_TYPE.PERSPECTIVE) {
|
|
547
|
-
const controls = <PerspectiveCameraControls>(<PerspectiveCamera>camera).controls;
|
|
548
|
-
if (controls.enableAutoRotation === true && controls.autoRotationSpeed !== 0)
|
|
549
|
-
return { showScene, rendering: true, updateShadowMap, busyMode: this._renderingEngine.busy, softShadowRendering: false };
|
|
550
|
-
}
|
|
551
|
-
} else {
|
|
552
|
-
rendering = false;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
// If the scene should be blurred
|
|
556
|
-
let busyMode = false;
|
|
557
|
-
if (this._renderingEngine.busy)
|
|
558
|
-
busyMode = true;
|
|
559
|
-
|
|
560
|
-
// If we should render in beauty mode
|
|
561
|
-
let softShadowRendering = false;
|
|
562
|
-
if (this._softShadowRenderingActive === true && busyMode === false && this._continuousRendering === false &&
|
|
563
|
-
(this._renderingEngine.shadows || !this._systemInfo.isIOS) &&
|
|
564
|
-
this._renderingEngine.usingSwiftShader === false && this._runningAnimation === false && this._renderingEngine.type !== RENDERER_TYPE.ATTRIBUTES)
|
|
565
|
-
softShadowRendering = true;
|
|
566
|
-
|
|
567
|
-
return { showScene, rendering, updateShadowMap, busyMode, softShadowRendering };
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
private setShaderProperties() {
|
|
571
|
-
if (this._renderingEngine.softShadows === false) {
|
|
572
|
-
this._renderingEngine.materialLoader.updateSoftShadow(this._lightSizeUVStart, 0);
|
|
573
|
-
return 0;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
const deltaTime = Math.min(this._softShadowRenderingDurationActive, this._renderingEngine.beautyRenderBlendingDuration);
|
|
577
|
-
const percentage = deltaTime / this._renderingEngine.beautyRenderBlendingDuration;
|
|
578
|
-
|
|
579
|
-
if (percentage < 0.25) {
|
|
580
|
-
const percentageMapped = percentage / 0.25;
|
|
581
|
-
this._renderingEngine.materialLoader.updateSoftShadow(this._lightSizeUVStart, percentageMapped);
|
|
582
|
-
|
|
583
|
-
} else {
|
|
584
|
-
const percentageMapped = (percentage - 0.25) / (1 - 0.25);
|
|
585
|
-
// this._lightSizeUVStart -> this._lightSizeUVEnd
|
|
586
|
-
this._renderingEngine.materialLoader.updateSoftShadow(this._lightSizeUVStart + (this._lightSizeUVEnd - this._lightSizeUVStart) * percentageMapped, 1.0);
|
|
587
|
-
}
|
|
588
|
-
return percentage;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
private showStatistics() {
|
|
592
|
-
if (this._renderingEngine.showStatistics) {
|
|
593
|
-
for (let i = 0; i < this._stats.stats.length; i++)
|
|
594
|
-
this._stats.stats[i].dom.style.display = '';
|
|
595
|
-
} else {
|
|
596
|
-
for (let i = 0; i < this._stats.stats.length; i++)
|
|
597
|
-
this._stats.stats[i].dom.style.display = 'none';
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
private startAndStopRendering() {
|
|
602
|
-
this._activeRendering = true;
|
|
603
|
-
this.stopBeautyRenderCountdown();
|
|
604
|
-
this.startBeautyRenderCountdown();
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
private startBeautyRenderCountdown() {
|
|
608
|
-
this._softShadowRenderingTimeout = setTimeout(() => {
|
|
609
|
-
this._softShadowRenderingActive = true;
|
|
610
|
-
this._softShadowRenderingDurationActive = 0;
|
|
611
|
-
this.activateBeautyRenderShaders();
|
|
612
|
-
}, this._renderingEngine.beautyRenderDelay);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
private startRendering() {
|
|
616
|
-
this._activeRendering = true;
|
|
617
|
-
this.stopBeautyRenderCountdown();
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
private stopBeautyRenderCountdown() {
|
|
621
|
-
if (this._softShadowRenderingTimeout)
|
|
622
|
-
clearTimeout(this._softShadowRenderingTimeout);
|
|
623
|
-
this.deactivateBeautyRenderShaders();
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
private stopRendering() {
|
|
627
|
-
this.startBeautyRenderCountdown();
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
private toggleBusyMode(toggle: boolean) {
|
|
631
|
-
if (this._renderingEngine.branding.busyModeDisplay === BUSY_MODE_DISPLAY.BLUR) {
|
|
632
|
-
this._renderingEngine.htmlElementAnchorLoader.toggleBusyMode(toggle);
|
|
633
|
-
if (toggle) {
|
|
634
|
-
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 && navigator.userAgent.toLowerCase().indexOf('android') > -1)
|
|
635
|
-
return;
|
|
636
|
-
this._renderingEngine.renderer.domElement.style.filter = 'blur(3px)';
|
|
637
|
-
} else {
|
|
638
|
-
this._renderingEngine.renderer.domElement.style.filter = '';
|
|
639
|
-
}
|
|
640
|
-
} else if (this._renderingEngine.branding.busyModeDisplay === BUSY_MODE_DISPLAY.SPINNER) {
|
|
641
|
-
if (toggle) {
|
|
642
|
-
this._renderingEngine.spinnerDivElement.style.visibility = 'visible';
|
|
643
|
-
} else {
|
|
644
|
-
this._renderingEngine.spinnerDivElement.style.visibility = 'hidden';
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
private toggleLogo(toggle: boolean) {
|
|
650
|
-
if (this._renderingEngine.logoDivElement)
|
|
651
|
-
this._renderingEngine.logoDivElement.style.display = toggle ? 'inherit' : 'none';
|
|
652
|
-
if (this._renderingEngine.canvas)
|
|
653
|
-
this._renderingEngine.canvas.style.display = !toggle ? 'inherit' : 'none';
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// #endregion Private Methods (14)
|
|
657
|
-
}
|