Needle Engine

Changes between version 3.25.3 and 3.25.4
Files changed (6) hide show
  1. src/engine-components/Camera.ts +9 -0
  2. src/engine/engine_context.ts +1 -0
  3. src/engine/engine_lifecycle_api.ts +16 -2
  4. src/engine/engine_lifecycle_functions_internal.ts +5 -3
  5. src/engine/engine_physics_rapier.ts +9 -5
  6. src/engine/codegen/register_types.ts +2 -2
src/engine-components/Camera.ts CHANGED
@@ -96,6 +96,10 @@
96
96
  @serializable()
97
97
  public ARBackgroundAlpha: number = 0;
98
98
 
99
+ /**
100
+ * The [`mask`](https://threejs.org/docs/#api/en/core/Layers.mask) value of the three camera object layers
101
+ * If you want to just see objects on one layer (e.g. layer 2) then you can use `cullingLayer = 2` on this camera component instead
102
+ */
99
103
  @serializable()
100
104
  public set cullingMask(val: number) {
101
105
  this._cullingMask = val;
@@ -109,6 +113,11 @@
109
113
  }
110
114
  private _cullingMask: number = 0xffffffff;
111
115
 
116
+ /** Set only a specific layer active to be rendered by the camera. This is equivalent to calling `layers.set(val)` */
117
+ public set cullingLayer(val: number) {
118
+ this.cullingMask = (1 << val | 0) >>> 0;
119
+ }
120
+
112
121
  @serializable()
113
122
  public set backgroundBlurriness(val: number | undefined) {
114
123
  if (val === this._backgroundBlurriness) return;
src/engine/engine_context.ts CHANGED
@@ -828,6 +828,7 @@
828
828
  this.domElement?.internalSetLoadingMessage("finish loading");
829
829
  await res;
830
830
  }
831
+ invokeLifecycleFunctions(this, ContextEvent.ContextCreated)
831
832
 
832
833
  this._isCreating = false;
833
834
  if (!this.isManagedExternally)
src/engine/engine_lifecycle_api.ts CHANGED
@@ -1,16 +1,30 @@
1
+ import { ContextEvent } from "./engine_context_registry.js";
1
2
  import { FrameEvent } from "./engine_context.js";
2
3
  import { LifecycleMethod, registerCallback } from "./engine_lifecycle_functions_internal.js";
3
4
 
4
5
 
5
- /** Register a callback in the engine start event */
6
+ /**
7
+ * Register a callback in the engine context created event.
8
+ * This happens once per context (after the context has been created and the first content has been loaded)
9
+ */
10
+ export function onInitialized(cb: LifecycleMethod) {
11
+ registerCallback(cb, ContextEvent.ContextCreated);
12
+ }
13
+
14
+ /** Register a callback in the engine start event.
15
+ * This happens at the beginning of each frame */
6
16
  export function onStart(cb: LifecycleMethod) {
7
17
  registerCallback(cb, FrameEvent.Start);
8
18
  }
9
19
 
10
20
 
11
21
  /** Register a callback in the engine update event
12
- * called every frame
22
+ * This is called every frame
13
23
  * */
14
24
  export function onUpdate(cb: LifecycleMethod) {
15
25
  registerCallback(cb, FrameEvent.Update);
26
+ }
27
+
28
+ export function onBeforeRender(cb: LifecycleMethod) {
29
+ registerCallback(cb, FrameEvent.OnBeforeRender);
16
30
  }
src/engine/engine_lifecycle_functions_internal.ts CHANGED
@@ -1,18 +1,20 @@
1
1
  import { safeInvoke } from "./engine_generic_utils.js";
2
2
  import { FrameEvent, type Context } from "./engine_context.js";
3
+ import type { ContextEvent } from "./engine_context_registry.js";
3
4
 
4
5
  export declare type LifecycleMethod = (ctx: Context) => void;
6
+ export declare type Event = ContextEvent | FrameEvent;
5
7
 
6
- const allMethods = new Map<FrameEvent, Array<LifecycleMethod>>();
8
+ const allMethods = new Map<Event, Array<LifecycleMethod>>();
7
9
 
8
- export function registerCallback(cb: LifecycleMethod, evt: FrameEvent) {
10
+ export function registerCallback(cb: LifecycleMethod, evt: Event) {
9
11
  if (!allMethods.has(evt)) {
10
12
  allMethods.set(evt, new Array<LifecycleMethod>());
11
13
  }
12
14
  allMethods.get(evt)!.push(cb);
13
15
  }
14
16
 
15
- export function invokeLifecycleFunctions(ctx: Context, evt: FrameEvent) {
17
+ export function invokeLifecycleFunctions(ctx: Context, evt: Event) {
16
18
  const methods = allMethods.get(evt);
17
19
  if (methods) {
18
20
  if (methods.length > 0) {
src/engine/engine_physics_rapier.ts CHANGED
@@ -456,6 +456,7 @@
456
456
  public get world(): World | undefined { return this._world };
457
457
 
458
458
  private _tempPosition: Vector3 = new Vector3();
459
+ private _tempPosition2: Vector3 = new Vector3();
459
460
  private _tempQuaternion: Quaternion = new Quaternion();
460
461
  private _tempScale: Vector3 = new Vector3();
461
462
  private _tempMatrix: Matrix4 = new Matrix4();
@@ -1092,12 +1093,15 @@
1092
1093
  private tryApplyCenter(collider: ICollider, targetVector: Vector3) {
1093
1094
  const center = collider.center;
1094
1095
  if (center && collider.gameObject) {
1095
- getWorldScale(collider.gameObject, this._tempScale);
1096
- center.multiply(this._tempScale);
1096
+ getWorldScale(collider.gameObject, this._tempScale);
1097
+ this._tempPosition2.x = center.x;
1098
+ this._tempPosition2.y = center.y;
1099
+ this._tempPosition2.z = center.z;
1100
+ this._tempPosition2.multiply(this._tempScale);
1097
1101
  // TODO: fix export of center in editor integrations so we dont have to flip here
1098
- targetVector.x -= center.x;
1099
- targetVector.y += center.y;
1100
- targetVector.z += center.z;
1102
+ targetVector.x -= this._tempPosition2.x;
1103
+ targetVector.y += this._tempPosition2.y;
1104
+ targetVector.z += this._tempPosition2.z;
1101
1105
  }
1102
1106
  }
1103
1107
 
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);