@needle-tools/engine 4.9.0-next.ce04b9f → 4.9.1

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 (48) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -1
  3. package/components.needle.json +1 -1
  4. package/dist/{needle-engine.bundle-DHAUN6T_.umd.cjs → needle-engine.bundle-BuTUhZAc.umd.cjs} +133 -133
  5. package/dist/{needle-engine.bundle-a5_4RZjH.min.js → needle-engine.bundle-DoywABnJ.min.js} +135 -135
  6. package/dist/{needle-engine.bundle-qHhlH-u4.js → needle-engine.bundle-O7rlGMn7.js} +6332 -6224
  7. package/dist/needle-engine.js +2 -2
  8. package/dist/needle-engine.min.js +1 -1
  9. package/dist/needle-engine.umd.cjs +1 -1
  10. package/lib/engine/engine_gameobject.d.ts +7 -7
  11. package/lib/engine/engine_gameobject.js +88 -27
  12. package/lib/engine/engine_gameobject.js.map +1 -1
  13. package/lib/engine/engine_networking_instantiate.js +23 -6
  14. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  15. package/lib/engine/engine_serialization_core.d.ts +2 -2
  16. package/lib/engine/engine_serialization_core.js +7 -7
  17. package/lib/engine/engine_serialization_core.js.map +1 -1
  18. package/lib/engine/engine_serialization_decorator.js +2 -1
  19. package/lib/engine/engine_serialization_decorator.js.map +1 -1
  20. package/lib/engine-components/Component.d.ts +8 -5
  21. package/lib/engine-components/Component.js +8 -5
  22. package/lib/engine-components/Component.js.map +1 -1
  23. package/lib/engine-components/Renderer.d.ts +7 -6
  24. package/lib/engine-components/Renderer.js.map +1 -1
  25. package/lib/engine-components/physics/Attractor.d.ts +12 -0
  26. package/lib/engine-components/physics/Attractor.js +14 -2
  27. package/lib/engine-components/physics/Attractor.js.map +1 -1
  28. package/lib/engine-components/web/Clickthrough.d.ts +1 -0
  29. package/lib/engine-components/web/Clickthrough.js +4 -2
  30. package/lib/engine-components/web/Clickthrough.js.map +1 -1
  31. package/lib/engine-components/web/CursorFollow.d.ts +9 -0
  32. package/lib/engine-components/web/CursorFollow.js +17 -0
  33. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  34. package/lib/engine-components/web/ScrollFollow.d.ts +66 -4
  35. package/lib/engine-components/web/ScrollFollow.js +155 -18
  36. package/lib/engine-components/web/ScrollFollow.js.map +1 -1
  37. package/package.json +3 -3
  38. package/plugins/vite/build.js +3 -0
  39. package/src/engine/engine_gameobject.ts +105 -38
  40. package/src/engine/engine_networking_instantiate.ts +21 -6
  41. package/src/engine/engine_serialization_core.ts +9 -9
  42. package/src/engine/engine_serialization_decorator.ts +2 -1
  43. package/src/engine-components/Component.ts +8 -5
  44. package/src/engine-components/Renderer.ts +12 -10
  45. package/src/engine-components/physics/Attractor.ts +14 -4
  46. package/src/engine-components/web/Clickthrough.ts +6 -2
  47. package/src/engine-components/web/CursorFollow.ts +17 -2
  48. package/src/engine-components/web/ScrollFollow.ts +174 -26
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollFollow.js","sourceRoot":"","sources":["../../../src/engine-components/web/ScrollFollow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScrollFollow.js","sourceRoot":"","sources":["../../../src/engine-components/web/ScrollFollow.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "4.9.0-next.ce04b9f",
3
+ "version": "4.9.1",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.",
5
5
  "main": "dist/needle-engine.min.js",
6
6
  "exports": {
@@ -93,7 +93,7 @@
93
93
  ],
