@p100-web/core-three 100.0.66 → 100.0.67

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.
Files changed (46) hide show
  1. package/dist/App.d.ts +2 -2
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +11 -10
  4. package/dist/App.js.map +1 -1
  5. package/dist/ThreeCanvas.d.ts +55 -0
  6. package/dist/ThreeCanvas.d.ts.map +1 -0
  7. package/dist/ThreeCanvas.js +430 -0
  8. package/dist/ThreeCanvas.js.map +1 -0
  9. package/dist/ThreeEngine.d.ts +5 -2
  10. package/dist/ThreeEngine.d.ts.map +1 -1
  11. package/dist/ThreeEngine.js +8 -3
  12. package/dist/ThreeEngine.js.map +1 -1
  13. package/dist/ThreeNodeRenderer.js +1 -1
  14. package/dist/ThreeNodeRenderer.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/media/EnvironmentLoader.js.map +1 -1
  20. package/dist/media/ImageLoader.d.ts +1 -1
  21. package/dist/media/ImageLoader.d.ts.map +1 -1
  22. package/dist/media/ModelLoader.js.map +1 -1
  23. package/dist/media/VideoLoader.d.ts +1 -1
  24. package/dist/media/VideoLoader.d.ts.map +1 -1
  25. package/dist/pcomponents/PCollider.js.map +1 -1
  26. package/dist/pcomponents/PEnvironment.d.ts +1 -1
  27. package/dist/pcomponents/PEnvironment.d.ts.map +1 -1
  28. package/dist/pcomponents/PEnvironment.js.map +1 -1
  29. package/dist/pcomponents/PModelGLTF.js.map +1 -1
  30. package/dist/pcomponents/PProjectRoot.js.map +1 -1
  31. package/dist/pcomponents/PSlider.js.map +1 -1
  32. package/dist/three/FreeCameraControls.d.ts +2 -2
  33. package/dist/three/FreeCameraControls.d.ts.map +1 -1
  34. package/dist/three/FreeCameraControls.js.map +1 -1
  35. package/dist/three/OrbitCameraControls.d.ts +2 -2
  36. package/dist/three/OrbitCameraControls.d.ts.map +1 -1
  37. package/dist/three/OrbitCameraControls.js +1 -0
  38. package/dist/three/OrbitCameraControls.js.map +1 -1
  39. package/dist/three/VrCameraControls.d.ts +2 -2
  40. package/dist/three/VrCameraControls.d.ts.map +1 -1
  41. package/dist/three/VrCameraControls.js.map +1 -1
  42. package/package.json +2 -8
  43. package/dist/PCanvas.d.ts +0 -171
  44. package/dist/PCanvas.d.ts.map +0 -1
  45. package/dist/PCanvas.js +0 -992
  46. package/dist/PCanvas.js.map +0 -1
