@needle-tools/engine 4.10.4-next.f6dc9f2 → 4.10.5-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 (28) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/components.needle.json +1 -1
  3. package/dist/{gltf-progressive-DUR9TuAH.js → gltf-progressive-B63NpN_i.js} +1 -1
  4. package/dist/{gltf-progressive-Iy7aSAPk.umd.cjs → gltf-progressive-CHeORqEv.umd.cjs} +2 -2
  5. package/dist/{gltf-progressive-CoZbSfPR.min.js → gltf-progressive-D4Z_Khp3.min.js} +1 -1
  6. package/dist/{needle-engine.bundle-VwU3FjT0.umd.cjs → needle-engine.bundle-DM47n5Y6.umd.cjs} +117 -117
  7. package/dist/{needle-engine.bundle-BLWB7qT-.js → needle-engine.bundle-D_w8FYF5.js} +2204 -2198
  8. package/dist/{needle-engine.bundle-qakLfSFW.min.js → needle-engine.bundle-DpOu8NmD.min.js} +114 -114
  9. package/dist/needle-engine.js +3 -3
  10. package/dist/needle-engine.min.js +1 -1
  11. package/dist/needle-engine.umd.cjs +1 -1
  12. package/lib/engine/debug/debug_overlay.js +1 -1
  13. package/lib/engine/engine_context.js +1 -0
  14. package/lib/engine/engine_context.js.map +1 -1
  15. package/lib/engine-components/Renderer.js +33 -32
  16. package/lib/engine-components/Renderer.js.map +1 -1
  17. package/lib/engine-components/RendererLightmap.d.ts +6 -5
  18. package/lib/engine-components/RendererLightmap.js +35 -21
  19. package/lib/engine-components/RendererLightmap.js.map +1 -1
  20. package/lib/engine-components/web/CursorFollow.d.ts +16 -2
  21. package/lib/engine-components/web/CursorFollow.js +41 -7
  22. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  23. package/package.json +3 -3
  24. package/src/engine/debug/debug_overlay.ts +1 -1
  25. package/src/engine/engine_context.ts +1 -0
  26. package/src/engine-components/Renderer.ts +38 -37
  27. package/src/engine-components/RendererLightmap.ts +42 -24
  28. package/src/engine-components/web/CursorFollow.ts +46 -9