94
94
  "dependencies": {
95
95
  "@dimforge/rapier3d-compat": "^0.19.0",
96
- "@needle-tools/gltf-progressive": "3.3.3",
96
+ "@needle-tools/gltf-progressive": "3.3.4",
97
97
  "@needle-tools/three-animation-pointer": "1.0.2",
98
98
  "@webxr-input-profiles/motion-controllers": "^1.0.0",
99
99
  "flatbuffers": "2.0.4",
@@ -168,4 +168,4 @@
168
168
  "module": "lib/needle-engine.js",
169
169
  "typings": "lib/needle-engine.d.ts",
170
170
  "types": "lib/needle-engine.d.ts"
171
- }
171
+ }
@@ -1,4 +1,7 @@
1
1
 
2
+ /**
3
+ * @returns {import('vite').Plugin}
4
+ */
2
5
  export const needleBuild = (command, config, userSettings) => {
3
6
 
4
7
  // TODO: need to set this when building a dist
@@ -1,4 +1,4 @@
1
- import { Bone, Object3D, Quaternion, SkinnedMesh, Vector3 } from "three";
1
+ import { Bone, Euler, Object3D, Quaternion, SkinnedMesh, Vector3 } from "three";
2
2
 
3
3
  import { $shadowDomOwner } from "../engine-components/ui/Symbols.js";
4
4
  import { type AssetReference } from "./engine_addressables.js";
@@ -11,7 +11,7 @@ import { processNewScripts } from "./engine_mainloop_utils.js";
11
11
  import { InstantiateIdProvider } from "./engine_networking_instantiate.js";
12
12
  import { assign, ISerializable } from "./engine_serialization_core.js";
13
13
  import { Context, registerComponent } from "./engine_setup.js";
14
- import { logHierarchy, setWorldPosition, setWorldQuaternion } from "./engine_three_utils.js";
14
+ import { getTempQuaternion, logHierarchy, setWorldPosition, setWorldQuaternion } from "./engine_three_utils.js";
15
15
  import { type Constructor, type GuidsMap, type IComponent as Component, type IComponent, IEventList, type IGameObject as GameObject, type UIDProvider } from "./engine_types.js";
16
16
  import { deepClone, getParam, tryFindObject } from "./engine_utils.js";
17
17
  import { apply } from "./js-extensions/index.js";
@@ -24,12 +24,12 @@ export type IInstantiateOptions = {
24
24
  //** parent guid or object */
25
25
  parent?: string | Object3D;
26
26
  /** position in local space. Set `keepWorldPosition` to true if this is world space */
27
- position?: Vector3;
27
+ position?: Vector3 | [number, number, number];
28
28
  /** for duplicatable parenting */
29
29
  keepWorldPosition?: boolean;
30
30
  /** rotation in local space. Set `keepWorldPosition` to true if this is world space */
31
- rotation?: Quaternion;
32
- scale?: Vector3;
31
+ rotation?: Quaternion | Euler | [number, number, number];
32
+ scale?: Vector3 | [number, number, number];
33
33
  /** if the instantiated object should be visible */
34
34
  visible?: boolean;
35
35
  context?: Context;
@@ -46,9 +46,9 @@ export class InstantiateOptions implements IInstantiateOptions {
46
46
  idProvider?: UIDProvider | undefined;
47
47
  parent?: string | undefined | Object3D;
48
48
  keepWorldPosition?: boolean
49
- position?: Vector3 | undefined;
50
- rotation?: Quaternion | undefined;
51
- scale?: Vector3 | undefined;
49
+ position?: Vector3 | [number, number, number] | undefined;
50
+ rotation?: Quaternion | Euler | [number, number, number] | undefined;
51
+ scale?: Vector3 | [number, number, number] | undefined;
52
52
  visible?: boolean | undefined;
53
53
  context?: Context | undefined;
54
54
  components?: boolean | undefined;
@@ -58,9 +58,9 @@ export class InstantiateOptions implements IInstantiateOptions {
58
58
  clone.idProvider = this.idProvider;
59
59
  clone.parent = this.parent;
60
60
  clone.keepWorldPosition = this.keepWorldPosition;
61
- clone.position = this.position?.clone();
62
- clone.rotation = this.rotation?.clone();
63
- clone.scale = this.scale?.clone();
61
+ clone.position = Array.isArray(this.position) ? [...this.position] : this.position?.clone();
62
+ clone.rotation = Array.isArray(this.rotation) ? [...this.rotation] : this.rotation?.clone();
63
+ clone.scale = Array.isArray(this.scale) ? [...this.scale] : this.scale?.clone();
64
64
  clone.visible = this.visible;
65
65
  clone.context = this.context;
66
66
  clone.components = this.components;
@@ -72,9 +72,9 @@ export class InstantiateOptions implements IInstantiateOptions {
72
72
  this.idProvider = other.idProvider;
73
73
  this.parent = other.parent;
74
74
  this.keepWorldPosition = other.keepWorldPosition;
75
- this.position = other.position?.clone();
76
- this.rotation = other.rotation?.clone();
77
- this.scale = other.scale?.clone();
75
+ this.position = Array.isArray(other.position) ? [...other.position] : other.position?.clone();
76
+ this.rotation = Array.isArray(other.rotation) ? [...other.rotation] : other.rotation?.clone();
77
+ this.scale = Array.isArray(other.scale) ? [...other.scale] : other.scale?.clone();
78
78
  this.visible = other.visible;
79
79
  this.context = other.context;
80
80
  this.components = other.components;
@@ -287,6 +287,8 @@ declare type ObjectCloneReference = {
287
287
 
288
288
 
289
289
  declare type InstantiateReferenceMap = Record<string, ObjectCloneReference>;
290
+ declare type NewObjectReferenceMap = Record<string, { target: object, key: string }>;
291
+
290
292
  /**
291
293
  * Provides access to the instantiated object and its clone
292
294
  */
@@ -325,13 +327,13 @@ export function instantiate(instance: AssetReference | GameObject | Object3D, op
325
327
  }
326
328
 
327
329
  const components: Array<Component> = [];
328
- const goMapping: InstantiateReferenceMap = {}; // used to resolve references on components to components on other gameobjects to their new counterpart
330
+ const referencemap: InstantiateReferenceMap = {}; // used to resolve references on components to components on other gameobjects to their new counterpart
329
331
  const skinnedMeshes: InstantiateReferenceMap = {}; // used to resolve skinned mesh bones
330
- const clone = internalInstantiate(context, instance, options, components, goMapping, skinnedMeshes);
332
+ const clone = internalInstantiate(context, instance, options, components, referencemap, skinnedMeshes);
331
333
 
332
334
  if (clone) {
333
- resolveReferences(goMapping);
334
- resolveAndBindSkinnedMeshBones(skinnedMeshes, goMapping);
335
+ resolveReferences(clone, referencemap);
336
+ resolveAndBindSkinnedMeshBones(skinnedMeshes, referencemap);
335
337
  }
336
338
 
337
339
  if (debug) {
@@ -426,19 +428,45 @@ function internalInstantiate(
426
428
  parent.add(clone);
427
429
  }
428
430
 
429
- // apply transform
431
+ // POSITION
430
432
  if (opts?.position) {
431
- setWorldPosition(clone, opts.position);
433
+ if (Array.isArray(opts.position)) {
434
+ const vec = new Vector3();
435
+ vec.fromArray(opts.position);
436
+ clone.worldPosition = vec;
437
+ }
438
+ else {
439
+ clone.worldPosition = opts.position;
440
+ }
432
441
  }
433
442
  else clone.position.copy(instance.position);
443
+
444
+ // ROTATION
434
445
  if (opts?.rotation) {
435
- setWorldQuaternion(clone, opts.rotation);
446
+ if (opts.rotation instanceof Quaternion)
447
+ clone.worldQuaternion = opts.rotation;
448
+ else if (opts.rotation instanceof Euler)
449
+ clone.worldQuaternion = getTempQuaternion().setFromEuler(opts.rotation);
450
+ else if (Array.isArray(opts.rotation)) {
451
+ const euler = new Euler();
452
+ euler.fromArray(opts.rotation);
453
+ clone.worldQuaternion = getTempQuaternion().setFromEuler(euler);
454
+ }
436
455
  }
437
456
  else clone.quaternion.copy(instance.quaternion);
457
+
458
+ // SCALE
438
459
  if (opts?.scale) {
439
- clone.scale.copy(opts.scale);
440
460
  // TODO MAJOR: replace with worldscale
441
461
  // clone.worldScale = opts.scale;
462
+ if (Array.isArray(opts.scale)) {
463
+ const vec = new Vector3();
464
+ vec.fromArray(opts.scale);
465
+ opts.scale = vec;
466
+ }
467
+ else {
468
+ clone.scale.copy(opts.scale);
469
+ }
442
470
  }
443
471
  else clone.scale.copy(instance.scale);
444
472
 
@@ -470,17 +498,7 @@ function internalInstantiate(
470
498
  for (let i = 0; i < components.length; i++) {
471
499
  const comp = components[i];
472
500
  const copy = new comp.constructor();
473
- assign(copy, comp, undefined, {
474
- // onAssign: (source, key, value) => {
475
- // if (typeof value === "object") {
476
- // const serializable = source as ISerializable;
477
- // if (serializable?.$serializedTypes?.[key]) {
478
- // console.debug("TODO CLONE", key, value);
479
- // }
480
- // }
481
- // return value;
482
- // }
483
- });
501
+ onAssignComponent(comp, copy, objectsMap);
484
502
  // make sure the original guid stays intact
485
503
  if (comp[editorGuidKeyName] !== undefined)
486
504
  copy[editorGuidKeyName] = comp[editorGuidKeyName];
@@ -501,7 +519,6 @@ function internalInstantiate(
501
519
  opts.parent = undefined;
502
520
  opts.visible = undefined;
503
521
  }
504
-
505
522
  for (const ch in instance.children) {
506
523
  const child = instance.children[ch];
507
524
  const newChild = internalInstantiate(context, child as GameObject, opts, componentsList, objectsMap, skinnedMeshesMap);
@@ -510,11 +527,59 @@ function internalInstantiate(
510
527
  clone.add(newChild);
511
528
  }
512
529
  }
513
-
514
530
  return clone;
531
+ }
532
+
515
533
 
534
+ function onAssignComponent(source: any, target: any, _newObjectsMap: InstantiateReferenceMap) {
535
+ assign(target, source, undefined, {
536
+ // onAssigned: (target, key, _oldValue, value) => {
537
+ // if (value !== null && typeof value === "object") {
538
+ // const serializable = target as ISerializable;
539
+ // if (serializable?.$serializedTypes?.[key]) {
540
+ // if (!(value instanceof Object3D)) {
541
+ // // let clone = null;
542
+ // // if ("clone" in value) {
543
+ // // if (canClone(value)) clone = (value as any).clone();
544
+ // // }
545
+ // // else {
546
+ // // clone = Object.assign(Object.create(Object.getPrototypeOf(value)), value);
547
+ // // }
548
+ // // if (clone) {
549
+ // // console.debug(key, { target, value, clone })
550
+ // // target[key] = clone;
551
+ // // findNestedReferences(clone, objectsMap);
552
+ // // }
553
+ // // else console.debug("Could not clone value for key", key, value);
554
+ // }
555
+ // else {
556
+ // console.log("ASSIGNED", value)
557
+ // }
558
+
559
+ // recursiveAssign(target, target[key], newObjectsMap);
560
+ // }
561
+
562
+ // }
563
+ // }
564
+ });
516
565
  }
517
566
 
567
+ // function findNestedReferences(object: object, map: InstantiateReferenceMap) {
568
+ // const keys = Object.keys(object);
569
+ // for (const key of keys) {
570
+ // const val = (object as any)[key];
571
+ // if (val instanceof Object3D) {
572
+ // if ("guid" in val && val.guid) {
573
+ // console.log("FOUND ", val.guid, val)
574
+ // map[val.guid] = { original: val, clone: null };
575
+ // }
576
+ // }
577
+ // else if (typeof val === "object" && val !== null) {
578
+ // findNestedReferences(val, map);
579
+ // }
580
+ // }
581
+ // }
582
+
518
583
  function resolveAndBindSkinnedMeshBones(
519
584
  skinnedMeshes: { [key: string]: ObjectCloneReference },
520
585
  newObjectsMap: { [key: string]: ObjectCloneReference }
@@ -599,13 +664,13 @@ function resolveAndBindSkinnedMeshBones(
599
664
 
600
665
  // }
601
666
 
602
- function resolveReferences(newObjectsMap: InstantiateReferenceMap) {
667
+ function resolveReferences(_newInstance: Object3D, newObjectsMap: InstantiateReferenceMap) {
603
668
  // for every object that is newly created we want to update references to their newly created counterparts
604
669
  // e.g. a collider instance referencing a rigidbody instance should be updated so that
605
670
  // the cloned collider does not reference the cloned rigidbody (instead of the original rigidbody)
606
671
  for (const key in newObjectsMap) {
607
672
  const val = newObjectsMap[key];
608
- const clone = val.clone as Object3D;
673
+ const clone = val.clone as Object3D | null;
609
674
  // resolve references
610
675
  if (clone?.isObject3D && clone?.userData?.components) {
611
676
  for (let i = 0; i < clone.userData.components.length; i++) {
@@ -706,4 +771,6 @@ function postProcessNewInstance(copy: Object3D, key: string, value: IComponent |
706
771
  return copy;
707
772
  }
708
773
  }
709
- }
774
+ }
775
+
776
+ // const canClone = (value: any) => value.isVector4 || value.isVector3 || value.isVector2 || value.isQuaternion || value.isEuler || value.isColor === true;
@@ -1,4 +1,4 @@
1
- import { Object3D, Quaternion, Vector3 } from "three";
1
+ import { Euler, Object3D, Quaternion, Vector3 } from "three";
2
2
  // https://github.com/uuidjs/uuid
3
3
  // v5 takes string and namespace
4
4
  import { v5 } from 'uuid';
@@ -254,12 +254,27 @@ export function syncInstantiate(object: GameObject | Object3D, opts: SyncInstant
254
254
  if (opts.deleteOnDisconnect === true)
255
255
  model.deleteStateOnDisconnect = true;
256
256
  if (originalOpts) {
257
- if (originalOpts.position)
258
- model.position = { x: originalOpts.position.x, y: originalOpts.position.y, z: originalOpts.position.z };
259
- if (originalOpts.rotation)
257
+ if (originalOpts.position) {
258
+ if (Array.isArray(originalOpts.position)) {
259
+ model.position = { x: originalOpts.position[0], y: originalOpts.position[1], z: originalOpts.position[2] };
260
+ }
261
+ else model.position = { x: originalOpts.position.x, y: originalOpts.position.y, z: originalOpts.position.z };
262
+ }
263
+ if (originalOpts.rotation) {
264
+ if (originalOpts.rotation instanceof Euler) {
265
+ originalOpts.rotation = new Quaternion().setFromEuler(originalOpts.rotation);
266
+ }
267
+ else if (originalOpts.rotation instanceof Array) {
268
+ originalOpts.rotation = new Quaternion().fromArray(originalOpts.rotation);
269
+ }
260
270
  model.rotation = { x: originalOpts.rotation.x, y: originalOpts.rotation.y, z: originalOpts.rotation.z, w: originalOpts.rotation.w };
261
- if (originalOpts.scale)
262
- model.scale = { x: originalOpts.scale.x, y: originalOpts.scale.y, z: originalOpts.scale.z };
271
+ }
272
+ if (originalOpts.scale) {
273
+ if (Array.isArray(originalOpts.scale)) {
274
+ model.scale = { x: originalOpts.scale[0], y: originalOpts.scale[1], z: originalOpts.scale[2] };
275
+ }
276
+ else model.scale = { x: originalOpts.scale.x, y: originalOpts.scale.y, z: originalOpts.scale.z };
277
+ }
263
278
  }
264
279
  if (!model.position)
265
280
  model.position = { x: go.position.x, y: go.position.y, z: go.position.z };
@@ -658,10 +658,10 @@ export const $isAssigningProperties = Symbol("assigned component properties");
658
658
  * @param key the key that is being assigned
659
659
  * @param value the value that is being assigned
660
660
  */
661
- type OnAssign = (source: object, key: string, value: any) => any;
661
+ type AssignedCallback = (source: object, key: string, oldValue: any, newValue: any) => any;
662
662
 
663
663
  /** Object.assign behaviour but check if property is writeable (e.g. getter only properties are skipped) */
664
- export function assign(target: any, source: any, info?: ImplementationInformation, opts?: { onAssign?: OnAssign }) {
664
+ export function assign(target: any, source: any, info?: ImplementationInformation, opts?: { onAssigned?: AssignedCallback }) {
665
665
  if (source === undefined || source === null) return;
666
666
  if (target === undefined || target === null) return;
667
667
 
@@ -699,13 +699,13 @@ export function assign(target: any, source: any, info?: ImplementationInformatio
699
699
  // arrow functions are defined as properties on the object
700
700
  continue;
701
701
  }
702
- if (!desc || desc.writable === true) {
703
- const value = opts?.onAssign ? opts.onAssign(source, key, source[key]) : source[key];
704
- target[key] = value;
705
- }
706
- else if (desc?.set !== undefined) {
707
- const value = opts?.onAssign ? opts.onAssign(source, key, source[key]) : source[key];
708
- target[key] = value;
702
+ if (!desc || desc.writable === true || desc.set !== undefined) {
703
+ const newValue = source[key];
704
+ const oldValue = target[key];
705
+ target[key] = newValue;
706
+ if (opts?.onAssigned) {
707
+ opts.onAssigned(target, key, oldValue, newValue);
708
+ }
709
709
  }
710
710
  }
711
711
  delete target[$isAssigningProperties];
@@ -27,7 +27,8 @@ export const serializable = function <T>(type?: Constructor<T> | null | Array<Co
27
27
 
28
28
  return function (_target: any, _propertyKey: string | { name: string }) {
29
29
  if (!_target) {
30
- console.error("Found @serializable decorator without a target");
30
+ const propertyName = typeof _propertyKey === 'string' ? _propertyKey : _propertyKey.name;
31
+ console.warn(`@serializable without a target at '${propertyName}'.`);
31
32
  return;
32
33
  }
33
34
  // The _propertyKey parameter is a string in TS4 with experimentalDecorators
@@ -543,22 +543,25 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
543
543
 
544
544
 
545
545
  /**
546
- * Needle Engine component base class. Component's are the main building blocks of the Needle Engine.
546
+ * Needle Engine component's are the main building blocks of the Needle Engine.
547
547
  * Derive from {@link Behaviour} to implement your own using the provided lifecycle methods.
548
548
  * Components can be added to any {@link Object3D} using {@link addComponent} or {@link GameObject.addComponent}.
549
549
  *
550
- * The most common lifecycle methods are {@link update}, {@link awake}, {@link start}, {@link onEnable}, {@link onDisable} and {@link onDestroy}.
550
+ * **Component lifecycle event methods:**
551
+ * {@link awake}, {@link start}, {@link onEnable}, {@link onDisable}, {@link onDestroy}, {@link earlyUpdate}, {@link update}, {@link lateUpdate}, {@link onBeforeRender}, {@link onAfterRender}.
551
552
  *
552
- * XR specific callbacks include {@link onEnterXR}, {@link onLeaveXR}, {@link onUpdateXR}, {@link onXRControllerAdded} and {@link onXRControllerRemoved}.
553
+ * **XR event methods:**
554
+ * {@link onEnterXR}, {@link onLeaveXR}, {@link onUpdateXR}, {@link onXRControllerAdded} and {@link onXRControllerRemoved}.
553
555
  *
554
- * To receive pointer events implement {@link onPointerDown}, {@link onPointerUp}, {@link onPointerEnter}, {@link onPointerExit} and {@link onPointerMove}.
556
+ * **Input event methods:**
557
+ * {@link onPointerDown}, {@link onPointerUp}, {@link onPointerEnter}, {@link onPointerExit} and {@link onPointerMove}.
555
558
  *
556
559
  * @example
557
560
  * ```typescript
558
561
  * import { Behaviour } from "@needle-tools/engine";
559
562
  * export class MyComponent extends Behaviour {
560
563
  * start() {
561
- * console.log("Hello World");
564
+ * console.log("Hello World", this.gameObject.name);
562
565
  * }
563
566
  * update() {
564
567
  * console.log("Frame", this.context.time.frame);
@@ -1,5 +1,5 @@
1
1
  import { getRaycastMesh } from "@needle-tools/gltf-progressive";
2
- import { AxesHelper, Material, Mesh, Object3D, SkinnedMesh, Texture, Vector4 } from "three";
2
+ import { AxesHelper, Material, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, MeshStandardMaterial, Object3D, RawShaderMaterial, ShaderMaterial, SkinnedMesh, Texture, Vector4 } from "three";
3
3
 
4
4
  import { showBalloonWarning } from "../engine/debug/index.js";
5
5
  import { getComponent, getOrAddComponent } from "../engine/engine_components.js";
@@ -48,6 +48,8 @@ export enum RenderState {
48
48
  Front = 2,
49
49
  }
50
50
 
51
+ type SharedMaterial = (Material & Partial<MeshStandardMaterial> & Partial<MeshPhysicalMaterial> & Partial<ShaderMaterial> & Partial<RawShaderMaterial>);
52
+
51
53
 
52
54
  // support sharedMaterials[index] assigning materials directly to the objects
53
55
  class SharedMaterialArray implements ISharedMaterials {
@@ -185,7 +187,7 @@ class SharedMaterialArray implements ISharedMaterials {
185
187
  this.changed = true;
186
188
  }
187
189
 
188
- private getMaterial(index: number): Material | null {
190
+ private getMaterial(index: number): SharedMaterial | null {
189
191
  index = this.resolveIndex(index);
190
192
  if (index < 0) return null;
191
193
  const obj = this._targets;
@@ -302,11 +304,11 @@ export class Renderer extends Behaviour implements IRenderer {
302
304
  return this._sharedMeshes;
303
305
  }
304
306
 
305
- get sharedMaterial(): Material {
306
- return this.sharedMaterials[0];
307
+ get sharedMaterial(): SharedMaterial {
308
+ return this.sharedMaterials[0] as SharedMaterial;
307
309
  }
308
310
 
309
- set sharedMaterial(mat: Material) {
311
+ set sharedMaterial(mat: SharedMaterial) {
310
312
  const cur = this.sharedMaterials[0];
311
313
  if (cur === mat) return;
312
314
  this.sharedMaterials[0] = mat;
@@ -314,12 +316,12 @@ export class Renderer extends Behaviour implements IRenderer {
314
316
  }
315
317
 
316
318
  /**@deprecated please use sharedMaterial */
317
- get material(): Material {
318
- return this.sharedMaterials[0];
319
+ get material(): SharedMaterial {
320
+ return this.sharedMaterials[0] as SharedMaterial;
319
321
  }
320
322
 
321
323
  /**@deprecated please use sharedMaterial */
322
- set material(mat: Material) {
324
+ set material(mat: SharedMaterial) {
323
325
  this.sharedMaterial = mat;
324
326
  }
325
327
 
@@ -329,10 +331,10 @@ export class Renderer extends Behaviour implements IRenderer {
329
331
  private _probeAnchorLastFrame?: Object3D;
330
332
 
331
333
  // this is just available during deserialization
332
- private set sharedMaterials(_val: Array<Material | null>) {
334
+ private set sharedMaterials(_val: Array<SharedMaterial | null>) {
333
335
  // TODO: elements in the array might be missing at the moment which leads to problems if an index is serialized
334
336
  if (!this._originalMaterials) {
335
- this._originalMaterials = _val as Material[];
337
+ this._originalMaterials = _val as SharedMaterial[];
336
338
  }
337
339
  else if (_val) {
338
340
  let didWarn = false;
@@ -1,9 +1,20 @@
1
+ import { serializable } from "../../engine/engine_serialization_decorator.js";
1
2
  import { Behaviour } from "../Component.js";
2
3
  import { Rigidbody } from "../RigidBody.js";
3
- import { serializable } from "../../engine/engine_serialization_decorator.js";
4
-
5
4
 
6
5
 
6
+ /**
7
+ * Used to attract Rigidbodies towards the position of this component.
8
+ * Add Rigidbodies to the `targets` array to have them be attracted.
9
+ * You can use negative strength values to create a repulsion effect.
10
+ *
11
+ * @example Attractor component attracting a Rigidbody
12
+ * ```ts
13
+ * const attractor = object.addComponent(Attractor);
14
+ * attractor.strength = 5; // positive value to attract
15
+ * attractor.radius = 10; // only attract within 10 units
16
+ * attractor.targets.push(rigidbody); // add the Rigidbody to be attracted
17
+ */
7
18
  export class Attractor extends Behaviour {
8
19
 
9
20
  @serializable()
@@ -15,11 +26,10 @@ export class Attractor extends Behaviour {
15
26
  @serializable(Rigidbody)
16
27
  targets: Rigidbody[] = [];
17
28
 
18
-
19
29
  update() {
20
30
  const wp = this.gameObject.worldPosition;
21
31
  const factor = -this.strength * this.context.time.deltaTime;
22
- this.targets.forEach(t => {
32
+ this.targets?.forEach(t => {
23
33
  if(!t) return;
24
34
  const dir = t.gameObject.worldPosition.sub(wp);
25
35
  const length = dir.length();
@@ -1,6 +1,6 @@
1
1
  import { NEPointerEvent } from "../../engine/engine_input.js";
2
- import { Behaviour } from "../Component.js";
3
2
  import { onStart } from "../../engine/engine_lifecycle_api.js";
3
+ import { Behaviour } from "../Component.js";
4
4
 
5
5
  // Automatically add ClickThrough component if "clickthrough" attribute is present on the needle-engine element
6
6
  onStart(ctx => {
@@ -23,6 +23,9 @@ onStart(ctx => {
23
23
  * @link Example https://stackblitz.com/~/github.com/needle-engine/sample-3d-over-html
24
24
  */
25
25
  export class ClickThrough extends Behaviour {
26
+
27
+ private _previousPointerEvents: string = 'all';
28
+
26
29
  onEnable() {
27
30
  // Register for pointer down and pointer move event
28
31
  this.context.input.addEventListener('pointerdown', this.onPointerEvent);
@@ -30,12 +33,13 @@ export class ClickThrough extends Behaviour {
30
33
  queue: 100,
31
34
  });
32
35
  window.addEventListener("touchend", this.onTouchEnd, { passive: true });
36
+ this._previousPointerEvents = this.context.domElement.style.pointerEvents;
33
37
  }
34
38
  onDisable() {
35
39
  this.context.input.removeEventListener('pointerdown', this.onPointerEvent);
36
40
  this.context.input.removeEventListener('pointermove', this.onPointerEvent);
37
41
  window.removeEventListener("touchend", this.onTouchEnd);
38
- this.context.domElement.style.pointerEvents = 'all';
42
+ this.context.domElement.style.pointerEvents = this._previousPointerEvents;
39
43
  }
40
44
  onPointerEnter() {
41
45
  /** do nothing, necessary to raycast children */
@@ -2,7 +2,9 @@ import { serializable } from "../../engine/engine_serialization_decorator.js";
2
2
  import { getTempVector } from "../../engine/engine_three_utils.js";
3
3
  import { Behaviour } from "../Component.js";
4
4
 
5
-
5
+ /**
6
+ * The CursorFollow component makes the object follow the cursor (or touch) position on screen.
7
+ */
6
8
  export class CursorFollow extends Behaviour {
7
9
 
8
10
  /**
@@ -12,13 +14,26 @@ export class CursorFollow extends Behaviour {
12
14
  @serializable()
13
15
  damping: number = 0;
14
16
 
17
+ /**
18
+ * If true, the initial distance to the camera is maintained when following the cursor.
19
+ * @default true
20
+ */
21
+ @serializable()
22
+ keepDistance: boolean = true;
23
+
24
+ awake() {
25
+ this._distance = -1;
26
+ }
15
27
 
16
28
  private _distance: number = -1;
29
+
17
30
  updateDistance() {
31
+ if (this.keepDistance && this._distance !== -1) {
32
+ return;
33
+ }
18
34
  this._distance = this.gameObject.worldPosition.distanceTo(this.context.mainCamera.worldPosition);
19
35
  }
20
36
 
21
-
22
37
  /** @internal */
23
38
  update() {
24
39
  // continuously update distance in case camera or object moves