package/dist/PCanvas.js DELETED
@@ -1,992 +0,0 @@
1
- import { Clock, Color, PerspectiveCamera, Raycaster, Scene, Vector2, WebGLRenderer, Group, MathUtils, SRGBColorSpace, } from "three";
2
- import { Group as TweenGroup } from "@tweenjs/tween.js";
3
- import ThreeJsPostProcessor from "./postprocessing/ThreeJsPostProcessor";
4
- import { PEvent, PostProcessingSystems, Workers, AdaptivePerformance, } from "@p100-web/core";
5
- const _pointer = new Vector2(-1000, -1000);
6
- const _size = new Vector2(0, 0);
7
- let _offset = 0;
8
- const _cameraColor = new Color(0x000000);
9
- const SLEEP_INTERVAL = 600;
10
- export default class PCanvas {
11
- constructor(context) {
12
- this._disposed = true;
13
- this._canvas = null;
14
- this._renderer = null;
15
- this._controls = null;
16
- // PP
17
- this._composer = null;
18
- this._updates = [];
19
- this._clock = new Clock();
20
- this._tweens = new TweenGroup();
21
- this._startHoverId = null;
22
- this._backgroundColor = new Color(0x000000);
23
- this._cameraUpdate = null;
24
- this._hoverCanvas = false;
25
- this._hoverWindow = false;
26
- this._isAdmin = false;
27
- //
28
- // BACKGROUND / ENVIRONMENT
29
- //
30
- this._environment = null;
31
- //
32
- // EXTERNAL EVENTS
33
- //
34
- this.onExternalEvent = (e) => {
35
- const event = this.context.getExternalEvent(e.detail.name);
36
- if (event) {
37
- if (PEvent.Debug) {
38
- console.log("<[EXTERNAL IN-EVENT]> [" +
39
- event.name +
40
- "] [" +
41
- e.detail.payload +
42
- "]");
43
- }
44
- event.emit(e.detail.payload);
45
- }
46
- else {
47
- this.context.error("Event not found");
48
- }
49
- };
50
- this.onMouseEnter = (_event) => {
51
- this._hoverCanvas = true;
52
- this.updateHoverState();
53
- };
54
- this.onMouseExit = (_event) => {
55
- this._hoverCanvas = false;
56
- this.updateHoverState();
57
- };
58
- //
59
- // STATS
60
- //
61
- this._stats = null;
62
- //
63
- // MOUSE
64
- //
65
- /**
66
- * Event callback when mouse moves.
67
- */
68
- this.onMouseMove = (event) => {
69
- _pointer.x = ((event.clientX - _offset) / _size.x) * 2 - 1;
70
- _pointer.y = -(event.clientY / _size.y) * 2 + 1;
71
- if (!this._hoverWindow)
72
- this.onWindowEnter();
73
- if (!this._hoverCanvas)
74
- this.onMouseEnter(event);
75
- };
76
- this._wasDown = false;
77
- /**
78
- * User pressed down on canvas
79
- */
80
- this.onCanvasClickDown = (e) => {
81
- e.preventDefault();
82
- this._wasDown = true;
83
- if (e.button === 0 && this._isRaycasting) {
84
- if (this.hovered) {
85
- this._startHoverId = this.hovered.id;
86
- }
87
- }
88
- };
89
- /**
90
- * User pressed up on canvas
91
- */
92
- this.onCanvasClickUp = (e) => {
93
- if (!this._wasDown) {
94
- return;
95
- }
96
- this._wasDown = false;
97
- e.preventDefault();
98
- if (e.button === 0 && this._isRaycasting) {
99
- const hovered = this.hovered && this.hovered.id === this._startHoverId
100
- ? this.hovered
101
- : null;
102
- if (!this._editor && hovered)
103
- hovered.collider?.native_onClick();
104
- this.context.onClick(hovered, e.ctrlKey || e.metaKey, e.shiftKey);
105
- }
106
- this._startHoverId = null;
107
- };
108
- //
109
- // RENDER LOOP
110
- //
111
- this._hasUpdators = false;
112
- // Keep track of ongoing animations
113
- this._hasTweens = false;
114
- //
115
- // Sleeping
116
- //
117
- this._isSleeping = false;
118
- this._isSleepEnabled = false;
119
- this._isHoveringAdmin = false;
120
- this.onWindowHide = () => {
121
- this._performanceCounter?.pause();
122
- };
123
- this.onWindowEnter = () => {
124
- this._hoverWindow = true;
125
- this.updateHoverState();
126
- };
127
- this.onWindowExit = () => {
128
- this._hoverWindow = false;
129
- this.updateHoverState();
130
- };
131
- //
132
- // SETTINGS
133
- //
134
- this._debug = false;
135
- //
136
- // QUALITY
137
- //
138
- this._renderScale = 1;
139
- // private _isInteracting = false;
140
- // private _interactiveReduction = false;
141
- this._maxScale = 1;
142
- this._minScale = 1;
143
- this._adaptiveQuality = false;
144
- this._estimating = false;
145
- this._baseQuality = 100;
146
- this._currentQuality = -100;
147
- this._estimatedQuality = 0;
148
- this._performanceCounter = null;
149
- //_skipFrameActive - true if we are currently dropping frames
150
- this._skipFrameActive = false;
151
- this.onPerformanceEstimated = (quality, fps, estimating) => {
152
- // console.log(
153
- // "onPerformanceEstimated() document.hidden:",
154
- // document.hidden,
155
- // quality,
156
- // Math.round(fps),
157
- // estimating
158
- // );
159
- this._estimatedQuality = quality;
160
- // Should we change quality level?
161
- if (this._adaptiveQuality) {
162
- // Did we stop estimating?
163
- if (estimating === false && this._estimating) {
164
- this.context.clearWorkFlag(Workers.AdaptivePerformance);
165
- if (this._debug)
166
- console.log("[PCanvas] onPerformanceEstimated() STOPPED", Math.round(fps), quality);
167
- }
168
- else if (estimating && !this._estimating) {
169
- this.context.setWorkFlag(Workers.AdaptivePerformance);
170
- if (this._debug)
171
- console.log("[PCanvas] onPerformanceEstimated() STARTED", Math.round(fps), quality);
172
- }
173
- if (!this._skipFrameActive && quality <= 75 && fps < 50) {
174
- this.setSkipFrameActive(true);
175
- this.setQuality(100);
176
- }
177
- else if (this._currentQuality !== quality) {
178
- this.setQuality(quality);
179
- }
180
- this._estimating = estimating;
181
- }
182
- this.snooze();
183
- };
184
- //
185
- // WORKER/INTERACTION
186
- //
187
- this._isWorking = false;
188
- this._isSceneRunning = false;
189
- //
190
- // UPDATE
191
- //
192
- this._renderCounter = 0;
193
- this._renderInterval = 2;
194
- this.update = () => {
195
- if (this._disposed) {
196
- console.log("<<<<<<<<< DISPOSED >>>>>>>>>>>");
197
- return;
198
- }
199
- if (this._hasTweens) {
200
- this._tweens.update();
201
- if (this._tweens.allStopped()) {
202
- this._tweens.removeAll();
203
- this._hasTweens = false;
204
- this.context.clearWorkFlag(Workers.Animating);
205
- }
206
- }
207
- if (this._cameraUpdate)
208
- this._cameraUpdate();
209
- const delta = this._clock.getDelta();
210
- if (this._hasUpdators) {
211
- for (const update of this._updates) {
212
- update(delta);
213
- }
214
- }
215
- if (this._isRaycasting) {
216
- this.raycast();
217
- }
218
- this._stats?.update(delta);
219
- if (this._renderCounter >= this._renderInterval) {
220
- if (this._composer)
221
- this._composer.render();
222
- else
223
- this._renderer.render(this._sceneNode, this._cameraNode);
224
- this._renderCounter = 0;
225
- }
226
- if (!this._isSleeping) {
227
- this._performanceCounter?.update(delta);
228
- }
229
- this._renderCounter++;
230
- };
231
- //
232
- // RAYCASTER
233
- //
234
- this._isRaycasting = false;
235
- this._editor = false;
236
- this.hovered = null;
237
- this.colliders = [];
238
- this.context = context;
239
- this._isAdmin = context.isAdmin();
240
- // Create a Scene
241
- const scene = new Scene();
242
- this._sceneNode = scene;
243
- this._sceneNode.background = _cameraColor;
244
- // Create a Camera
245
- const cameraNode = new PerspectiveCamera(70, 1280 / 720, 0.1, 6);
246
- this._cameraNode = cameraNode;
247
- this._cameraNode.layers.mask = 1;
248
- this._raycaster = new Raycaster();
249
- this._raycaster.layers.mask = 2;
250
- // Add root node
251
- const rootNode = new Group();
252
- this._rootNode = rootNode;
253
- // Add nodes to scene
254
- rootNode.add(cameraNode);
255
- scene.add(rootNode);
256
- }
257
- render(canvas, width, height, settings) {
258
- if (this._disposed === false)
259
- throw new Error("PCanvas was already rendered");
260
- if (canvas.dataset.rendered)
261
- throw new Error("The canvas was disposed, create a new");
262
- this._disposed = false;
263
- this._cameraNode.near = settings.renderer.near;
264
- this._cameraNode.far = settings.renderer.far;
265
- const rendererArgs = settings.postProcessing?.enabled === PostProcessingSystems.THREEJS
266
- ? {
267
- powerPreference: "high-performance",
268
- antialias: false,
269
- stencil: settings.renderer.stencil,
270
- depth: false,
271
- }
272
- : {
273
- powerPreference: "high-performance",
274
- antialias: settings.renderer.antialias,
275
- stencil: settings.renderer.stencil,
276
- depth: settings.renderer.depth,
277
- };
278
- const renderer = new WebGLRenderer({
279
- ...rendererArgs,
280
- canvas: canvas,
281
- });
282
- renderer.outputColorSpace = SRGBColorSpace;
283
- _size.x = width;
284
- _size.y = height;
285
- this._renderer = renderer;
286
- this._canvas = canvas;
287
- // if (settings.postProcessing?.enabled === PostProcessingSystems.PMNDRS) {
288
- // renderer.toneMapping = NoToneMapping;
289
- // } else {
290
- renderer.toneMapping = settings.renderer.toneMapping;
291
- renderer.toneMappingExposure = settings.renderer.toneMappingExposure;
292
- // }
293
- this.setupShadows(settings.renderer.useShadows);
294
- renderer.setSize(_size.x, _size.y, true);
295
- renderer.setClearColor(_cameraColor);
296
- renderer.clear();
297
- if (settings.postProcessing?.enabled === PostProcessingSystems.THREEJS) {
298
- this.setupPostProcessing(settings.postProcessing);
299
- }
300
- if (!this._cameraNode)
301
- throw new Error("Missing camera");
302
- this._cameraNode.aspect = width / height;
303
- this._cameraNode.updateProjectionMatrix();
304
- document.addEventListener("mouseenter", this.onWindowEnter);
305
- document.addEventListener("mouseleave", this.onWindowExit);
306
- document.addEventListener("visibilitychange", this.onWindowHide);
307
- canvas.addEventListener("pointermove", this.onMouseMove);
308
- canvas.addEventListener("mouseenter", this.onMouseEnter);
309
- canvas.addEventListener("mouseleave", this.onMouseExit);
310
- canvas.addEventListener("pointerdown", this.onCanvasClickDown);
311
- canvas.addEventListener("pointerup", this.onCanvasClickUp);
312
- canvas.addEventListener("p100-in-event", this.onExternalEvent);
313
- this.startRenderLoop();
314
- }
315
- /**
316
- * Should be called after render() and restore()
317
- */
318
- init(settings) {
319
- // Set FOV
320
- this.setFOV(settings.renderer.fov);
321
- this._cameraNode.fov = settings.renderer.fov;
322
- this._cameraNode.updateProjectionMatrix();
323
- // Set background color
324
- this.setBackgroundColor(settings.renderer.background);
325
- // Work quality
326
- if (settings.quality) {
327
- this.initQualitySettings(settings.quality);
328
- }
329
- }
330
- restore(canvas, settings) {
331
- this.render(canvas, _size.width, _size.height, settings);
332
- }
333
- disable() { }
334
- dispose() {
335
- // console.log("[PCanvas] DISPOSE()");
336
- if (this._disposed === true)
337
- throw new Error("PCanvas was already disposed");
338
- this.stopRenderLoop();
339
- this._disposed = true;
340
- if (this._adaptiveQuality) {
341
- this._performanceCounter?.dispose();
342
- this.context.clearWorkFlag(Workers.AdaptivePerformance);
343
- }
344
- if (this._controls) {
345
- this._controls.dispose();
346
- this._controls = null;
347
- }
348
- const renderer = this._renderer;
349
- const canvas = this._canvas;
350
- if (!canvas)
351
- throw new Error("Missing canvas");
352
- document.removeEventListener("mouseenter", this.onWindowEnter);
353
- document.removeEventListener("mouseleave", this.onWindowExit);
354
- document.removeEventListener("visibilitychange", this.onWindowHide);
355
- canvas.removeEventListener("pointermove", this.onMouseMove);
356
- canvas.removeEventListener("mouseenter", this.onMouseEnter);
357
- canvas.removeEventListener("mouseleave", this.onMouseExit);
358
- canvas.removeEventListener("pointerdown", this.onCanvasClickDown);
359
- canvas.removeEventListener("pointerup", this.onCanvasClickUp);
360
- canvas.removeEventListener("p100-in-event", this.onExternalEvent);
361
- canvas.dataset.rendered = "true";
362
- if (this._composer !== null) {
363
- this._composer.dispose();
364
- }
365
- renderer.dispose();
366
- renderer.forceContextLoss();
367
- this._renderer = null;
368
- this._composer?.dispose();
369
- this._composer = null;
370
- }
371
- enable() {
372
- if (this._renderer) {
373
- // this._renderer.shadowMap.needsUpdate = true;
374
- }
375
- }
376
- getComposer() {
377
- return this._composer;
378
- }
379
- getEnvironment() {
380
- return this._environment;
381
- }
382
- setEnvironment(environment) {
383
- if (this._environment !== null) {
384
- this.context.error("Already had an environment");
385
- return;
386
- }
387
- this._environment = environment;
388
- this.updateEnvironment();
389
- }
390
- updateEnvironment() {
391
- if (this._environment === null) {
392
- }
393
- else {
394
- const scene = this._sceneNode;
395
- if (this._environment.environment) {
396
- scene.environment = this._environment.getTexture();
397
- scene.environmentRotation.y = MathUtils.degToRad(180 + this._environment.rotation);
398
- scene.environmentIntensity = this._environment.intensity;
399
- }
400
- else if (scene.environment === this._environment.getTexture()) {
401
- scene.environment = null;
402
- }
403
- if (this._environment.background) {
404
- scene.background = this._environment.getTexture();
405
- scene.backgroundRotation.y = MathUtils.degToRad(180 + this._environment.rotation);
406
- scene.backgroundIntensity = this._environment.intensity;
407
- }
408
- else if (scene.background === this._environment.getTexture()) {
409
- scene.background = null;
410
- scene.background = this._backgroundColor;
411
- }
412
- }
413
- }
414
- setBackgroundColor(bg) {
415
- this._backgroundColor = new Color(bg);
416
- const current = this._sceneNode.background;
417
- if (current && current.isColor) {
418
- this._sceneNode.background = this._backgroundColor;
419
- }
420
- }
421
- clearEnvironment(environment) {
422
- const scene = this._sceneNode;
423
- if (this._environment !== environment) {
424
- this.context.error("Clear environment called with invalid PEnvironment");
425
- return;
426
- }
427
- if (this._environment === null) {
428
- this.context.error("No environtment");
429
- return;
430
- }
431
- if (this._environment.environment) {
432
- scene.environment = null;
433
- }
434
- if (this._environment.background) {
435
- scene.background = null;
436
- scene.background = this._backgroundColor;
437
- }
438
- this._environment = null;
439
- }
440
- //
441
- // RENDERER
442
- //
443
- setToneMapping(value) {
444
- this._renderer.toneMapping = value;
445
- }
446
- setToneMappingExposure(value) {
447
- this._renderer.toneMappingExposure = value;
448
- }
449
- setFOV(fov) {
450
- this._cameraNode.fov = fov;
451
- this._cameraNode.updateProjectionMatrix();
452
- }
453
- setNearFar(near = -1, far = -1) {
454
- if (near > 0)
455
- this._cameraNode.near = near;
456
- if (far > 0)
457
- this._cameraNode.far = far;
458
- this._cameraNode.updateProjectionMatrix();
459
- }
460
- //
461
- // SHADOWS
462
- //
463
- setupShadows(value) {
464
- const renderer = this._renderer;
465
- if (value > 0) {
466
- // Enable
467
- renderer.shadowMap.autoUpdate = false;
468
- console.log("TODO: manual shadows");
469
- renderer.shadowMap.enabled = true;
470
- renderer.shadowMap.type = (value - 1);
471
- renderer.shadowMap.needsUpdate = true;
472
- }
473
- else {
474
- // Disable
475
- renderer.shadowMap.enabled = false;
476
- renderer.shadowMap.needsUpdate = true;
477
- renderer.shadowMap.autoUpdate = false;
478
- }
479
- renderer.clear();
480
- }
481
- //
482
- // CONTROLS
483
- //
484
- getCameraNode() {
485
- return this._cameraNode;
486
- }
487
- setCameraControls(controls) {
488
- if (this._controls) {
489
- this._controls.dispose();
490
- }
491
- this._controls = controls;
492
- }
493
- getCameraControls() {
494
- return this._controls;
495
- }
496
- //
497
- // POST PROCESSING
498
- //
499
- setupPostProcessing(settings) {
500
- // if (settings.enabled === PostProcessingSystems.PMNDRS) {
501
- // // this._composer = new PmndrsPostProcessor(
502
- // // settings,
503
- // // this._sceneNode,
504
- // // this._renderer!,
505
- // // this._cameraNode,
506
- // // _size
507
- // // );
508
- // } else if (settings.enabled === PostProcessingSystems.THREEJS) {
509
- this._composer = new ThreeJsPostProcessor(settings, this._sceneNode, this._renderer, this._cameraNode, _size);
510
- // }
511
- }
512
- /**
513
- * Base settings has changed for post processing
514
- */
515
- updatePostProcessingSettings(field, settings) {
516
- if (this._composer === null)
517
- return;
518
- // Note: If we are updating all, then we will restart the context really soon
519
- if (field === "postProcessing.samples") {
520
- this._composer.updateAASamples(settings.samples);
521
- }
522
- else {
523
- const needsResize = this._composer?.updatePostProcessing(settings, field);
524
- if (needsResize) {
525
- this._composer.resizeEffects();
526
- }
527
- }
528
- }
529
- //
530
- // DOM
531
- //
532
- /**
533
- * Helper function to trigger events
534
- */
535
- emit(type, detail, bubbles) {
536
- if (this._canvas !== null) {
537
- this._canvas.dispatchEvent(new CustomEvent(type, {
538
- bubbles: bubbles,
539
- detail: detail,
540
- }));
541
- }
542
- }
543
- /**
544
- * Add <canvas/> event listener
545
- */
546
- addEventListener(type, callback) {
547
- this._canvas.addEventListener(type, callback);
548
- }
549
- /**
550
- * Add <canvas/> event listener
551
- */
552
- removeEventListener(type, callback) {
553
- this._canvas.removeEventListener(type, callback);
554
- }
555
- registerStats(updator) {
556
- this._stats = updator;
557
- }
558
- //
559
- // WINDOW
560
- //
561
- /**
562
- * Return mouse position
563
- */
564
- getPointer() {
565
- return this._hoverCanvas ? _pointer : null;
566
- }
567
- getSize() {
568
- return _size;
569
- }
570
- onWindowResize(width, height, resize) {
571
- if (this._canvas) {
572
- _offset = this._canvas.getBoundingClientRect().x;
573
- }
574
- _size.x = width;
575
- _size.y = height;
576
- this._renderer?.setSize(width, height, true);
577
- if (this._composer !== null) {
578
- if (resize)
579
- this._composer.resize(width, height);
580
- else
581
- this._composer.setSize(width, height);
582
- }
583
- this.snooze();
584
- if (this._cameraNode !== null) {
585
- this._cameraNode.aspect = width / height;
586
- this._cameraNode.updateProjectionMatrix();
587
- }
588
- if (this._isSleepEnabled) {
589
- this._renderCounter = this._currentQuality;
590
- }
591
- }
592
- //
593
- // THREE NODES
594
- //
595
- getThreeSceneNode() {
596
- return this._sceneNode;
597
- }
598
- getThreeRenderer() {
599
- return this._renderer;
600
- }
601
- getCanvasElement() {
602
- return this._canvas;
603
- }
604
- getThreeRootNode() {
605
- return this._rootNode;
606
- }
607
- getThreeCamera() {
608
- return this._cameraNode;
609
- }
610
- registerUpdate(f) {
611
- const oldCount = this._updates.length;
612
- this._updates = [...this._updates, f];
613
- this._hasUpdators = this._updates.length > 0;
614
- if (oldCount === 0 && this._hasUpdators) {
615
- this.context.setWorkFlag(Workers.Updators);
616
- }
617
- }
618
- unregisterUpdate(f) {
619
- this._updates = this._updates.filter((u) => u !== f);
620
- this._hasUpdators = this._updates.length > 0;
621
- if (!this._hasUpdators) {
622
- this.context.clearWorkFlag(Workers.Updators);
623
- }
624
- }
625
- startRenderLoop() {
626
- if (!this._renderer)
627
- throw new Error("No renderer");
628
- // Start rendering
629
- this._renderer.setAnimationLoop(this.update);
630
- }
631
- stopRenderLoop() {
632
- if (!this._renderer)
633
- throw new Error("No renderer");
634
- // Stop rendering
635
- this._renderer.setAnimationLoop(null);
636
- }
637
- addTween(tween) {
638
- const didHaveTweens = this._hasTweens;
639
- this._hasTweens = true;
640
- this._tweens.add(tween);
641
- if (!didHaveTweens && this._hasTweens) {
642
- this.context.setWorkFlag(Workers.Animating);
643
- }
644
- }
645
- setCameraUpdate(updateFunction) {
646
- this._cameraUpdate = updateFunction;
647
- }
648
- updateHoverState() {
649
- const isHoveringAdmin = this._isAdmin && this._hoverWindow && !this._hoverCanvas;
650
- if (isHoveringAdmin !== this._isHoveringAdmin) {
651
- if (isHoveringAdmin) {
652
- this._isHoveringAdmin = true;
653
- this.context.setWorkFlag(Workers.Admin);
654
- }
655
- else {
656
- this._isHoveringAdmin = false;
657
- this.context.clearWorkFlag(Workers.Admin);
658
- }
659
- }
660
- }
661
- isSleepEnabled() {
662
- return this._isSleepEnabled;
663
- }
664
- setIsSleepEnabled(value) {
665
- if (this._isSceneRunning)
666
- this._renderInterval = this._skipFrameActive ? 2 : 1;
667
- this._isSleepEnabled = value;
668
- this.updateHoverState();
669
- if (!value) {
670
- this._isSleeping = false;
671
- this.context.getOwner().setSleepState(false);
672
- }
673
- }
674
- snooze() {
675
- this._renderCounter = this._renderInterval;
676
- }
677
- updateRendererSettings(field, isettings) {
678
- const settings = isettings.renderer;
679
- if (field === "renderer" || field === "renderer.fov") {
680
- this.setFOV(settings.fov);
681
- }
682
- if (field === "renderer" ||
683
- field === "renderer.near" ||
684
- field === "renderer.far") {
685
- this.setNearFar(settings.near, settings.far);
686
- }
687
- if (field === "renderer" || field === "renderer.toneMapping") {
688
- this.setToneMapping(settings.toneMapping);
689
- }
690
- if (field === "renderer" || field === "renderer.toneMappingExposure") {
691
- this.setToneMappingExposure(settings.toneMappingExposure);
692
- }
693
- }
694
- updateQualitySettings(field, isettings) {
695
- const settings = isettings.quality;
696
- if (field === "quality" || field === "quality.sleep") {
697
- this.setIsSleepEnabled(settings.sleep);
698
- }
699
- if (field === "quality" || field === "quality.adaptive") {
700
- this.setIsAdaptiveQualityEnabled(settings);
701
- this.updateSkipFrameState(settings);
702
- }
703
- if (field === "quality" || field === "quality.minScale") {
704
- this._minScale = settings.minScale;
705
- this.updateRenderScale(false);
706
- }
707
- if (field === "quality" || field === "quality.maxScale") {
708
- this._maxScale = settings.maxScale;
709
- this.updateRenderScale(false);
710
- }
711
- if (field === "quality" || field === "quality.baseQuality") {
712
- this._baseQuality = settings.baseQuality;
713
- if (!this._adaptiveQuality) {
714
- this._estimatedQuality = this._baseQuality;
715
- }
716
- this.setQuality(this._baseQuality);
717
- }
718
- if (field === "quality" || field === "quality.skipFrame") {
719
- this.updateSkipFrameState(settings);
720
- }
721
- if (field === "quality" || field === "quality.debug") {
722
- this._debug = settings.debug;
723
- if (this._performanceCounter)
724
- this._performanceCounter.debug = settings.debug;
725
- }
726
- }
727
- initQualitySettings(settings) {
728
- this.setIsSleepEnabled(settings.sleep);
729
- this._maxScale = settings.maxScale;
730
- this._minScale = settings.minScale;
731
- this._baseQuality = settings.baseQuality;
732
- this._debug = settings.debug;
733
- this.setIsAdaptiveQualityEnabled(settings);
734
- this.updateSkipFrameState(settings);
735
- }
736
- getRenderScale() {
737
- return this._renderScale;
738
- }
739
- getCurrentQuality() {
740
- return this._currentQuality;
741
- }
742
- getEstimatedQuality() {
743
- return this._estimatedQuality;
744
- }
745
- getRenderInterval() {
746
- return this._renderInterval;
747
- }
748
- updateSkipFrameState(settings) {
749
- // Skip frame is automatically handled if we are in adaptive mode
750
- if (this._adaptiveQuality) {
751
- // Adaptive Quality
752
- this._skipFrameActive = false;
753
- if (this._isSceneRunning)
754
- this._renderInterval = 1;
755
- }
756
- else {
757
- // Manual Quality
758
- this.setSkipFrameActive(settings.skipFrame);
759
- }
760
- }
761
- setSkipFrameActive(value) {
762
- if (value) {
763
- // Turn on
764
- this._skipFrameActive = true;
765
- if (this._isSceneRunning)
766
- this._renderInterval = 2;
767
- if (this._debug)
768
- console.log("[PCanvas] Skip Frame ON", this._renderInterval);
769
- }
770
- else {
771
- this._skipFrameActive = false;
772
- if (this._isSceneRunning)
773
- this._renderInterval = 1;
774
- // Turn off
775
- if (this._debug)
776
- console.log("[PCanvas] Skip Frame OFF", this._renderInterval);
777
- }
778
- }
779
- setIsAdaptiveQualityEnabled(settings) {
780
- this._adaptiveQuality = settings.adaptive;
781
- this._estimating = this._adaptiveQuality;
782
- if (settings.adaptive) {
783
- this._estimatedQuality = 100;
784
- this.setQuality(this._estimatedQuality);
785
- this._performanceCounter = new AdaptivePerformance(this.onPerformanceEstimated);
786
- this._performanceCounter.debug = settings.debug;
787
- this.context.setWorkFlag(Workers.AdaptivePerformance);
788
- if (this._isSceneRunning) {
789
- this._performanceCounter.init(this._currentQuality);
790
- }
791
- }
792
- else {
793
- this._performanceCounter?.dispose();
794
- this._performanceCounter = null;
795
- this._estimatedQuality = this._baseQuality;
796
- this.setQuality(this._baseQuality);
797
- this.context.clearWorkFlag(Workers.AdaptivePerformance);
798
- }
799
- }
800
- /**
801
- * Quality is always clamped to steps of 0.05
802
- */
803
- setQuality(quality) {
804
- if (this._currentQuality !== quality) {
805
- this._performanceCounter?.setCurrentQuality(quality);
806
- this._currentQuality = quality;
807
- //
808
- // POST PROCESSING
809
- const resizePostProcessing = this._composer?.setCurrentQuality(quality) || false;
810
- //
811
- // RENDER SCALE
812
- this.updateRenderScale(resizePostProcessing);
813
- }
814
- }
815
- updateRenderScale(forced) {
816
- const qualityScale = MathUtils.lerp(this._minScale, this._maxScale, this._currentQuality * 0.01);
817
- const newScale = Math.min(Math.max(qualityScale, this._minScale), this._maxScale);
818
- const resizePixelRatio = Math.abs(this._renderScale - newScale) >= 0.01;
819
- if (forced || resizePixelRatio) {
820
- if (resizePixelRatio) {
821
- // console.log(
822
- // "[PCanvas] Change PixelRatio [",
823
- // this._renderScale.toFixed(2),
824
- // "] -> [",
825
- // newScale.toFixed(2),
826
- // "]"
827
- // );
828
- this._renderScale = newScale;
829
- }
830
- if (this._composer) {
831
- this._composer.setPixelRatio(this._renderScale);
832
- this.snooze();
833
- }
834
- else {
835
- this._renderer.setPixelRatio(this._renderScale);
836
- this.snooze();
837
- }
838
- }
839
- }
840
- onSceneRunning() {
841
- if (this._debug)
842
- console.log("[PCanvas] onSceneRunning()");
843
- this._isSceneRunning = true;
844
- this._renderInterval = this._skipFrameActive ? 2 : 1;
845
- if (this._adaptiveQuality) {
846
- this._performanceCounter.init(this._currentQuality);
847
- }
848
- else {
849
- this.sleepCheck();
850
- }
851
- }
852
- onWorkStarted(_workers) {
853
- this._isWorking = true;
854
- // if (this._debug)
855
- // console.log("[PCanvas] onWorkStarted()", Workers[_workers]);
856
- if (this._isSleepEnabled && this._isSleeping) {
857
- this._isSleeping = false;
858
- this._renderInterval = this._skipFrameActive ? 2 : 1;
859
- this.setQuality(this._estimatedQuality);
860
- this.context.getOwner().setSleepState(false);
861
- }
862
- }
863
- onWorkStopped(_workers) {
864
- this._isWorking = false;
865
- // if (this._debug)
866
- // console.log("[PCanvas] onWorkStopped: ", Workers[_workers]);
867
- // Do we need to change sleep state?
868
- this.sleepCheck();
869
- }
870
- sleepCheck() {
871
- if (this._isSleepEnabled && !this._isSleeping && !this._isWorking) {
872
- this.sleep();
873
- }
874
- }
875
- sleep() {
876
- // if (this._debug) console.log("[PCanvas] sleep()");
877
- // This will force one last render
878
- this._isSleeping = true;
879
- this._renderInterval = SLEEP_INTERVAL;
880
- this.setQuality(Math.min(100, this._estimatedQuality + 50));
881
- this.context.getOwner().setSleepState(true);
882
- this.snooze();
883
- }
884
- addCollider(object) {
885
- this.colliders.push(object);
886
- }
887
- removeCollider(object) {
888
- const index = this.colliders.indexOf(object);
889
- if (index >= 0) {
890
- this.colliders.splice(index, 1);
891
- }
892
- }
893
- getRaycaster() {
894
- return this._raycaster;
895
- }
896
- enableRaycaster() {
897
- this._isRaycasting = true;
898
- this.hovered = null;
899
- this._startHoverId = null;
900
- if (!this._rootNode) {
901
- console.error("Warning: no root node!");
902
- }
903
- }
904
- disableRaycaster() {
905
- this._isRaycasting = false;
906
- this._startHoverId = null;
907
- if (this.hovered) {
908
- // console.log("disableRaycaster() while hovered");
909
- this.setHovered(null, null);
910
- }
911
- }
912
- updateEditorMode(editor) {
913
- this._editor = editor;
914
- }
915
- raycast() {
916
- const raycaster = this._raycaster;
917
- // Get pointer, null if outside canvas
918
- const pointer = this.getPointer();
919
- if (pointer !== null) {
920
- raycaster.setFromCamera(pointer, this._cameraNode);
921
- const intersects = raycaster.intersectObjects(this.colliders, false);
922
- this.onHover(intersects.length > 0 ? intersects : null);
923
- }
924
- else {
925
- this.onHover(null);
926
- }
927
- }
928
- /**
929
- * Set current hovered object.
930
- */
931
- setHovered(node, point) {
932
- const hovered = this.hovered;
933
- if (node === null) {
934
- // Skip if nothing is hovered
935
- if (hovered === null) {
936
- return;
937
- }
938
- this.snooze();
939
- this.hovered = null;
940
- // EventSystem.emit("hover-exit", hovered.id, hovered.id, DataType.Node);
941
- this.context.onHoverExit(hovered);
942
- if (!this._editor) {
943
- hovered.collider?.native_onHoverExit();
944
- }
945
- }
946
- else {
947
- // Skip if already hovered
948
- if (hovered === node) {
949
- // if (!this._editor && node.collider?.native_onHover) {
950
- // node.collider.native_onHover(point);
951
- // }
952
- return;
953
- }
954
- this.snooze();
955
- // Did we have something hovered?
956
- if (hovered) {
957
- this.setHovered(null, null);
958
- }
959
- this.hovered = node;
960
- this.context.onHoverEnter(node);
961
- if (!this._editor) {
962
- this.hovered?.collider?.native_onHoverEnter(point);
963
- }
964
- }
965
- }
966
- /**
967
- * User hovers collider
968
- */
969
- onHover(intersects) {
970
- let object3D = null;
971
- let distance = 999999;
972
- let point = null;
973
- if (intersects !== null) {
974
- for (const intersect of intersects) {
975
- // Check that we hover a valid target
976
- if (intersect.object.visible && intersect.distance < distance) {
977
- object3D = intersect.object;
978
- distance = intersect.distance;
979
- point = intersect.point;
980
- }
981
- }
982
- }
983
- if (object3D === null) {
984
- this.setHovered(null, null);
985
- return;
986
- }
987
- const collider = object3D.collider || object3D.userData.collider;
988
- if (collider)
989
- this.setHovered(collider.node, point);
990
- }
991
- }
992
- //# sourceMappingURL=PCanvas.js.map