@needle-tools/engine 3.28.5-beta → 3.28.6-beta

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 (41) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/needle-engine.js +7306 -7290
  3. package/dist/needle-engine.light.js +6972 -6956
  4. package/dist/needle-engine.light.min.js +217 -217
  5. package/dist/needle-engine.light.umd.cjs +216 -216
  6. package/dist/needle-engine.min.js +218 -218
  7. package/dist/needle-engine.umd.cjs +217 -217
  8. package/lib/engine/engine_gameobject.js +1 -0
  9. package/lib/engine/engine_gameobject.js.map +1 -1
  10. package/lib/engine/engine_gizmos.js +1 -0
  11. package/lib/engine/engine_gizmos.js.map +1 -1
  12. package/lib/engine/engine_hot_reload.js +2 -2
  13. package/lib/engine/engine_hot_reload.js.map +1 -1
  14. package/lib/engine/engine_physics_rapier.js +7 -3
  15. package/lib/engine/engine_physics_rapier.js.map +1 -1
  16. package/lib/engine/engine_serialization_builtin_serializer.d.ts +1 -0
  17. package/lib/engine/engine_serialization_builtin_serializer.js +24 -8
  18. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  19. package/lib/engine/engine_three_utils.d.ts +1 -0
  20. package/lib/engine/engine_three_utils.js +11 -0
  21. package/lib/engine/engine_three_utils.js.map +1 -1
  22. package/lib/engine/engine_types.d.ts +27 -7
  23. package/lib/engine/engine_types.js +8 -4
  24. package/lib/engine/engine_types.js.map +1 -1
  25. package/lib/engine-components/Animator.d.ts +2 -1
  26. package/lib/engine-components/Animator.js +33 -6
  27. package/lib/engine-components/Animator.js.map +1 -1
  28. package/lib/engine-components/RigidBody.js +2 -0
  29. package/lib/engine-components/RigidBody.js.map +1 -1
  30. package/package.json +1 -1
  31. package/plugins/vite/imports-logger.js +2 -1
  32. package/src/engine/codegen/register_types.ts +2 -2
  33. package/src/engine/engine_gameobject.ts +1 -0
  34. package/src/engine/engine_gizmos.ts +1 -0
  35. package/src/engine/engine_hot_reload.ts +2 -2
  36. package/src/engine/engine_physics_rapier.ts +5 -3
  37. package/src/engine/engine_serialization_builtin_serializer.ts +27 -9
  38. package/src/engine/engine_three_utils.ts +11 -0
  39. package/src/engine/engine_types.ts +31 -31
  40. package/src/engine-components/Animator.ts +27 -9
  41. package/src/engine-components/RigidBody.ts +1 -0
@@ -215,6 +215,7 @@ declare type EventListCall = {
215
215
  method: string,
216
216
  target: string,
217
217
  argument?: any,
218
+ arguments?: Array<any>,
218
219
  enabled?: boolean,
219
220
  }
220
221
 
@@ -280,14 +281,22 @@ class EventListSerializer extends TypeSerializer {
280
281
  }
281
282
  }
282
283
 
