@needle-tools/engine 4.10.4 → 4.10.5-next.11705bc
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.
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-CQzbMO5P.js → needle-engine.bundle-BLW60mqN.js} +2204 -2198
- package/dist/{needle-engine.bundle-ITqL-yYC.min.js → needle-engine.bundle-BY5d8vBy.min.js} +114 -114
- package/dist/{needle-engine.bundle-DfqZ3U87.umd.cjs → needle-engine.bundle-CB9LSUuz.umd.cjs} +117 -117
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/debug/debug_overlay.js +1 -1
- package/lib/engine/engine_context.js +1 -0
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine-components/Renderer.js +33 -32
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/RendererLightmap.d.ts +6 -5
- package/lib/engine-components/RendererLightmap.js +35 -21
- package/lib/engine-components/RendererLightmap.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.d.ts +16 -2
- package/lib/engine-components/web/CursorFollow.js +41 -7
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/package.json +2 -2
- package/src/engine/debug/debug_overlay.ts +1 -1
- package/src/engine/engine_context.ts +1 -0
- package/src/engine-components/Renderer.ts +38 -37
- package/src/engine-components/RendererLightmap.ts +42 -24
- 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
|
|
35
|
-
private
|
|
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(
|
|
41
|
-
this.
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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(
|
|
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
|