@needle-tools/engine 4.10.5-next.a5d5bf4 → 4.11.0-next.358bed1
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/CHANGELOG.md +10 -0
- package/components.needle.json +1 -1
- package/dist/{gltf-progressive-B63NpN_i.js → gltf-progressive-CXVECA3a.js} +1 -1
- package/dist/{needle-engine.bundle-DPHrCUDs.umd.cjs → needle-engine.bundle-BX6JeEif.umd.cjs} +139 -139
- package/dist/{needle-engine.bundle-D56E0HeK.min.js → needle-engine.bundle-CDMrKOoV.min.js} +137 -137
- package/dist/{needle-engine.bundle-B2qX4saI.js → needle-engine.bundle-Dy5wgRLd.js} +6591 -6436
- package/dist/needle-engine.d.ts +14 -0
- package/dist/needle-engine.js +321 -320
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/codegen/register_types.js +2 -0
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_gizmos.js +2 -2
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_physics.js +44 -14
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/js-extensions/Object3D.d.ts +14 -0
- package/lib/engine/js-extensions/Object3D.js +13 -0
- package/lib/engine/js-extensions/Object3D.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +2 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.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 +7 -5
- package/lib/engine-components/RendererLightmap.js +29 -30
- package/lib/engine-components/RendererLightmap.js.map +1 -1
- package/lib/engine-components/SeeThrough.d.ts +70 -0
- package/lib/engine-components/SeeThrough.js +223 -0
- package/lib/engine-components/SeeThrough.js.map +1 -0
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/ui/Graphic.js +13 -1
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/RaycastUtils.js +5 -3
- package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
- package/lib/engine-components/utils/LookAt.js +4 -2
- package/lib/engine-components/utils/LookAt.js.map +1 -1
- package/lib/engine-components/web/Clickthrough.d.ts +2 -1
- package/lib/engine-components/web/Clickthrough.js +2 -1
- package/lib/engine-components/web/Clickthrough.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.d.ts +7 -1
- package/lib/engine-components/web/CursorFollow.js +35 -2
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/package.json +1 -1
- package/plugins/common/needle-engine.js +41 -0
- package/plugins/common/worker.js +130 -0
- package/plugins/vite/asap.js +5 -23
- package/plugins/vite/dependencies.js +21 -11
- package/plugins/vite/index.js +4 -0
- package/plugins/vite/needle-app.js +148 -0
- package/src/engine/codegen/register_types.ts +2 -0
- package/src/engine/engine_gizmos.ts +3 -3
- package/src/engine/engine_physics.ts +51 -14
- package/src/engine/js-extensions/Object3D.ts +32 -0
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +3 -1
- package/src/engine-components/Renderer.ts +38 -37
- package/src/engine-components/RendererLightmap.ts +31 -33
- package/src/engine-components/SeeThrough.ts +256 -0
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/ui/Graphic.ts +13 -1
- package/src/engine-components/ui/RaycastUtils.ts +9 -8
- package/src/engine-components/utils/LookAt.ts +4 -1
- package/src/engine-components/web/Clickthrough.ts +2 -1
- package/src/engine-components/web/CursorFollow.ts +48 -7
|
@@ -325,8 +325,12 @@ export class Physics {
|
|
|
325
325
|
const mesh = obj as Mesh | SkinnedMesh;
|
|
326
326
|
const geo = mesh.geometry;
|
|
327
327
|
|
|
328
|
+
if (obj.raycastAllowed === false) {
|
|
329
|
+
shouldIntersectObject = false;
|
|
330
|
+
}
|
|
331
|
+
|
|
328
332
|
// We need to run this first because of "EventSystem.testObject" implementation
|
|
329
|
-
if (options.testObject) {
|
|
333
|
+
if (shouldIntersectObject && options.testObject) {
|
|
330
334
|
const testResult = options.testObject?.(obj);
|
|
331
335
|
if (testResult === false) {
|
|
332
336
|
continue;
|
|
@@ -335,8 +339,7 @@ export class Physics {
|
|
|
335
339
|
shouldIntersectObject = false;
|
|
336
340
|
}
|
|
337
341
|
}
|
|
338
|
-
|
|
339
|
-
if (shouldIntersectObject) {
|
|
342
|
+
else if (shouldIntersectObject) {
|
|
340
343
|
if (!geo) {
|
|
341
344
|
shouldIntersectObject = false;
|
|
342
345
|
}
|
|
@@ -348,18 +351,24 @@ export class Physics {
|
|
|
348
351
|
|
|
349
352
|
|
|
350
353
|
if (shouldIntersectObject) {
|
|
351
|
-
const raycastMesh = getRaycastMesh(obj);
|
|
352
|
-
if (raycastMesh) mesh.geometry = raycastMesh as any;
|
|
353
354
|
const lastResultsCount = results.length;
|
|
355
|
+
const preference = obj.raycastPreference || "lod";
|
|
354
356
|
|
|
355
|
-
let usePrecise =
|
|
357
|
+
let usePrecise = preference !== "bounds";
|
|
356
358
|
if (options.precise === false) usePrecise = false;
|
|
357
359
|
usePrecise ||= geo.getAttribute("position")?.array?.length < 64;
|
|
358
360
|
if (mesh instanceof GroundedSkybox) {
|
|
359
361
|
usePrecise = false;
|
|
360
362
|
}
|
|
361
363
|
|
|
362
|
-
|
|
364
|
+
|
|
365
|
+
if (preference === "lod") {
|
|
366
|
+
const raycastMesh = getRaycastMesh(obj);
|
|
367
|
+
if (raycastMesh) mesh.geometry = raycastMesh as any;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
if (!usePrecise && boundsRaycast(mesh, raycaster, results)) {
|
|
363
372
|
// did handle raycast
|
|
364
373
|
}
|
|
365
374
|
else if (options.useAcceleratedRaycast !== false) {
|
|
@@ -369,13 +378,16 @@ export class Physics {
|
|
|
369
378
|
raycaster.intersectObject(mesh, false, results);
|
|
370
379
|
}
|
|
371
380
|
|
|
381
|
+
// Restore
|
|
382
|
+
mesh.geometry = geo;
|
|
383
|
+
|
|
384
|
+
// Debug
|
|
372
385
|
if (debugPhysics && results.length != lastResultsCount) {
|
|
373
386
|
const latestResult = results[results.length - 1];
|
|
374
|
-
|
|
375
|
-
Gizmos.
|
|
376
|
-
Gizmos.DrawWireMesh({ mesh: obj as Mesh, depthTest: false, duration: .2, color: col });
|
|
387
|
+
Gizmos.DrawWireSphere(latestResult.point, .1, 0x770000, 1, false);
|
|
388
|
+
Gizmos.DrawWireMesh({ mesh: obj as Mesh, depthTest: false, duration: .2, color: 0x770000 });
|
|
377
389
|
}
|
|
378
|
-
|
|
390
|
+
|
|
379
391
|
}
|
|
380
392
|
|
|
381
393
|
if (options.recursive !== false) {
|
|
@@ -481,7 +493,7 @@ const normalUpMatrix = new Matrix3();
|
|
|
481
493
|
/**
|
|
482
494
|
* @returns false if custom raycasting can not run, otherwise true
|
|
483
495
|
*/
|
|
484
|
-
function
|
|
496
|
+
function boundsRaycast(mesh: Mesh, raycaster: Raycaster, results: Intersection[]): boolean {
|
|
485
497
|
const originalComputeIntersectionsFn = mesh["_computeIntersections"];
|
|
486
498
|
if (!originalComputeIntersectionsFn) {
|
|
487
499
|
return false;
|
|
@@ -560,6 +572,9 @@ declare module 'three' {
|
|
|
560
572
|
|
|
561
573
|
|
|
562
574
|
namespace NEMeshBVH {
|
|
575
|
+
|
|
576
|
+
let failedToCreateMeshBVHWorker = 0;
|
|
577
|
+
|
|
563
578
|
export function runMeshBVHRaycast(method: Raycaster | Sphere, mesh: Mesh, results: Intersection[], context: Pick<Context, "xr">, options: { allowSlowRaycastFallback?: boolean }): boolean {
|
|
564
579
|
if (!mesh.geometry) {
|
|
565
580
|
return false;
|
|
@@ -618,6 +633,10 @@ namespace NEMeshBVH {
|
|
|
618
633
|
|| geom.index && geom.index?.["isInterleavedBufferAttribute"]) {
|
|
619
634
|
canUseWorker = false;
|
|
620
635
|
}
|
|
636
|
+
else if (failedToCreateMeshBVHWorker > 10) {
|
|
637
|
+
// if we failed to create a worker multiple times, don't try again
|
|
638
|
+
canUseWorker = false;
|
|
639
|
+
}
|
|
621
640
|
|
|
622
641
|
// if we have a worker use that
|
|
623
642
|
if (canUseWorker && _GenerateMeshBVHWorker) {
|
|
@@ -634,8 +653,23 @@ namespace NEMeshBVH {
|
|
|
634
653
|
}
|
|
635
654
|
// if there are no workers available, create a new one
|
|
636
655
|
if (!workerInstance && workerInstances.length < 3) {
|
|
637
|
-
|
|
638
|
-
|
|
656
|
+
try {
|
|
657
|
+
workerInstance = new _GenerateMeshBVHWorker();
|
|
658
|
+
workerInstances.push(workerInstance);
|
|
659
|
+
}
|
|
660
|
+
catch (err) {
|
|
661
|
+
const isSecurityError = err instanceof DOMException && err.name === "SecurityError";
|
|
662
|
+
if (isSecurityError) {
|
|
663
|
+
console.warn("Failed to create MeshBVH worker, falling back to main thread generation. This can happen when running from file://, if the browser does not support workers or if the browser is blocking workers for other reasons.");
|
|
664
|
+
console.debug(err);
|
|
665
|
+
failedToCreateMeshBVHWorker += 10;
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
console.error("Failed to create MeshBVH worker");
|
|
669
|
+
console.debug(err);
|
|
670
|
+
}
|
|
671
|
+
failedToCreateMeshBVHWorker++;
|
|
672
|
+
}
|
|
639
673
|
}
|
|
640
674
|
|
|
641
675
|
if (workerInstance != null && !workerInstance.running) {
|
|
@@ -794,6 +828,9 @@ namespace NEMeshBVH {
|
|
|
794
828
|
if (debugPhysics || isDevEnvironment()) {
|
|
795
829
|
console.warn("Failed to setup mesh bvh worker");
|
|
796
830
|
}
|
|
831
|
+
else {
|
|
832
|
+
console.debug("Failed to setup mesh bvh worker", _err);
|
|
833
|
+
}
|
|
797
834
|
})
|
|
798
835
|
.finally(() => {
|
|
799
836
|
isRequestingWorker = false;
|
|
@@ -34,6 +34,23 @@ declare module 'three' {
|
|
|
34
34
|
*/
|
|
35
35
|
hideFlags: HideFlags;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* If false the object will be ignored for raycasting (e.g. pointer events). Default is true.
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
raycastAllowed: boolean;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Set a raycast preference for the object:
|
|
45
|
+
* - `lod` will use the raycast mesh lod if available (default). This is usually a simplified mesh for raycasting.
|
|
46
|
+
* - `bounds` will use the bounding box of the object for raycasting. This is very fast but not very accurate.
|
|
47
|
+
* - `full` will use the full mesh for raycasting. This is the most accurate but also the slowest option.
|
|
48
|
+
*
|
|
49
|
+
* **NOTE:** Needle Engine's Raycast system will use Mesh BVH by default - so event 'full' is usually faster than default three.js raycasting.
|
|
50
|
+
*/
|
|
51
|
+
raycastPreference?: 'lod' | 'bounds' | 'full';
|
|
52
|
+
|
|
53
|
+
|
|
37
54
|
/**
|
|
38
55
|
* Add a Needle Engine component to the {@link Object3D}.
|
|
39
56
|
* @param comp The component instance or constructor to add.
|
|
@@ -242,6 +259,21 @@ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "activeSelf")) {
|
|
|
242
259
|
});
|
|
243
260
|
}
|
|
244
261
|
|
|
262
|
+
|
|
263
|
+
if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "raycastAllowed")) {
|
|
264
|
+
Object.defineProperty(Object3D.prototype, "raycastAllowed", {
|
|
265
|
+
get: function () {
|
|
266
|
+
return this.userData && this.userData.raycastAllowed !== false;
|
|
267
|
+
},
|
|
268
|
+
set: function (val: boolean) {
|
|
269
|
+
const self = this as Object3D;
|
|
270
|
+
if (!self.userData) self.userData = {};
|
|
271
|
+
self.userData.raycastAllowed = val;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
245
277
|
if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldPosition")) {
|
|
246
278
|
Object.defineProperty(Object3D.prototype, "worldPosition", {
|
|
247
279
|
get: function () {
|
|
@@ -4,14 +4,16 @@ import { MeshBVH } from 'three-mesh-bvh';
|
|
|
4
4
|
// Modified according to https://github.com/gkjohnson/three-mesh-bvh/issues/636#issuecomment-2209571751
|
|
5
5
|
import { WorkerBase } from "three-mesh-bvh/src/workers/utils/WorkerBase.js";
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
export class GenerateMeshBVHWorker extends WorkerBase {
|
|
8
9
|
|
|
9
10
|
constructor() {
|
|
10
11
|
// TODO: make mesh bvh worker "work" for prebundled CDN loading
|
|
11
12
|
// https://linear.app/needle/issue/NE-6572
|
|
12
13
|
// Also we don't use toplevel imports to not completely fail to load needle-engine where loading the worker fails
|
|
13
|
-
// const
|
|
14
|
+
// const meta_url = import.meta.url;
|
|
14
15
|
// const getWorker = () => new Worker(url, { type: 'module' })
|
|
16
|
+
// console.log(meta_url, url, getWorker());
|
|
15
17
|
super(new Worker(new URL('three-mesh-bvh/src/workers/generateMeshBVH.worker.js', import.meta.url), { type: 'module' }));
|
|
16
18
|
this.name = 'GenerateMeshBVHWorker';
|
|
17
19
|
|
|
@@ -359,7 +359,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
359
359
|
get sharedMaterials(): SharedMaterialArray {
|
|
360
360
|
|
|
361
361
|
// @ts-ignore (original materials will be set during deserialization)
|
|
362
|
-
if(this._originalMaterials === undefined) return null;
|
|
362
|
+
if (this._originalMaterials === undefined) return null;
|
|
363
363
|
|
|
364
364
|
// @ts-ignore during deserialization code might access this property *before* the setter and then create an empty array
|
|
365
365
|
if (this.__isDeserializing === true) return null;
|
|
@@ -476,41 +476,43 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
476
476
|
? this._lightmapTextureOverride
|
|
477
477
|
: this.context.lightmaps.tryGetLightmap(this.sourceId, this.lightmapIndex);
|
|
478
478
|
if (tex) {
|
|
479
|
-
if (!this._lightmaps)
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
479
|
+
if (!this._lightmaps) this._lightmaps = [];
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
const rm = new RendererLightmap(this);
|
|
483
|
+
rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
484
|
+
this._lightmaps.push(rm);
|
|
485
|
+
|
|
486
|
+
// if (type === "Mesh") {
|
|
487
|
+
// const mat = this.gameObject["material"];
|
|
488
|
+
// if (!mat?.isMeshBasicMaterial) {
|
|
489
|
+
// if (this._lightmaps.length <= 0) {
|
|
490
|
+
// }
|
|
491
|
+
// const rm = this._lightmaps[0];
|
|
492
|
+
// rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
493
|
+
// }
|
|
494
|
+
// else {
|
|
495
|
+
// if (mat)
|
|
496
|
+
// console.warn("Lightmapping is not supported on MeshBasicMaterial", mat.name)
|
|
497
|
+
// }
|
|
498
|
+
// }
|
|
499
|
+
// // for multi materials we need to loop through children
|
|
500
|
+
// // and then we add a lightmap renderer component to each of them
|
|
501
|
+
// else if (this.isMultiMaterialObject(this.gameObject) && this.sharedMaterials.length > 0) {
|
|
502
|
+
// for (let i = 0; i < this.gameObject.children.length; i++) {
|
|
503
|
+
// const child = this.gameObject.children[i];
|
|
504
|
+
// if (!child["material"]?.isMeshBasicMaterial) {
|
|
505
|
+
// let rm: RendererLightmap | undefined = undefined;
|
|
506
|
+
// if (i >= this._lightmaps.length) {
|
|
507
|
+
// rm = new RendererLightmap(child as Mesh, this.context);
|
|
508
|
+
// this._lightmaps.push(rm);
|
|
509
|
+
// }
|
|
510
|
+
// else
|
|
511
|
+
// rm = this._lightmaps[i];
|
|
512
|
+
// rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
513
|
+
// }
|
|
514
|
+
// }
|
|
515
|
+
// }
|
|
514
516
|
}
|
|
515
517
|
else {
|
|
516
518
|
if (debugRenderer) console.warn("Lightmap not found", this.sourceId, this.lightmapIndex);
|
|
@@ -742,7 +744,6 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
742
744
|
const environmentIntensity = this.context.mainCameraComponent?.environmentIntensity ?? 1;
|
|
743
745
|
material.envMapIntensity = Math.max(0, environmentIntensity * this.context.sceneLighting.environmentIntensity / factor);
|
|
744
746
|
}
|
|
745
|
-
|
|
746
747
|
if (this._lightmaps) {
|
|
747
748
|
for (const lm of this._lightmaps) {
|
|
748
749
|
lm.updateLightmapUniforms(material);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
|
|
2
|
-
import { Material, Mesh, MeshPhysicalMaterial, ShaderMaterial, Texture, Vector4, WebGLProgramParametersWithUniforms } from "three";
|
|
2
|
+
import { Group, Material, Mesh, MeshPhysicalMaterial, Object3D, ShaderMaterial, Texture, Vector4, WebGLProgramParametersWithUniforms } from "three";
|
|
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
|
|
|
@@ -77,42 +78,38 @@ export class RendererLightmap {
|
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.gameObject["Needle:Multimaterial-LightmapWarning"] = true;
|
|
83
|
-
console.warn("Lightmap on multimaterial object is not supported yet... please open a feature request on https://github.com/needle-tools/needle-engine-support if your project requires it");
|
|
84
|
-
}
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
81
|
+
const mesh = this.gameObject as unknown as (Mesh | Group);
|
|
82
|
+
this.ensureLightmapUvs(mesh);
|
|
87
83
|
|
|
88
|
-
|
|
84
|
+
for (let i = 0; i < this.renderer.sharedMaterials.length; i++) {
|
|
89
85
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
mesh.geometry.setAttribute("uv1", mesh.geometry.getAttribute("uv"));
|
|
86
|
+
const mat = this.renderer.sharedMaterials[i];
|
|
87
|
+
if (!mat) continue;
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
mats[i] = this.ensureLightmapMaterial(mats[i]);
|
|
89
|
+
const newMat = this.ensureLightmapMaterial(mat);
|
|
90
|
+
if (mat !== newMat) {
|
|
91
|
+
this.renderer.sharedMaterials[i] = newMat;
|
|
98
92
|
}
|
|
99
93
|
}
|
|
100
|
-
else {
|
|
101
|
-
this.gameObject.material = this.ensureLightmapMaterial(this.gameObject.material);
|
|
102
|
-
}
|
|
103
94
|
|
|
104
95
|
if (this.lightmapIndex >= 0 && this.lightmapTexture) {
|
|
105
96
|
// always on channel 1 for now. We could optimize this by passing the correct lightmap index along
|
|
106
97
|
this.lightmapTexture.channel = 1;
|
|
107
|
-
const mat
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
for (const mat of this.renderer.sharedMaterials) {
|
|
99
|
+
if (mat) this.assignLightmapTexture(mat);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
111
103
|
|
|
112
|
-
|
|
104
|
+
private ensureLightmapUvs(object: Object3D | Group | Mesh) {
|
|
105
|
+
if (object instanceof Mesh) {
|
|
106
|
+
if (!object.geometry.getAttribute("uv1")) {
|
|
107
|
+
object.geometry.setAttribute("uv1", object.geometry.getAttribute("uv"));
|
|
113
108
|
}
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
}
|
|
110
|
+
else if (object instanceof Group) {
|
|
111
|
+
for (const child of object.children) {
|
|
112
|
+
this.ensureLightmapUvs(child);
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
115
|
}
|
|
@@ -127,7 +124,7 @@ export class RendererLightmap {
|
|
|
127
124
|
if (material["NEEDLE:lightmap-material-version"] == undefined) {
|
|
128
125
|
if (debug) console.warn("Cloning material for lightmap " + material.name);
|
|
129
126
|
const mat: Material = material.clone();
|
|
130
|
-
if(!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
|
|
127
|
+
if (!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
|
|
131
128
|
material = mat;
|
|
132
129
|
material.onBeforeCompile = this.onBeforeCompile;
|
|
133
130
|
}
|
|
@@ -152,6 +149,7 @@ export class RendererLightmap {
|
|
|
152
149
|
|
|
153
150
|
// assign the lightmap
|
|
154
151
|
material.lightMap = this.lightmapTexture;
|
|
152
|
+
material.needsUpdate = true;
|
|
155
153
|
// store the version of the material
|
|
156
154
|
material["NEEDLE:lightmap-material-version"] = material.version;
|
|
157
155
|
}
|