@needle-tools/engine 2.50.0-pre → 2.52.0-pre

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 (132) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/needle-engine.d.ts +74 -36
  3. package/dist/needle-engine.js +588 -3662
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +24 -25
  6. package/dist/needle-engine.min.js.map +4 -4
  7. package/lib/engine/engine_addressables.d.ts +1 -1
  8. package/lib/engine/engine_create_objects.d.ts +1 -1
  9. package/lib/engine/engine_element.d.ts +5 -4
  10. package/lib/engine/engine_element.js.map +1 -1
  11. package/lib/engine/engine_element_overlay.d.ts +3 -2
  12. package/lib/engine/engine_element_overlay.js.map +1 -1
  13. package/lib/engine/engine_input.js +15 -9
  14. package/lib/engine/engine_input.js.map +1 -1
  15. package/lib/engine/engine_physics.d.ts +1 -1
  16. package/lib/engine/engine_physics.js +1 -1
  17. package/lib/engine/engine_physics.js.map +1 -1
  18. package/lib/engine/engine_scenetools.d.ts +1 -1
  19. package/lib/engine/engine_serialization_core.d.ts +1 -1
  20. package/lib/engine/engine_setup.d.ts +2 -1
  21. package/lib/engine/engine_setup.js +28 -5
  22. package/lib/engine/engine_setup.js.map +1 -1
  23. package/lib/engine/engine_three_utils.d.ts +1 -0
  24. package/lib/engine/engine_three_utils.js +6 -0
  25. package/lib/engine/engine_three_utils.js.map +1 -1
  26. package/lib/engine/engine_types.d.ts +10 -9
  27. package/lib/engine/engine_utils.d.ts +3 -1
  28. package/lib/engine/engine_utils.js +9 -0
  29. package/lib/engine/engine_utils.js.map +1 -1
  30. package/lib/engine/extensions/NEEDLE_components.js +15 -11
  31. package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
  32. package/lib/engine/extensions/NEEDLE_deferred_texture.js +4 -3
  33. package/lib/engine/extensions/NEEDLE_deferred_texture.js.map +1 -1
  34. package/lib/engine/extensions/NEEDLE_lighting_settings.d.ts +1 -1
  35. package/lib/engine-components/Camera.d.ts +8 -2
  36. package/lib/engine-components/Camera.js +39 -2
  37. package/lib/engine-components/Camera.js.map +1 -1
  38. package/lib/engine-components/Component.d.ts +2 -1
  39. package/lib/engine-components/DragControls.js +10 -4
  40. package/lib/engine-components/DragControls.js.map +1 -1
  41. package/lib/engine-components/EventTrigger.d.ts +10 -1
  42. package/lib/engine-components/EventTrigger.js +47 -0
  43. package/lib/engine-components/EventTrigger.js.map +1 -1
  44. package/lib/engine-components/Light.js +20 -20
  45. package/lib/engine-components/Light.js.map +1 -1
  46. package/lib/engine-components/OrbitControls.js +19 -14
  47. package/lib/engine-components/OrbitControls.js.map +1 -1
  48. package/lib/engine-components/ParticleSystemModules.js +0 -1
  49. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  50. package/lib/engine-components/Renderer.d.ts +1 -0
  51. package/lib/engine-components/Renderer.js +10 -3
  52. package/lib/engine-components/Renderer.js.map +1 -1
  53. package/lib/engine-components/RigidBody.js +13 -1
  54. package/lib/engine-components/RigidBody.js.map +1 -1
  55. package/lib/engine-components/ScreenCapture.js +2 -0
  56. package/lib/engine-components/ScreenCapture.js.map +1 -1
  57. package/lib/engine-components/ShadowCatcher.js +5 -6
  58. package/lib/engine-components/ShadowCatcher.js.map +1 -1
  59. package/lib/engine-components/Skybox.d.ts +1 -0
  60. package/lib/engine-components/Skybox.js +5 -0
  61. package/lib/engine-components/Skybox.js.map +1 -1
  62. package/lib/engine-components/SpriteRenderer.d.ts +19 -3
  63. package/lib/engine-components/SpriteRenderer.js +154 -41
  64. package/lib/engine-components/SpriteRenderer.js.map +1 -1
  65. package/lib/engine-components/VideoPlayer.js +2 -1
  66. package/lib/engine-components/VideoPlayer.js.map +1 -1
  67. package/lib/engine-components/WebARSessionRoot.d.ts +2 -2
  68. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  69. package/lib/engine-components/WebXR.d.ts +2 -1
  70. package/lib/engine-components/WebXR.js +5 -2
  71. package/lib/engine-components/WebXR.js.map +1 -1
  72. package/lib/engine-components/WebXRAvatar.d.ts +1 -1
  73. package/lib/engine-components/WebXRAvatar.js +6 -1
  74. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  75. package/lib/engine-components/WebXRController.d.ts +2 -1
  76. package/lib/engine-components/WebXRController.js +3 -2
  77. package/lib/engine-components/WebXRController.js.map +1 -1
  78. package/lib/engine-components/WebXRRig.js +12 -0
  79. package/lib/engine-components/WebXRRig.js.map +1 -1
  80. package/lib/engine-components/WebXRSync.js +5 -0
  81. package/lib/engine-components/WebXRSync.js.map +1 -1
  82. package/lib/engine-components/XRFlag.js +6 -6
  83. package/lib/engine-components/XRFlag.js.map +1 -1
  84. package/lib/engine-components/codegen/components.d.ts +1 -0
  85. package/lib/engine-components/codegen/components.js +1 -0
  86. package/lib/engine-components/codegen/components.js.map +1 -1
  87. package/lib/engine-components/js-extensions/Vector.js +2 -5
  88. package/lib/engine-components/js-extensions/Vector.js.map +1 -1
  89. package/lib/engine-components/timeline/PlayableDirector.d.ts +1 -1
  90. package/lib/engine-components/timeline/PlayableDirector.js +7 -5
  91. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  92. package/lib/engine-components/ui/EventSystem.d.ts +2 -1
  93. package/lib/engine-components/ui/EventSystem.js +9 -1
  94. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  95. package/lib/engine-components/ui/Utils.d.ts +1 -1
  96. package/package.json +2 -4
  97. package/src/engine/codegen/register_types.js +2 -0
  98. package/src/engine/engine_element.ts +5 -5
  99. package/src/engine/engine_element_overlay.ts +2 -2
  100. package/src/engine/engine_input.ts +12 -8
  101. package/src/engine/engine_physics.ts +1 -1
  102. package/src/engine/engine_setup.ts +25 -6
  103. package/src/engine/engine_three_utils.ts +7 -0
  104. package/src/engine/engine_types.ts +3 -3
  105. package/src/engine/engine_utils.ts +13 -2
  106. package/src/engine/extensions/NEEDLE_components.ts +13 -9
  107. package/src/engine/extensions/NEEDLE_deferred_texture.ts +9 -6
  108. package/src/engine-components/Camera.ts +36 -2
  109. package/src/engine-components/Component.ts +1 -1
  110. package/src/engine-components/DragControls.ts +8 -4
  111. package/src/engine-components/EventTrigger.ts +39 -19
  112. package/src/engine-components/Light.ts +18 -16
  113. package/src/engine-components/OrbitControls.ts +19 -14
  114. package/src/engine-components/ParticleSystemModules.ts +0 -3
  115. package/src/engine-components/Renderer.ts +10 -4
  116. package/src/engine-components/RigidBody.ts +13 -1
  117. package/src/engine-components/ScreenCapture.ts +1 -0
  118. package/src/engine-components/ShadowCatcher.ts +5 -6
  119. package/src/engine-components/Skybox.ts +4 -0
  120. package/src/engine-components/SpriteRenderer.ts +140 -44
  121. package/src/engine-components/VideoPlayer.ts +2 -1
  122. package/src/engine-components/WebARSessionRoot.ts +1 -2
  123. package/src/engine-components/WebXR.ts +5 -3
  124. package/src/engine-components/WebXRAvatar.ts +6 -1
  125. package/src/engine-components/WebXRController.ts +4 -3
  126. package/src/engine-components/WebXRRig.ts +14 -1
  127. package/src/engine-components/WebXRSync.ts +6 -1
  128. package/src/engine-components/XRFlag.ts +7 -6
  129. package/src/engine-components/codegen/components.ts +1 -0
  130. package/src/engine-components/js-extensions/Vector.ts +2 -5
  131. package/src/engine-components/timeline/PlayableDirector.ts +6 -4
  132. package/src/engine-components/ui/EventSystem.ts +12 -1