@@ -3,6 +3,7 @@ import { Material, Mesh, MeshPhysicalMaterial, ShaderMaterial, Texture, Vector4,
3
3
 
4
4
  import type { Context } from "../engine/engine_setup.js";
5
5
  import { getParam } from "../engine/engine_utils.js";
6
+ import { type Renderer } from "./Renderer.js";
6
7
 
7
8
  const debug = getParam("debuglightmaps");
8
9
 
@@ -31,15 +32,15 @@ export class RendererLightmap {
31
32
  private lightmapIndex: number = -1;
32
33
  private lightmapScaleOffset: Vector4 = new Vector4(1, 1, 0, 0);
33
34
 
34
- private context: Context;
35
- private gameObject: Mesh;
35
+ private readonly renderer: Renderer;
36
+ private get context(): Context { return this.renderer.context; }
37
+ private get gameObject() { return this.renderer.gameObject; }
36
38
  private lightmapTexture: Texture | null = null;
37
39
  private lightmapScaleOffsetUniform = { value: new Vector4(1, 1, 0, 0) };
38
40
  private lightmapUniform: { value: Texture | null } = { value: null };
39
41
 
40
- constructor(gameObject: Mesh, context: Context) {
41
- this.gameObject = gameObject;
42
- this.context = context;
42
+ constructor(renderer: Renderer) {
43
+ this.renderer = renderer;
43
44
  }
44
45
 
45
46
  init(lightmapIndex: number, lightmapScaleOffset: Vector4, lightmapTexture: Texture) {
@@ -55,7 +56,7 @@ export class RendererLightmap {
55
56
  console.log("Lightmap:", this.gameObject.name, lightmapIndex, "\nScaleOffset:", lightmapScaleOffset, "\nTexture:", lightmapTexture)
56
57
  this.setLightmapDebugMaterial();
57
58
  }
58
- else if(debug) console.log("Use debuglightmaps=show to render lightmaps only in the scene.")
59
+ else if (debug) console.log("Use debuglightmaps=show to render lightmaps only in the scene.")
59
60
  this.applyLightmap();
60
61
  }
61
62
 
@@ -88,32 +89,49 @@ export class RendererLightmap {
88
89
  console.assert(this.gameObject.type === "Mesh", "Lightmap only works on meshes", this);
89
90
 
90
91
  const mesh = this.gameObject as unknown as Mesh;
91
- if (!mesh.geometry.getAttribute("uv1"))
92
+ if (!mesh.geometry.getAttribute("uv1")) {
92
93
  mesh.geometry.setAttribute("uv1", mesh.geometry.getAttribute("uv"));
94
+ }
95
+
96
+ for (let i = 0; i < this.renderer.sharedMaterials.length; i++) {
93
97
 
94
- if (Array.isArray(this.gameObject.material)) {
95
- const mats: Material[] = this.gameObject.material;
96
- for (let i = 0; i < mats.length; i++) {
97
- mats[i] = this.ensureLightmapMaterial(mats[i]);
98
+ const mat = this.renderer.sharedMaterials[i];
99
+ if (!mat) continue;
100
+
101
+ const newMat = this.ensureLightmapMaterial(mat);
102
+ if (mat !== newMat) {
103
+ this.renderer.sharedMaterials[i] = newMat;
98
104
  }
99
- }
100
- else {
101
- this.gameObject.material = this.ensureLightmapMaterial(this.gameObject.material);
105
+
102
106
  }
103
107
 
108
+ // if (Array.isArray(this.gameObject.material)) {
109
+ // const mats: Material[] = this.gameObject.material;
110
+ // for (let i = 0; i < mats.length; i++) {
111
+ // mats[i] = this.ensureLightmapMaterial(mats[i]);
112
+ // }
113
+ // }
114
+ // else {
115
+ // this.gameObject.material = this.ensureLightmapMaterial(this.gameObject.material);
116
+ // }
117
+
104
118
  if (this.lightmapIndex >= 0 && this.lightmapTexture) {
105
119
  // always on channel 1 for now. We could optimize this by passing the correct lightmap index along
106
120
  this.lightmapTexture.channel = 1;
107
- const mat = this.gameObject.material;
108
- if (Array.isArray(mat)) {
109
- for (const entry of mat) {
110
- this.assignLightmapTexture(entry as any);
111
-
112
- }
113
- }
114
- else if (mat) {
115
- this.assignLightmapTexture(mat);
121
+ for (const mat of this.renderer.sharedMaterials) {
122
+ if (mat) this.assignLightmapTexture(mat);
116
123
  }
124
+
125
+ // const mat = this.gameObject.material;
126
+ // if (Array.isArray(mat)) {
127
+ // for (const entry of mat) {
128
+ // this.assignLightmapTexture(entry as any);
129
+
130
+ // }
131
+ // }
132
+ // else if (mat) {
133
+ // this.assignLightmapTexture(mat);
134
+ // }
117
135
  }
118
136
  }
119
137
 
@@ -127,7 +145,7 @@ export class RendererLightmap {
127
145
  if (material["NEEDLE:lightmap-material-version"] == undefined) {
128
146
  if (debug) console.warn("Cloning material for lightmap " + material.name);
129
147
  const mat: Material = material.clone();
130
- if(!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
148
+ if (!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
131
149
  material = mat;
132
150
  material.onBeforeCompile = this.onBeforeCompile;
133
151
  }
@@ -3,7 +3,10 @@ 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.
6
+ * The CursorFollow component makes the object follow the cursor (or touch) position on screen.
7
+ *
8
+ * - Example: [Look At Cursor sample](https://engine.needle.tools/samples/look-at-cursor-interactive-3d-header/). This sample combines the CursorFollow component with a LookAt component to create an interactive 3D header that looks at the cursor.
9
+ *
7
10
  * @category Web
8
11
  * @group Components
9
12
  * @component
@@ -17,6 +20,13 @@ export class CursorFollow extends Behaviour {
17
20
  @serializable()
18
21
  damping: number = 0;
19
22
 
23
+ /**
24
+ * When enabled the object will follow the cursor even outside of the needle-engine canvas. This is useful for example for look at effects where you have a small needle-engine element on your page and you want the 3D object to keep looking at the cursor even when it's outside of the canvas.
25
+ * @default true
26
+ */
27
+ @serializable()
28
+ useFullPage: boolean = true;
29
+
20
30
  /**
21
31
  * If true, the initial distance to the camera is maintained when following the cursor.
22
32
  * @default true
@@ -24,31 +34,58 @@ export class CursorFollow extends Behaviour {
24
34
  @serializable()
25
35
  keepDistance: boolean = true;
26
36
 
37
+
38
+ private _distance: number = -1;
39
+ updateDistance(force:boolean = false) {
40
+ if (!force && (this.keepDistance && this._distance !== -1)) {
41
+ return;
42
+ }
43
+ this._distance = this.gameObject.worldPosition.distanceTo(this.context.mainCamera.worldPosition);
44
+ }
45
+
46
+ /** @internal */
27
47
  awake() {
28
48
  this._distance = -1;
29
49
  }
30
50
 
31
- private _distance: number = -1;
51
+ onEnable(): void {
52
+ this._distance = -1;
53
+ window.addEventListener('pointermove', this._onPointerMove);
54
+ }
55
+ onDisable(): void {
56
+ window.removeEventListener('pointermove', this._onPointerMove);
57
+ }
32
58
 
33
- updateDistance() {
34
- if (this.keepDistance && this._distance !== -1) {
35
- return;
36
- }
37
- this._distance = this.gameObject.worldPosition.distanceTo(this.context.mainCamera.worldPosition);
59
+ private _ndc_x = 0;
60
+ private _ndc_y = 0;
61
+
62
+ private _onPointerMove = (e:PointerEvent) => {
63
+ if(!this.useFullPage) return;
64
+ const x = e.clientX;
65
+ const y = e.clientY;
66
+ const domx = this.context.domX;
67
+ const domy = this.context.domY;
68
+ const domw = this.context.domWidth;
69
+ const domh = this.context.domHeight;
70
+ this._ndc_x = (x - domx) / domw * 2 - 1;
71
+ this._ndc_y = - (y - domy) / domh * 2 + 1;
38
72
  }
39
73
 
74
+
40
75
  /** @internal */
41
76
  update() {
42
77
  // continuously update distance in case camera or object moves
43
78
  this.updateDistance();
44
79
 
80
+ const x = this.useFullPage ? this._ndc_x : this.context.input.mousePositionRC.x;
81
+ const y = this.useFullPage ? this._ndc_y : this.context.input.mousePositionRC.y;
82
+
45
83
  // follow cursor in screenspace but maintain initial distance from camera
46
- const cursor = this.context.input.mousePositionRC;
47
84
  const camera = this.context.mainCamera;
48
85
  const cameraPosition = camera.worldPosition;
49
86
 
50
87
  // create ray from camera through cursor position
51
- const rayDirection = getTempVector(cursor.x, cursor.y, 1).unproject(camera);
88
+ const rayDirection = getTempVector(x, y, 1).unproject(camera);
52
89
  rayDirection.sub(cameraPosition).normalize();
53
90
 
54
91
  // position object at initial distance along the ray