Needle Engine

Changes between version 3.20.1 and 3.20.2
Files changed (6) hide show
  1. src/engine/engine_context.ts +3 -3
  2. src/engine/engine_element.ts +1 -1
  3. src/engine/engine_input.ts +1 -1
  4. src/engine-components/OrbitControls.ts +3 -1
  5. src/engine-components/postprocessing/PostProcessingHandler.ts +18 -2
  6. src/engine-components/webxr/WebXRPlaneTracking.ts +3 -2
src/engine/engine_context.ts CHANGED
@@ -231,13 +231,13 @@
231
231
  this.calculateBoundingClientRect();
232
232
  return this._domY;
233
233
  }
234
- get isInXR() { return this.renderer.xr?.isPresenting || false; }
234
+ get isInXR() { return this.renderer?.xr?.isPresenting || false; }
235
235
  xrSessionMode: XRSessionMode | undefined = undefined;
236
236
  get isInVR() { return this.xrSessionMode === XRSessionMode.ImmersiveVR; }
237
237
  get isInAR() { return this.xrSessionMode === XRSessionMode.ImmersiveAR; }
238
- get xrSession() { return this.renderer.xr?.getSession(); }
238
+ get xrSession() { return this.renderer?.xr?.getSession(); }
239
239
  get xrFrame() { return this._xrFrame }
240
- get xrCamera(): WebXRArrayCamera | undefined { return this.renderer.xr?.getCamera(); }
240
+ get xrCamera(): WebXRArrayCamera | undefined { return this.renderer?.xr?.getCamera(); }
241
241
  private _xrFrame: XRFrame | null = null;
242
242
  get arOverlayElement(): HTMLElement {
243
243
  const el = this.domElement as any;
src/engine/engine_element.ts CHANGED
@@ -518,7 +518,7 @@
518
518
  }
519
519
 
520
520
  private setupElementsForMode(el: HTMLElement, currentSessionType: string, _session: XRSession | null = null) {
521
- if (el === this._context?.renderer.domElement) return;
521
+ if (el === this._context?.renderer?.domElement) return;
522
522
  if (el.id === "VRButton" || el.id === "ARButton") return;
523
523
 
524
524
  const classList = el.classList;
src/engine/engine_input.ts CHANGED
@@ -403,7 +403,7 @@
403
403
 
404
404
  // We only check the target elements here since the canvas may be overlapped by other elements
405
405
  // in which case we do not want to use the input (e.g. if a HTML element is being triggered)
406
- if(evt.target === this.context.renderer.domElement) return true;
406
+ if(evt.target === this.context.renderer?.domElement) return true;
407
407
  if(evt.target === this.context.domElement) return true;
408
408
  return false;
409
409
  }
src/engine-components/OrbitControls.ts CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  const freeCam = getParam("freecam");
19
19
  const debugCameraFit = getParam("debugcamerafit");
20
- const smoothcam = getParam("smoothcam")
20
+ const smoothcam = getParam("smoothcam");
21
21
 
22
22
  const disabledKeys = { LEFT: "", UP: "", RIGHT: "", BOTTOM: "" };
23
23
  let defaultKeys: any = undefined;
@@ -134,6 +134,8 @@
134
134
  if (hits.length > 0) {
135
135
  this.setTarget(hits[0].point, true);
136
136
  }
137
+ if (debugCameraFit)
138
+ console.log("OrbitControls hits", ...hits);
137
139
  }
138
140
  if (this.autoFit) this.fitCamera()
139
141
  }
src/engine-components/postprocessing/PostProcessingHandler.ts CHANGED
@@ -10,7 +10,8 @@
10
10
 
11
11
  const debug = getParam("debugpost");
12
12
 
13
- const activeKey = Symbol("postprocessing-handler");
13
+ const activeKey = Symbol("needle:postprocessing-handler");
14
+ const autoclearSetting = Symbol("needle:previous-autoclear-state")
14
15
 
15
16
  export class PostProcessingHandler {
16
17
 
@@ -22,6 +23,10 @@
22
23
  return this._isActive;
23
24
  }
24
25
 
26
+ get composer() {
27
+ return this._composer;
28
+ }
29
+
25
30
  private _isActive: boolean = false;
26
31
  private readonly context: Context;
27
32
 
@@ -47,8 +52,13 @@
47
52
  if (active === this) {
48
53
  delete context[activeKey];
49
54
  }
50
- if (context.composer === this._composer)
55
+ if (context.composer === this._composer) {
56
+ context.composer?.dispose();
51
57
  context.composer = null;
58
+ }
59
+ if (typeof context.renderer[autoclearSetting] === "boolean") {
60
+ context.renderer.autoClear = context.renderer[autoclearSetting];
61
+ }
52
62
  }
53
63
 
54
64
  dispose() {
@@ -58,6 +68,7 @@
58
68
  effect.dispose();
59
69
  }
60
70
  this._effects.length = 0;
71
+ this._composer = null;
61
72
  }
62
73
 
63
74
 
@@ -113,6 +124,11 @@
113
124
  const renderer = context.renderer;
114
125
  const scene = context.scene;
115
126
  const cam = camera.cam;
127
+
128
+ // Store the auto clear setting because the postprocessing composer just disables it
129
+ // and when we disable postprocessing we want to restore the original setting
130
+ // https://github.com/pmndrs/postprocessing/blob/271944b74b543a5b743a62803a167b60cc6bb4ee/src/core/EffectComposer.js#L230C12-L230C12
131
+ renderer[autoclearSetting] = renderer.autoClear;
116
132
 
117
133
  // create composer and set active on context
118
134
  if (!this._composer) {
src/engine-components/webxr/WebXRPlaneTracking.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { BufferAttribute, BufferGeometry, Group, Material, Mesh, Object3D, TypedArray, Vector3 } from "three";
1
+ import { BufferAttribute, BufferGeometry, Group, Material, Mesh, Object3D, Vector3 } from "three";
2
+
2
3
  import { MeshCollider } from "../Collider.js";
3
4
  import { Behaviour, GameObject } from "../Component.js";
4
5
  import { WebXR, WebXREvent } from "./WebXR.js";
@@ -320,7 +321,7 @@
320
321
  geometry.setAttribute('uv', new BufferAttribute(new Float32Array(uvs), 2));
321
322
 
322
323
  geometry.computeVertexNormals();
323
- geometry.computeTangents();
324
+ // geometry.computeTangents();
324
325
 
325
326
  return geometry;
326
327
  }