@@ -53,15 +53,19 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
53
53
  // the write node callback is called after user data is serialized
54
54
  // we could also traverse everything before export and remove components
55
55
  // but doing it like that we avoid traversing multiple times
56
- const originalFunction = writer.serializeUserData.bind(writer);
57
- this.writer = writer;
58
- writer.serializeUserData = (o, def) => {
59
- try {
60
- this.serializeUserData(o, def);
61
- originalFunction(o, def);
62
- }
63
- finally {
64
- this.afterSerializeUserData(o, def);
56
+ if("serializeUserData" in writer){
57
+ //@ts-ignore
58
+ const originalFunction = writer.serializeUserData.bind(writer);
59
+ this.writer = writer;
60
+ //@ts-ignore
61
+ writer.serializeUserData = (o, def) => {
62
+ try {
63
+ this.serializeUserData(o, def);
64
+ originalFunction(o, def);
65
+ }
66
+ finally {
67
+ this.afterSerializeUserData(o, def);
68
+ }
65
69
  }
66
70
  }
67
71
  return this;
@@ -40,17 +40,19 @@ export class NEEDLE_deferred_texture implements GLTFLoaderPlugin {
40
40
 
41
41
  static assignTextureLOD(context: Context, source: SourceIdentifier | undefined, material: Material, level: number = 0) {
42
42
  if (!material) return;
43
- for (const slot of Object.keys(material)) {
43
+ for (let slot of Object.keys(material)) {
44
44
  const val = material[slot];
45
45
  if (val?.isTexture === true) {
46
- if (debug)
47
- console.log("-----------\n", "FIND", material.name, slot, val?.name, val?.userData, val);
46
+
47
+ if (debug) console.log("-----------\n", "FIND", material.name, slot, val?.name, val?.userData, val, material);
48
+
48
49
  NEEDLE_deferred_texture.getOrLoadTexture(context, source, material, slot, val, level).then(t => {
49
50
  if (t?.isTexture === true) {
50
- t.needsUpdate = true;
51
- if (debug)
52
- console.log("Assign LOD", material.name, slot, t.name, t["guid"], material, "Prev:", val, "Now:", t, "\n--------------");
51
+
52
+ if (debug) console.log("Assign LOD", material.name, slot, t.name, t["guid"], material, "Prev:", val, "Now:", t, "\n--------------");
53
+
53
54
  material[slot] = t;
55
+ t.needsUpdate = true;
54
56
  material.needsUpdate = true;
55
57
 
56
58
  if (debug) {
@@ -174,6 +176,7 @@ export class NEEDLE_deferred_texture implements GLTFLoaderPlugin {
174
176
 
175
177
  // const index = Number.parseInt(ext.pointer.substring("textures/".length));
176
178
  const tex = await parser.getDependency("texture", index);
179
+ tex.encoding = current.encoding;
177
180
  if (tex) {
178
181
  tex.guid = ext.guid;
179
182
  }
@@ -52,6 +52,7 @@ export class Camera extends Behaviour implements ICamera {
52
52
  this._cam.updateProjectionMatrix();
53
53
  }
54
54
  }
55
+ private _nearClipPlane: number = 0.1;
55
56
 
56
57
  get farClipPlane(): number { return this._farClipPlane; }
57
58
  @serializable()
@@ -63,6 +64,7 @@ export class Camera extends Behaviour implements ICamera {
63
64
  this._cam.updateProjectionMatrix();
64
65
  }
65
66
  }
67
+ private _farClipPlane: number = 1000;
66
68
 
67
69
  @serializable()
68
70
  public get clearFlags(): ClearFlags {
@@ -94,8 +96,33 @@ export class Camera extends Behaviour implements ICamera {
94
96
  }
95
97
  private _cullingMask: number = 0xffffffff;
96
98
 
97
- private _nearClipPlane: number = 0.1;
98
- private _farClipPlane: number = 1000;
99
+ @serializable()
100
+ public set backgroundBlurriness(val: number | undefined) {
101
+ if(val === this._backgroundBlurriness) return;
102
+ if (val === undefined)
103
+ this._backgroundBlurriness = undefined;
104
+ else
105
+ this._backgroundBlurriness = Math.min(Math.max(val, 0), 1);
106
+ this.applyClearFlagsIfIsActiveCamera();
107
+ }
108
+ public get backgroundBlurriness() : number | undefined {
109
+ return this._backgroundBlurriness;
110
+ }
111
+ private _backgroundBlurriness?: number;
112
+
113
+ @serializable()
114
+ public set backgroundIntensity(val: number | undefined) {
115
+ if(val === this._backgroundIntensity) return;
116
+ if (val === undefined)
117
+ this._backgroundIntensity = undefined;
118
+ else
119
+ this._backgroundIntensity = Math.min(Math.max(val, 0), 10);
120
+ this.applyClearFlagsIfIsActiveCamera();
121
+ }
122
+ public get backgroundIntensity() : number | undefined {
123
+ return this._backgroundIntensity;
124
+ }
125
+ private _backgroundIntensity?: number;
99
126
 
100
127
  @serializable(RGBAColor)
101
128
  public get backgroundColor(): RGBAColor | null {
@@ -220,6 +247,13 @@ export class Camera extends Behaviour implements ICamera {
220
247
  }
221
248
  }
222
249
  this.enableSkybox();
250
+
251
+ if (this._backgroundBlurriness !== undefined)
252
+ this.context.scene.backgroundBlurriness = this._backgroundBlurriness;
253
+ if (this._backgroundIntensity !== undefined)
254
+ //@ts-ignore
255
+ this.context.scene.backgroundIntensity = this._backgroundIntensity;
256
+
223
257
  break;
224
258
  case ClearFlags.SolidColor:
225
259
  if (this._backgroundColor) {
@@ -326,7 +326,7 @@ class Component implements IComponent, EventTarget {
326
326
  earlyUpdate?(): void;
327
327
  update?(): void;
328
328
  lateUpdate?(): void;
329
- onBeforeRender?(frame: THREE.XRFrame | null): void;
329
+ onBeforeRender?(frame: XRFrame | null): void;
330
330
  onAfterRender?(): void;
331
331
 
332
332
  onCollisionEnter?(col: Collision);
@@ -35,8 +35,8 @@ export interface IDragEventListener {
35
35
 
36
36
  export class DragControls extends Interactable implements IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler {
37
37
 
38
- private static _active: DragControls | null = null;
39
- public static get HasAnySelected(): boolean { return this._active !== null; }
38
+ private static _active: number = 0;
39
+ public static get HasAnySelected(): boolean { return this._active > 0; }
40
40
 
41
41
 
42
42
  public transformSelf: boolean = true;
@@ -106,20 +106,24 @@ export class DragControls extends Interactable implements IPointerDownHandler, I
106
106
  onPointerDown(args: PointerEventData) {
107
107
  if (!this.allowEdit(this.gameObject)) return;
108
108
  if (WebXR.IsInWebXR) return;
109
+ DragControls._active += 1;
109
110
  this._dragDelta.set(0, 0);
110
111
  this._didDrag = false;
111
112
  this._waitingForDragStart = args;
112
113
  args.StopPropagation();
113
- // if (this.orbit) this.orbit.enabled = false;
114
+ // disabling pointer controls here already, otherwise we get a few frames of movement event in orbit controls and this will rotate the camera sligthly AFTER drag controls dragging ends.
115
+ if (this.orbit) this.orbit.enabled = false;
114
116
  }
115
117
 
116
118
  onPointerUp(args: PointerEventData) {
117
119
  this._waitingForDragStart = null;
118
120
  if (!this.allowEdit(this.gameObject)) return;
121
+ if(DragControls._active > 0)
122
+ DragControls._active -= 1;
119
123
  if (WebXR.IsInWebXR) return;
120
124
  this.onDragEnd(args);
121
125
  args.StopPropagation();
122
- // if (this.orbit) this.orbit.enabled = true;
126
+ if (this.orbit) this.orbit.enabled = true;
123
127
  }
124
128
 
125
129
 
@@ -1,28 +1,48 @@
1
+ import { serializable } from "../engine/engine_serialization";
2
+ import { EventList } from "./EventList";
3
+ import { IPointerEventHandler, PointerEventData } from "./ui/PointerEvents"
1
4
  import { Behaviour } from "./Component"
2
5
  import { EventType } from "./EventType"
3
6
 
4
- export class EventTrigger extends Behaviour {
5
- /*
6
- private triggers: Array<{ key: EventType, callbacks: Array<Function> }> = [];
7
- private events: Map<EventType, Array<Function>> = new Map();
7
+ class TriggerEvent {
8
+ @serializable()
9
+ eventID!: EventType;
10
+ @serializable(EventList)
11
+ callback!: EventList;
12
+ }
8
13
 
9
- awake() {
10
- for (const i in this.triggers) {
11
- const evt = this.triggers[i];
12
- const key = EventType[evt.key];
13
- this.events.set(key, evt.callbacks);
14
+ export class EventTrigger extends Behaviour implements IPointerEventHandler {
15
+
16
+ @serializable(TriggerEvent)
17
+ private triggers?: Array<TriggerEvent>;
18
+
19
+ invoke(type: EventType) {
20
+ if(!this.triggers) return;
21
+ for(const trigger of this.triggers){
22
+ if(trigger.eventID === type){
23
+ trigger.callback.invoke();
24
+ }
14
25
  }
15
- console.log(this);
16
- // console.log(this.events);
17
26
  }
18
27
 
19
- public invoke(type: EventType) {
20
- const evt = this.events.get(type);
21
- if (evt) {
22
- evt.forEach(callback => {
23
- callback();
24
- });
25
- }
28
+ onPointerClick(_: PointerEventData) {
29
+ this.invoke(EventType.PointerClick);
30
+ }
31
+
32
+ onPointerEnter(_: PointerEventData) {
33
+ this.invoke(EventType.PointerEnter);
34
+ }
35
+
36
+ onPointerExit(_: PointerEventData) {
37
+ this.invoke(EventType.PointerExit);
26
38
  }
27
- */
39
+
40
+ onPointerDown(_: PointerEventData) {
41
+ this.invoke(EventType.PointerDown);
42
+ }
43
+
44
+ onPointerUp(_: PointerEventData) {
45
+ this.invoke(EventType.PointerUp);
46
+ }
47
+
28
48
  }
@@ -165,7 +165,7 @@ export class Light extends Behaviour implements ILight {
165
165
  }
166
166
  }
167
167
  get intensity(): number { return this._intensity; }
168
- private _intensity: number = 1;
168
+ private _intensity: number = -1;
169
169
 
170
170
  @serializable()
171
171
  get shadowDistance(): number {
@@ -344,7 +344,9 @@ export class Light extends Behaviour implements ILight {
344
344
 
345
345
 
346
346
  if (this.light) {
347
- this._intensity = this.light.intensity;
347
+ if (this._intensity >= 0)
348
+ this.light.intensity = this._intensity;
349
+ else this._intensity = this.light.intensity;
348
350
 
349
351
  if (this.shadows !== LightShadows.None) {
350
352
  this.light.castShadow = true;
@@ -440,20 +442,20 @@ export class Light extends Behaviour implements ILight {
440
442
  private updateShadowSoftHard() {
441
443
  if (!this.light) return;
442
444
  if (this.shadows === LightShadows.Soft) {
443
- const radius = this.light.shadow.mapSize.width / 1024 * 5;
444
- const samples = Mathf.clamp(Math.round(radius), 2, 10);
445
- this.light.shadow.radius = radius;
446
- this.light.shadow.blurSamples = samples;
447
- if (isMobileDevice()) {
448
- this.light.shadow.radius *= .5;
449
- this.light.shadow.blurSamples = Math.floor(this.light.shadow.blurSamples * .5);
450
- }
451
- if (Light.allowChangingRendererShadowMapType) {
452
- if(this.context.renderer.shadowMap.type !== THREE.VSMShadowMap){
453
- if(isLocalNetwork()) console.warn("Changing renderer shadow map type to VSMShadowMap because a light with soft shadows enabled was found (this will cause all shadow receivers to also cast shadows). If you don't want this behaviour either set the shadow type to hard or set Light.allowChangingRendererShadowMapType to false.", this);
454
- this.context.renderer.shadowMap.type = THREE.VSMShadowMap;
455
- }
456
- }
445
+ // const radius = this.light.shadow.mapSize.width / 1024 * 5;
446
+ // const samples = Mathf.clamp(Math.round(radius), 2, 10);
447
+ // this.light.shadow.radius = radius;
448
+ // this.light.shadow.blurSamples = samples;
449
+ // if (isMobileDevice()) {
450
+ // this.light.shadow.radius *= .5;
451
+ // this.light.shadow.blurSamples = Math.floor(this.light.shadow.blurSamples * .5);
452
+ // }
453
+ // if (Light.allowChangingRendererShadowMapType) {
454
+ // if(this.context.renderer.shadowMap.type !== THREE.VSMShadowMap){
455
+ // if(isLocalNetwork()) console.warn("Changing renderer shadow map type to VSMShadowMap because a light with soft shadows enabled was found (this will cause all shadow receivers to also cast shadows). If you don't want this behaviour either set the shadow type to hard or set Light.allowChangingRendererShadowMapType to false.", this);
456
+ // this.context.renderer.shadowMap.type = THREE.VSMShadowMap;
457
+ // }
458
+ // }
457
459
  }
458
460
  else {
459
461
  this.light.shadow.radius = 1;
@@ -3,13 +3,13 @@ import { Behaviour, GameObject } from "./Component";
3
3
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls";
4
4
  import { LookAtConstraint } from "./LookAtConstraint";
5
5
  import * as THREE from "three";
6
- import { getWorldPosition } from "../engine/engine_three_utils";
6
+ import { getWorldPosition, setWorldPosition, slerp } from "../engine/engine_three_utils";
7
7
  import { RaycastOptions } from "../engine/engine_physics";
8
8
  import { serializable } from "../engine/engine_serialization_decorator";
9
9
  import { Camera } from "./Camera";
10
- import { getParam } from "../engine/engine_utils";
10
+ import { getParam, isMobileDevice } from "../engine/engine_utils";
11
11
 
12
- const noLimits = getParam("nocamlimits");
12
+ const freeCam = getParam("freecam");
13
13
 
14
14
  export class OrbitControls extends Behaviour {
15
15
  public get controls() {
@@ -40,7 +40,7 @@ export class OrbitControls extends Behaviour {
40
40
  doubleClickToFocus: boolean = true;
41
41
 
42
42
  // remove once slerp works correctly
43
- useSlerp: boolean = false;
43
+ useSlerp: boolean = true;
44
44
 
45
45
 
46
46
  debugLog: boolean = false;
@@ -76,13 +76,21 @@ export class OrbitControls extends Behaviour {
76
76
  }
77
77
 
78
78
  if (this._controls) {
79
+ if (freeCam) {
80
+ this.enablePan = true;
81
+ this.enableZoom = true;
82
+ this.middleClickToFocus = true;
83
+ if(isMobileDevice()) this.doubleClickToFocus = true;
84
+ }
85
+
79
86
  this._controls.enableDamping = this.enableDamping;
87
+ //@ts-ignore (not in types)
80
88
  this._controls.enableKeys = this.enableKeys;
81
89
  this._controls.autoRotate = this.autoRotate;
82
90
  this._controls.autoRotateSpeed = this.autoRotateSpeed;
83
91
  this._controls.enableZoom = this.enableZoom;
84
92
  if (cam?.type === "PerspectiveCamera") {
85
- if (noLimits) {
93
+ if (freeCam) {
86
94
  // dont set limits
87
95
  }
88
96
  else {
@@ -91,7 +99,7 @@ export class OrbitControls extends Behaviour {
91
99
  }
92
100
  }
93
101
  else {
94
- if (noLimits) {
102
+ if (freeCam) {
95
103
  // dont set limits
96
104
  }
97
105
  else {
@@ -183,14 +191,10 @@ export class OrbitControls extends Behaviour {
183
191
 
184
192
  // lerp the camera
185
193
  if (this._lerpCameraToTarget && this._cameraTargetPosition && this._cameraObject) {
186
- if (this.useSlerp && typeof this._cameraObject?.position["slerp"] === "function") {
194
+ // setWorldPosition(this._cameraObject, this._cameraTargetPosition);
195
+ if (this.useSlerp) {
187
196
  const position = this._cameraObject?.position;
188
- position
189
- // TODO fix the offset here
190
- // .sub(this._cameraTargetPosition)
191
- //@ts-ignore
192
- .slerp(this._cameraTargetPosition, step)
193
- // .add(this._cameraTargetPosition);
197
+ slerp(position, this._cameraTargetPosition, step);
194
198
  }
195
199
  else {
196
200
  this._cameraObject?.position.lerp(this._cameraTargetPosition, step);
@@ -210,7 +214,7 @@ export class OrbitControls extends Behaviour {
210
214
  }
211
215
  }
212
216
 
213
- if (this.lookAtConstraint?.locked) this.setFromTargetPosition(0, this.lookAtConstraint01);
217
+ if (!freeCam && this.lookAtConstraint?.locked) this.setFromTargetPosition(0, this.lookAtConstraint01);
214
218
 
215
219
 
216
220
  if (this._controls && !this.context.isInXR) {
@@ -281,6 +285,7 @@ export class OrbitControls extends Behaviour {
281
285
  this._lerpCameraToTarget = true;
282
286
  const pos = getWorldPosition(this.context.mainCamera);
283
287
  this._cameraTargetPosition = pos.clone().sub(this.controls.target).add(this._lookTargetPosition);
288
+ this._cameraObject?.parent?.worldToLocal(this._cameraTargetPosition);
284
289
  }
285
290
  break;
286
291
  }
@@ -656,8 +656,6 @@ export class ShapeModule implements EmitterShape {
656
656
 
657
657
  private randomizeDirection(direction: Vector3, amount: number) {
658
658
  if (amount === 0) return;
659
- console.log('randomizeDirection', amount);
660
-
661
659
  const randomQuat = ShapeModule._randomQuat;
662
660
  const tempVec = ShapeModule._tempVec;
663
661
  tempVec.set(Math.random() - .5, Math.random() - .5, Math.random() - .5).normalize();
@@ -674,7 +672,6 @@ export class ShapeModule implements EmitterShape {
674
672
  const z = Math.cos(phi);
675
673
  const v = new Vector3(x, y, z);
676
674
  dir.lerp(v, amount);
677
-
678
675
  }
679
676
 
680
677
  private randomSpherePoint(pos: Vec3, radius: number, thickness: number, arc: number, vec: Vec3) {
@@ -2,7 +2,7 @@ import { Behaviour, GameObject } from "./Component";
2
2
  import * as THREE from "three";
3
3
  // import { RendererCustomShader } from "./RendererCustomShader";
4
4
  import { RendererLightmap } from "./RendererLightmap";
5
- import { Context } from "../engine/engine_setup";
5
+ import { Context, FrameEvent } from "../engine/engine_setup";
6
6
  import { getParam } from "../engine/engine_utils";
7
7
  import { serializable } from "../engine/engine_serialization_decorator";
8
8
  import { AxesHelper, Material, Mesh, Object3D, SkinnedMesh, Texture, Vector4 } from "three";
@@ -546,11 +546,17 @@ export class Renderer extends Behaviour implements IRenderer {
546
546
  this._reflectionProbe = null;
547
547
  if (this.reflectionProbeUsage !== ReflectionProbeUsage.Off) {
548
548
  if (!this.probeAnchor) return;
549
- const obj = this.probeAnchor || this.gameObject;
550
- const isAnchor = this.probeAnchor ? true : false;
551
- this._reflectionProbe = ReflectionProbe.get(obj, this.context, isAnchor);
549
+ // update the reflection probe right before rendering
550
+ // if we do it immediately the reflection probe might not be enabled yet
551
+ // (since this method is called from onEnable)
552
+ this.startCoroutine(this._updateReflectionProbe(), FrameEvent.OnBeforeRender);
552
553
  }
553
554
  }
555
+ private *_updateReflectionProbe(){
556
+ const obj = this.probeAnchor || this.gameObject;
557
+ const isAnchor = this.probeAnchor ? true : false;
558
+ this._reflectionProbe = ReflectionProbe.get(obj, this.context, isAnchor);
559
+ }
554
560
 
555
561
  private setVisibility(visible: boolean) {
556
562
 
@@ -3,7 +3,7 @@ import * as THREE from 'three'
3
3
  import { getWorldPosition } from "../engine/engine_three_utils";
4
4
  import { serializable } from "../engine/engine_serialization_decorator";
5
5
  import { Watch } from "../engine/engine_utils";
6
- import { Object3D, Vector3 } from "three";
6
+ import { Matrix4, Object3D, Vector3 } from "three";
7
7
  import { IRigidbody } from "../engine/engine_types";
8
8
  import { CollisionDetectionMode, RigidbodyConstraints } from "../engine/engine_physics.types";
9
9
  import { validate } from "../engine/engine_util_decorator";
@@ -110,6 +110,18 @@ class TransformWatch {
110
110
  this.rotationChanged = true;
111
111
  })
112
112
  }
113
+
114
+ // detect changes in the parent matrix
115
+ const original = this.obj.matrixWorld.multiplyMatrices.bind(this.obj.matrixWorld);
116
+ const lastParentMatrix = new Matrix4();
117
+ this.obj.matrixWorld["multiplyMatrices"] = (parent: Matrix4, matrix: Matrix4) => {
118
+ if (!lastParentMatrix.equals(parent)) {
119
+ this.positionChanged = true;
120
+ this.rotationChanged = true;
121
+ lastParentMatrix.copy(parent);
122
+ }
123
+ return original(parent, matrix);;
124
+ }
113
125
  }
114
126
 
115
127
  stop() {
@@ -40,6 +40,7 @@ declare type ScreenCaptureOptions = {
40
40
  export class ScreenCapture extends Behaviour implements IPointerClickHandler {
41
41
 
42
42
  onPointerClick() {
43
+ if(this.context.connection.isInRoom === false) return;
43
44
  if (this.isReceiving) {
44
45
  if (this.videoPlayer)
45
46
  this.videoPlayer.screenspace = !this.videoPlayer.screenspace;
@@ -40,7 +40,7 @@ export class ShadowCatcher extends Behaviour {
40
40
  applyLightBlendMaterial() {
41
41
  const renderer = GameObject.getComponent(this.gameObject, Renderer);
42
42
  if (renderer) {
43
- const material = renderer.material;
43
+ const material = renderer.sharedMaterial;
44
44
  material.blending = AdditiveBlending;
45
45
  this.applyMaterialOptions(material);
46
46
  material.onBeforeCompile = (shader) => {
@@ -50,9 +50,8 @@ export class ShadowCatcher extends Behaviour {
50
50
  // see https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js#L2
51
51
  // see https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js#L281
52
52
 
53
- shader.fragmentShader.replace("vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;",
53
+ shader.fragmentShader = shader.fragmentShader.replace("vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;",
54
54
  `vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;
55
-
56
55
  // diffuse-only lighting with overdrive to somewhat compensate
57
56
  // for the loss of indirect lighting and to make it more visible.
58
57
  vec3 direct = reflectedLight.directDiffuse * 3.;
@@ -73,15 +72,15 @@ export class ShadowCatcher extends Behaviour {
73
72
  applyShadowMaterial() {
74
73
  const renderer = GameObject.getComponent(this.gameObject, Renderer);
75
74
  if (renderer) {
76
- if (renderer.material?.type !== "ShadowMaterial") {
75
+ if (renderer.sharedMaterial?.type !== "ShadowMaterial") {
77
76
  const material = new ShadowMaterial();
78
77
  material.color = this.shadowColor;
79
78
  material.opacity = this.shadowColor.alpha;
80
79
  this.applyMaterialOptions(material);
81
- renderer.material = material;
80
+ renderer.sharedMaterial = material;
82
81
  }
83
82
  else {
84
- const material = renderer.material as ShadowMaterial;
83
+ const material = renderer.sharedMaterial as ShadowMaterial;
85
84
  material.color = this.shadowColor;
86
85
  material.opacity = this.shadowColor.alpha;
87
86
  this.applyMaterialOptions(material);
@@ -18,6 +18,9 @@ export class RemoteSkybox extends Behaviour {
18
18
  @serializable()
19
19
  background: boolean = true;
20
20
 
21
+ @serializable()
22
+ backgroundBlurriness: number = 0;
23
+
21
24
  @serializable()
22
25
  environment: boolean = true;
23
26
 
@@ -79,6 +82,7 @@ export class RemoteSkybox extends Behaviour {
79
82
  this._prevLoadedEnvironment = envMap;
80
83
  const nameIndex = url.lastIndexOf("/");
81
84
  envMap.name = url.substring(nameIndex >= 0 ? nameIndex + 1 : 0);
85
+ this.context.scene.backgroundBlurriness = this.backgroundBlurriness;
82
86
  }
83
87
 
84
88