Needle Engine

Changes between version 3.27.4-beta and 3.27.5-beta
Files changed (9) hide show
  1. src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +21 -7
  2. src/engine/engine_context.ts +3 -2
  3. src/engine/engine_setup.ts +1 -1
  4. src/engine/engine.ts +1 -2
  5. src/engine-components/ui/EventSystem.ts +9 -1
  6. src/engine/codegen/register_types.ts +2 -2
  7. src/engine-components/export/usdz/ThreeUSDZExporter.ts +3 -7
  8. src/engine-schemes/flatc.exe +0 -0
  9. src/engine/engine_shims.ts +31 -0
src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts CHANGED
@@ -477,11 +477,7 @@
477
477
  ensureRaycaster(this.gameObject);
478
478
  }
479
479
 
480
- onPointerClick(args: PointerEventData) {
481
- args.use();
482
-
483
- if (!this.clip) return;
484
-
480
+ ensureAudioSource() {
485
481
  if (!this.target) {
486
482
  const newAudioSource = this.gameObject.addNewComponent(AudioSource);
487
483
  if (newAudioSource) {
@@ -491,7 +487,15 @@
491
487
  newAudioSource.loop = false;
492
488
  }
493
489
  }
490
+ }
494
491
 
492
+ onPointerClick(args: PointerEventData) {
493
+ args.use();
494
+
495
+ if (!this.clip) return;
496
+
497
+ this.ensureAudioSource();
498
+
495
499
  if (this.target) {
496
500
 
497
501
  if (this.target.isPlaying && this.toggleOnClick) {
@@ -519,11 +523,21 @@
519
523
  const clipName = clipUrl.split("/").pop();
520
524
  const volume = this.target ? this.target.volume : 1;
521
525
  const auralMode = this.target && this.target.spatialBlend == 0 ? AuralMode.NonSpatial : AuralMode.Spatial;
522
- const playClip = new BehaviorModel("playAudio " + this.name,
526
+
527
+ const playClipOnTap = new BehaviorModel("playAudio " + this.name,
523
528
  TriggerBuilder.tapTrigger(this.gameObject),
524
529
  ActionBuilder.playAudioAction(playbackTarget, "audio/" + clipName, PlayAction.Play, volume, auralMode),
525
530
  );
526
- ext.addBehavior(playClip);
531
+ ext.addBehavior(playClipOnTap);
532
+
533
+ // automatically play audio on start too if the referenced AudioSource has playOnAwake enabled
534
+ if (this.target && this.target.playOnAwake && this.target.enabled) {
535
+ const playClipOnStart = new BehaviorModel("playAudioOnStart " + this.name,
536
+ TriggerBuilder.sceneStartTrigger(),
537
+ ActionBuilder.playAudioAction(playbackTarget, "audio/" + clipName, PlayAction.Play, volume, auralMode),
538
+ );
539
+ ext.addBehavior(playClipOnStart);
540
+ }
527
541
  }
528
542
  }
529
543
 
src/engine/engine_context.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  Material, NearestFilter, NoToneMapping, Object3D, PCFSoftShadowMap,
4
4
  PerspectiveCamera, RGBAFormat, Scene, SRGBColorSpace,
5
5
  Texture, WebGLRenderer, type WebGLRendererParameters, WebGLRenderTarget, type WebXRArrayCamera
6
- } from 'three'
6
+ } from 'three';
7
+
7
8
  import { Input } from './engine_input.js';
8
9
  import { Physics } from './engine_physics.js';
9
10
  import { Time } from './engine_time.js';
@@ -25,7 +26,7 @@
25
26
  import { LightDataRegistry, type ILightDataRegistry } from './engine_lightdata.js';
26
27
  import { PlayerViewManager } from './engine_playerview.js';
27
28
 
28
- import { type CoroutineData, type GLTF, type ICamera, type IComponent, type IContext, type ILight, type LoadedGLTF } from "./engine_types.js"
29
+ import { type CoroutineData, type GLTF, type ICamera, type IComponent, type IContext, type ILight, type LoadedGLTF } from "./engine_types.js";
29
30
  import { destroy, foreachComponent } from './engine_gameobject.js';
30
31
  import { ContextEvent, ContextRegistry } from './engine_context_registry.js';
31
32
  import { delay, getParam } from './engine_utils.js';
src/engine/engine_setup.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // TODO: change all usings to the new path:
2
- export * from "./engine_context.js"
2
+ export * from "./engine_context.js";
src/engine/engine.ts CHANGED
@@ -1,11 +1,10 @@
1
- import "./engine_hot_reload.js"
1
+ import "./engine_hot_reload.js";
2
2
 
3
3
  import * as engine_setup from "./engine_setup.js";
4
4
  import * as engine_scenetools from "./engine_scenetools.js";
5
5
  import "./tests/test_utils.js";
6
6
  import { RGBAColor } from "../engine-components/js-extensions/RGBAColor.js";
7
7
 
8
-
9
8
  const engine : any = {
10
9
  ...engine_setup,
11
10
  ...engine_scenetools,
src/engine-components/ui/EventSystem.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  import { type IPointerEventHandler, PointerEventData, hasPointerEventComponent } from "./PointerEvents.js";
8
8
  import { ObjectRaycaster, Raycaster } from "./Raycaster.js";
9
9
  import { InputEvents, NEPointerEvent, PointerType } from "../../engine/engine_input.js";
10
- import { Object3D } from "three";
10
+ import { Mesh, Object3D } from "three";
11
11
  import type { ICanvasGroup } from "./Interfaces.js";
12
12
  import { getParam } from "../../engine/engine_utils.js";
13
13
  import { UIRaycastUtils } from "./RaycastUtils.js";
@@ -295,6 +295,14 @@
295
295
  * */
296
296
  private shouldRaycastObject = (obj: Object3D): RaycastTestObjectReturnType => {
297
297
 
298
+ if (!(obj instanceof Mesh))
299
+ return "continue in children";
300
+
301
+ // Layer 2 is IgnoreRaycast
302
+ if (obj.layers.isEnabled(2)) {
303
+ return "continue in children"
304
+ }
305
+
298
306
  // check if this object is actually a UI shadow hierarchy object
299
307
  let shadowComponent: Object3D | null = null;
300
308
  const isUI = isUIObject(obj);
src/engine/codegen/register_types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { TypeStore } from "./../engine_typestore.js"
2
-
2
+
3
3
  // Import types
4
4
  import { __Ignore } from "../../engine-components/codegen/components.js";
5
5
  import { ActionBuilder } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js";
@@ -219,7 +219,7 @@
219
219
  import { XRGrabRendering } from "../../engine-components/webxr/WebXRGrabRendering.js";
220
220
  import { XRRig } from "../../engine-components/webxr/WebXRRig.js";
221
221
  import { XRState } from "../../engine-components/XRFlag.js";
222
-
222
+
223
223
  // Register types
224
224
  TypeStore.add("__Ignore", __Ignore);
225
225
  TypeStore.add("ActionBuilder", ActionBuilder);
src/engine-components/export/usdz/ThreeUSDZExporter.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { Renderer } from '../../Renderer.js';
2
2
  import { GameObject } from '../../Component.js';
3
+ import type { OffscreenCanvasExt } from '../../../engine/engine_shims.js';
4
+ import '../../../engine/engine_shims.js';
3
5
  import {
4
6
  PlaneGeometry,
5
7
  Texture,
@@ -77,12 +79,6 @@
77
79
  return structuralNodes;
78
80
  }
79
81
 
80
- // TODO: remove once we update to TypeScript 5 that has proper types for OffscreenCanvas
81
- declare type OffsetCanvasExt = OffscreenCanvas & {
82
- convertToBlob: (options?: any) => Promise<Blob>;
83
-
84
- }
85
-
86
82
  class USDObject {
87
83
 
88
84
  static USDObject_export_id = 0;
@@ -975,7 +971,7 @@
975
971
 
976
972
  }
977
973
 
978
- return canvas as OffsetCanvasExt;
974
+ return canvas as OffscreenCanvasExt;
979
975
 
980
976
  } else {
981
977
 
src/engine-schemes/flatc.exe ADDED
File without changes
src/engine/engine_shims.ts ADDED
@@ -0,0 +1,31 @@
1
+ // REMOVE once we switch to TypeScript 5.x
2
+ // OffscreenCanvas has a convertToBlob method, but TypeScript 4.x doesn't have the proper types for it.
3
+ export declare type OffscreenCanvasExt = OffscreenCanvas & {
4
+ convertToBlob: (options?: any) => Promise<Blob>;
5
+ }
6
+
7
+ console.log("APPLYING ENGINE SHIMS");
8
+
9
+ // REMOVE once usage of browsers that don't support OffscreenCanvas is low
10
+ // Shim for missing OffscreenCanvas in iOS 16.x
11
+ if (typeof globalThis !== undefined && !('OffscreenCanvas' in globalThis)) {
12
+ // @ts-ignore
13
+ globalThis['OffscreenCanvas'] = class OffscreenCanvas {
14
+ canvas: HTMLCanvasElement;
15
+ constructor(width, height) {
16
+ this.canvas = document.createElement("canvas");
17
+ this.canvas.width = width;
18
+ this.canvas.height = height;
19
+
20
+ // @ts-ignore
21
+ this.canvas.convertToBlob = (type?: string, quality?: any) => {
22
+ return new Promise(resolve => {
23
+ this.canvas.toBlob(resolve, type, quality);
24
+ });
25
+ };
26
+
27
+ // @ts-ignore
28
+ return this.canvas;
29
+ }
30
+ };
31
+ }