283
- let args = call.argument;
284
- if (args !== undefined) {
285
- if (typeof args === "object") {
284
+ function deserializeArgument(arg: any) {
285
+ if (typeof arg === "object") {
286
286
  // Try to deserialize the call argument to either a object or a component reference
287
- let argRes = objectSerializer.onDeserialize(call.argument, context);
288
- if (!argRes) argRes = componentSerializer.onDeserialize(call.argument, context);
289
- if (argRes) args = argRes;
287
+ let argRes = objectSerializer.onDeserialize(arg, context);
288
+ if (!argRes) argRes = componentSerializer.onDeserialize(arg, context);
289
+ if (argRes) return argRes;
290
290
  }
291
+ return arg;
292
+ }
293
+
294
+ let args = call.argument;
295
+ if (args !== undefined) {
296
+ args = deserializeArgument(args);
297
+ }
298
+ else if (call.arguments !== undefined) {
299
+ args = call.arguments.map(deserializeArgument);
291
300
  }
292
301
 
293
302
  // This is the final method we pass to the call info (or undefined if the method couldnt be resolved)
@@ -326,8 +335,17 @@ class EventListSerializer extends TypeSerializer {
326
335
  return (...forwardedArgs) => {
327
336
  const method = target[methodName];
328
337
  if (typeof method === "function") {
329
- if (args !== undefined)
330
- method?.call(target, args);
338
+ if (args !== undefined) {
339
+ // we now have support for creating event methods with multiple arguments
340
+ // an argument can not be an array right now - so if we receive an array we assume it's the array of arguments that we want to call the method with
341
+ // this means ["test", true] will invoke the method like this: myFunction("test", true)
342
+ if (Array.isArray(args))
343
+ method?.call(target, ...args);
344
+ // in any other case (when we just have one argument) we just call the method with the argument
345
+ // we an not use ...args by default becaue that would break string arguments (it would then just use the first character)
346
+ else
347
+ method?.call(target, args);
348
+ }
331
349
  else // support invoking EventList with any number of arguments (if none were declared in unity)
332
350
  method?.call(target, ...forwardedArgs);
333
351
  }
@@ -357,7 +375,7 @@ export class RenderTextureSerializer extends TypeSerializer {
357
375
  colorSpace: THREE.LinearSRGBColorSpace,
358
376
  });
359
377
  rt.texture = tex;
360
-
378
+
361
379
  tex.isRenderTargetTexture = true;
362
380
  tex.flipY = true;
363
381
  tex.offset.y = 1;
@@ -236,6 +236,17 @@ export function logHierarchy(root: Object3D | null | undefined, collapsible: boo
236
236
  };
237
237
  }
238
238
 
239
+ export function getParentHierarchyPath(obj: Object3D): string {
240
+ let path = obj?.name || "";
241
+ if(!obj) return path;
242
+ let parent = obj.parent;
243
+ while (parent) {
244
+ path = parent.name + "/" + path;
245
+ parent = parent.parent;
246
+ }
247
+ return path;
248
+ }
249
+
239
250
 
240
251
  export function isAnimationAction(obj: object) {
241
252
  if (obj) {
@@ -101,10 +101,14 @@ export declare interface INeedleEngineComponent extends HTMLElement {
101
101
  }
102
102
 
103
103
  export declare interface IGameObject extends Object3D {
104
+
105
+ /** the object's unique identifier */
104
106
  guid: string | undefined;
105
107
 
108
+ /** if the object is enabled in the hierarchy (usually equivalent to `visible`) */
106
109
  activeSelf: boolean;
107
110
 
111
+ /** call to destroy this object including all components that are attached to it. Will destroy all children recursively */
108
112
  destroy(): void;
109
113
 
110
114
  /** NOTE: this is just a wrapper for devs coming from Unity. Please use this.gameObject instead. In Needle Engine this.gameObject is the same as this.gameObject.transform. See the tutorial link below for more information
@@ -113,14 +117,26 @@ export declare interface IGameObject extends Object3D {
113
117
  * */
114
118
  get transform(): IGameObject;
115
119
 
120
+ /** Add a new component to this object. Expects a component type (e.g. `addNewComponent(Animator)`) */
116
121
  addNewComponent<T>(type: Constructor<T>): T | null;
122
+ /** Remove a component from this object. Expected a component instance
123
+ * @returns the removed component (equal to the passed in component)
124
+ */
117
125
  removeComponent(comp: IComponent): IComponent;
126
+ /** Searches for a component type on this object. If no component of the searched type exists yet a new instance will be created and returned */
118
127
  getOrAddComponent<T>(typeName: Constructor<T> | null): T;
128
+ /** Tries to find a component of a type on this object.
129
+ * @returns the first instance of a component on this object that matches the passed in type or null if no component of this type (or a subtype) exists */
119
130
  getComponent<T>(type: Constructor<T>): T | null;
131
+ /** @returns all components of a certain type on this object */
120
132
  getComponents<T>(type: Constructor<T>, arr?: T[]): Array<T>;
133
+ /** Finds a component of a certain type on this object OR a child object if any exists */
121
134
  getComponentInChildren<T>(type: Constructor<T>): T | null;
135
+ /** Finds all components of a certain type on this object AND all children (recursively) */
122
136
  getComponentsInChildren<T>(type: Constructor<T>, arr?: T[]): Array<T>;
137
+ /** Finds a component of a certain type on this object OR a parent object if any exists */
123
138
  getComponentInParent<T>(type: Constructor<T>): T | null;
139
+ /** Finds all components of a certain type on this object AND all parents (recursively) */
124
140
  getComponentsInParent<T>(type: Constructor<T>, arr?: T[]): Array<T>;
125
141
 
126
142
  get worldPosition(): Vector3;
@@ -144,6 +160,7 @@ export interface IHasGuid {
144
160
  export interface IComponent extends IHasGuid {
145
161
  get isComponent(): boolean;
146
162
 
163
+ /** the object this component is attached to */
147
164
  gameObject: IGameObject;
148
165
  // guid: string;
149
166
  enabled: boolean;
@@ -327,7 +344,9 @@ export class ContactPoint {
327
344
  private readonly _normal: Vec3;
328
345
  private readonly _tangentVelocity: Vec3;
329
346
 
347
+ /** the distance of the collision point */
330
348
  readonly distance: number;
349
+ /** the impulse velocity */
331
350
  readonly impulse: number;
332
351
  readonly friction: number;
333
352
 
@@ -343,7 +362,7 @@ export class ContactPoint {
343
362
  return target.set(this._normal.x, this._normal.y, this._normal.z);
344
363
  }
345
364
 
346
- /** */
365
+ /** worldspace tangent */
347
366
  get tangentVelocity() {
348
367
  const target = contactsVectorBuffer.get();
349
368
  return target.set(this._tangentVelocity.x, this._tangentVelocity.y, this._tangentVelocity.z);
@@ -361,55 +380,36 @@ export class ContactPoint {
361
380
 
362
381
  /// all info in here must be readonly because the object is only created once per started collision
363
382
  export class Collision {
383
+
384
+ /** The contact points of this collision. Contains information about positions, normals, distance, friction, impulse... */
364
385
  readonly contacts: ContactPoint[];
365
386
 
366
- constructor(obj: Object3D, otherCollider: ICollider, contacts: ContactPoint[]) {
387
+ constructor(obj: IGameObject, otherCollider: ICollider, contacts: ContactPoint[]) {
367
388
  this.me = obj;
368
389
  this._collider = otherCollider;
369
390
  this._gameObject = otherCollider.gameObject;
370
391
  this.contacts = contacts;
371
392
  }
372
393
 
373
- readonly me: Object3D;
374
- private _collider: ICollider;
394
+ /** the gameobject this collision event belongs to (e.g. if onCollisionEnter is called then `me` is the same as `this.gameObject`) */
395
+ readonly me: IGameObject;
375
396
 
376
- /** the collider the collision happened with */
397
+ private _collider: ICollider;
398
+ /** the other collider the collision happened with */
377
399
  get collider(): ICollider {
378
400
  return this._collider;
379
401
  }
380
402
 
381
- /** the object the collision happened with */
382
- private _gameObject: Object3D;
383
- get gameObject(): Object3D {
403
+ private _gameObject: IGameObject;
404
+ /** the other object the collision happened with */
405
+ get gameObject(): IGameObject {
384
406
  return this._gameObject;
385
407
  }
386
408
 
387
- /** the rigidbody we hit, null if none attached */
409
+ /** the other rigidbody we hit, null if none attached */
388
410
  get rigidBody(): IRigidbody | null {
389
411
  return this.collider?.attachedRigidbody;
390
412
  }
391
-
392
-
393
-
394
- // private _normal?: Vector3;
395
- // get normal(): Vector3 {
396
- // if (!this._normal) {
397
- // const vec = this.collision.contact.ni;
398
- // this._normal = new Vector3(vec.x, vec.y, vec.z);
399
- // }
400
- // return this._normal;
401
- // }
402
-
403
-
404
- // private _point?: Vector3;
405
- // get point(): Vector3 {
406
- // if (!this._point) {
407
- // const c = this.collision.contact;
408
- // const point = c.bi.position.clone().vadd(c.ri);
409
- // this._point = new Vector3(point.x, point.y, point.z);
410
- // }
411
- // return this._point;
412
- // }
413
413
  }
414
414
 
415
415
  export type RaycastResult = null | { point: Vector3, collider: ICollider, normal?: Vector3 };
@@ -87,7 +87,8 @@ export class Animator extends Behaviour {
87
87
  /**@deprecated use setBool */
88
88
  SetBool(name: string | number, val: boolean) { this.setBool(name, val); }
89
89
  setBool(name: string | number, value: boolean) {
90
- if(this.runtimeAnimatorController?.getBool(name) !== value)
90
+ if (debug) console.log("setBool", name, value);
91
+ if (this.runtimeAnimatorController?.getBool(name) !== value)
91
92
  this._parametersAreDirty = true;
92
93
  this.runtimeAnimatorController?.setBool(name, value);
93
94
  }
@@ -95,55 +96,71 @@ export class Animator extends Behaviour {
95
96
  /**@deprecated use getBool */
96
97
  GetBool(name: string | number) { return this.getBool(name); }
97
98
  getBool(name: string | number): boolean {
98
- return this.runtimeAnimatorController?.getBool(name) ?? false;
99
+ const res = this.runtimeAnimatorController?.getBool(name) ?? false;
100
+ if (debug) console.log("getBool", name, res);
101
+ return res;
102
+ }
103
+
104
+ toggleBool(name: string | number) {
105
+ this.setBool(name, !this.getBool(name));
99
106
  }
100
107
 
101
108
  /**@deprecated use setFloat */
102
109
  SetFloat(name: string | number, val: number) { this.setFloat(name, val); }
103
110
  setFloat(name: string | number, val: number) {
104
- if(this.runtimeAnimatorController?.getFloat(name) !== val)
111
+ if (this.runtimeAnimatorController?.getFloat(name) !== val)
105
112
  this._parametersAreDirty = true;
113
+ if (debug) console.log("setFloat", name, val);
106
114
  this.runtimeAnimatorController?.setFloat(name, val);
107
115
  }
108
116
 
109
117
  /**@deprecated use getFloat */
110
118
  GetFloat(name: string | number) { return this.getFloat(name); }
111
119
  getFloat(name: string | number): number {
112
- return this.runtimeAnimatorController?.getFloat(name) ?? -1;
120
+ const res = this.runtimeAnimatorController?.getFloat(name) ?? -1;
121
+ if (debug) console.log("getFloat", name, res);
122
+ return res;
113
123
  }
114
124
 
115
125
  /**@deprecated use setInteger */
116
126
  SetInteger(name: string | number, val: number) { this.setInteger(name, val); }
117
127
  setInteger(name: string | number, val: number) {
118
- if(this.runtimeAnimatorController?.getInteger(name) !== val)
128
+ if (this.runtimeAnimatorController?.getInteger(name) !== val)
119
129
  this._parametersAreDirty = true;
130
+ if (debug) console.log("setInteger", name, val);
120
131
  this.runtimeAnimatorController?.setInteger(name, val);
121
132
  }
122
133
 
123
134
  /**@deprecated use getInteger */
124
135
  GetInteger(name: string | number) { return this.getInteger(name); }
125
136
  getInteger(name: string | number): number {
126
- return this.runtimeAnimatorController?.getInteger(name) ?? -1;
137
+ const res = this.runtimeAnimatorController?.getInteger(name) ?? -1;
138
+ if (debug) console.log("getInteger", name, res);
139
+ return res;
127
140
  }
128
141
 
129
142
  /**@deprecated use setTrigger */
130
143
  SetTrigger(name: string | number) { this.setTrigger(name); }
131
144
  setTrigger(name: string | number) {
132
- this.runtimeAnimatorController?.setTrigger(name);
133
145
  this._parametersAreDirty = true;
146
+ if (debug) console.log("setTrigger", name);
147
+ this.runtimeAnimatorController?.setTrigger(name);
134
148
  }
135
149
 
136
150
  /**@deprecated use resetTrigger */
137
151
  ResetTrigger(name: string | number) { this.resetTrigger(name); }
138
152
  resetTrigger(name: string | number) {
139
- this.runtimeAnimatorController?.resetTrigger(name);
140
153
  this._parametersAreDirty = true;
154
+ if (debug) console.log("resetTrigger", name);
155
+ this.runtimeAnimatorController?.resetTrigger(name);
141
156
  }
142
157
 
143
158
  /**@deprecated use getTrigger */
144
159
  GetTrigger(name: string | number) { this.getTrigger(name); }
145
160
  getTrigger(name: string | number) {
146
- this.runtimeAnimatorController?.getTrigger(name);
161
+ const res = this.runtimeAnimatorController?.getTrigger(name);
162
+ if (debug) console.log("getTrigger", name, res);
163
+ return res;
147
164
  }
148
165
 
149
166
  /**@deprecated use isInTransition */
@@ -156,6 +173,7 @@ export class Animator extends Behaviour {
156
173
  SetSpeed(speed: number) { return this.setSpeed(speed); }
157
174
  setSpeed(speed: number) {
158
175
  if (speed === this.speed) return;
176
+ if (debug) console.log("setSpeed", speed);
159
177
  this.speed = speed;
160
178
  this._animatorController?.setSpeed(speed);
161
179
  }
@@ -115,6 +115,7 @@ class TransformWatch {
115
115
  const original = this.obj.matrixWorld.multiplyMatrices.bind(this.obj.matrixWorld);
116
116
  const lastParentMatrix = new Matrix4();
117
117
  this.obj.matrixWorld["multiplyMatrices"] = (parent: Matrix4, matrix: Matrix4) => {
118
+ if (this.context.physics.engine?.isUpdating || this.mute) return original(parent, matrix);
118
119
  if (!lastParentMatrix.equals(parent)) {
119
120
  this.positionChanged = true;
120
121
  this.rotationChanged = true;