@needle-tools/engine 3.8.0-alpha → 3.9.0-alpha
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 +8 -0
- package/dist/needle-engine.js +222 -221
- package/dist/needle-engine.light.js +222 -221
- package/dist/needle-engine.light.min.js +1 -1
- package/dist/needle-engine.light.umd.cjs +1 -1
- 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_context.js +1 -1
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_element.js +15 -8
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_element_overlay.d.ts +2 -1
- package/lib/engine/engine_element_overlay.js +38 -55
- package/lib/engine/engine_element_overlay.js.map +1 -1
- package/lib/engine/extensions/extensions.d.ts +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -1
- package/lib/engine-components/Renderer.js +14 -10
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/RendererLightmap.d.ts +4 -6
- package/lib/engine-components/RendererLightmap.js +35 -25
- package/lib/engine-components/RendererLightmap.js.map +1 -1
- 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/export/usdz/ThreeUSDZExporter.js +34 -30
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js +2 -0
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/USDZText.d.ts +2 -1
- package/lib/engine-components/export/usdz/extensions/USDZText.js +40 -3
- package/lib/engine-components/export/usdz/extensions/USDZText.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/USDZUI.d.ts +8 -0
- package/lib/engine-components/export/usdz/extensions/USDZUI.js +101 -0
- package/lib/engine-components/export/usdz/extensions/USDZUI.js.map +1 -0
- package/lib/engine-components/ui/Button.d.ts +1 -1
- package/lib/engine-components/ui/Button.js +4 -1
- package/lib/engine-components/ui/Button.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +2 -0
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Graphic.js +3 -3
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/webxr/WebXR.js +1 -1
- package/lib/engine-components/webxr/WebXR.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.js +2 -0
- package/src/engine/engine_context.ts +1 -1
- package/src/engine/engine_element.ts +15 -8
- package/src/engine/engine_element_overlay.ts +41 -52
- package/src/engine/extensions/extensions.ts +1 -1
- package/src/engine-components/Renderer.ts +19 -14
- package/src/engine-components/RendererLightmap.ts +36 -31
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +43 -37
- package/src/engine-components/export/usdz/USDZExporter.ts +2 -0
- package/src/engine-components/export/usdz/extensions/USDZText.ts +41 -1
- package/src/engine-components/export/usdz/extensions/USDZUI.ts +120 -0
- package/src/engine-components/ui/Button.ts +3 -1
- package/src/engine-components/ui/EventSystem.ts +3 -1
- package/src/engine-components/ui/Graphic.ts +3 -3
- package/src/engine-components/webxr/WebXR.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context } from "./engine_setup";
|
|
2
|
-
import { getParam, isMozillaXR } from "./engine_utils";
|
|
2
|
+
import { getParam, isMobileDevice, isMozillaXR } from "./engine_utils";
|
|
3
3
|
|
|
4
4
|
const debug = getParam("debugaroverlay");
|
|
5
5
|
export const arContainerClassName = "ar";
|
|
@@ -21,6 +21,7 @@ export class AROverlayHandler {
|
|
|
21
21
|
|
|
22
22
|
private _createdAROnlyElements: Array<any> = [];
|
|
23
23
|
private _reparentedObjects: Array<{ el: Element, previousParent: HTMLElement | null }> = [];
|
|
24
|
+
private contentElement: HTMLElement | null = null;
|
|
24
25
|
|
|
25
26
|
requestEndAR() {
|
|
26
27
|
this.onRequestedEndAR();
|
|
@@ -30,13 +31,16 @@ export class AROverlayHandler {
|
|
|
30
31
|
this.currentSession = session;
|
|
31
32
|
this.arContainer = overlayContainer;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
if (isMozillaXR()) {
|
|
35
|
+
const arElements = context.domElement!.children;
|
|
36
|
+
for (let i = 0; i < arElements?.length; i++) {
|
|
37
|
+
const el = arElements[i];
|
|
38
|
+
if (!el) return;
|
|
39
|
+
if (el === this.arContainer) return;
|
|
40
|
+
this._reparentedObjects.push({ el: el, previousParent: el.parentElement });
|
|
41
|
+
this.arContainer?.appendChild(el);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
40
44
|
|
|
41
45
|
const quit_Elements = overlayContainer.getElementsByClassName(quitARClassName);
|
|
42
46
|
if (!quit_Elements || quit_Elements.length <= 0) {
|
|
@@ -91,46 +95,20 @@ export class AROverlayHandler {
|
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
findOrCreateARContainer(element: HTMLElement): HTMLElement {
|
|
95
|
-
if(debug) console.log("findOrCreateARContainer");
|
|
96
|
-
// search in the needle-engine element
|
|
97
|
-
if (element.classList.contains(arContainerClassName)) {
|
|
98
|
-
if(debug) console.log("Found overlay container in needle-engine element");
|
|
99
|
-
return element;
|
|
100
|
-
}
|
|
101
|
-
if (element.shadowRoot) {
|
|
102
|
-
const el = element.shadowRoot!.querySelector(`.${arContainerClassName}`);
|
|
103
|
-
if (el) {
|
|
104
|
-
if(debug) console.log("Found overlay container in needle-engine element");
|
|
105
|
-
return el as HTMLElement;
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
98
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (arElements && arElements.length > 0){
|
|
112
|
-
if(debug) console.log("Found overlay container in document");
|
|
113
|
-
return arElements[0] as HTMLElement;
|
|
114
|
-
}
|
|
99
|
+
createOverlayContainer(needleEngineElement: HTMLElement): HTMLElement {
|
|
100
|
+
if (this.contentElement) return this.contentElement;
|
|
115
101
|
|
|
116
102
|
if (debug)
|
|
117
|
-
console.log("
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
display: flex;
|
|
127
|
-
visibility: visible;
|
|
128
|
-
z-index: 9999;
|
|
129
|
-
pointer-events: none;
|
|
130
|
-
// background: rgba(0,0,0,1);
|
|
131
|
-
`;
|
|
132
|
-
if(debug) this.createFallbackCloseARButton(element);
|
|
133
|
-
return this.appendElement(el, element) as HTMLElement;
|
|
103
|
+
console.log("Setup overlay container");
|
|
104
|
+
|
|
105
|
+
const contentElement = needleEngineElement.shadowRoot!.querySelector(".content") as HTMLElement;
|
|
106
|
+
this.contentElement = contentElement;
|
|
107
|
+
|
|
108
|
+
const overlaySlot = needleEngineElement.shadowRoot!.querySelector(".overlay-content");
|
|
109
|
+
if (overlaySlot) contentElement.appendChild(overlaySlot);
|
|
110
|
+
if (debug && !isMobileDevice()) this.createFallbackCloseARButton(contentElement);
|
|
111
|
+
return contentElement;
|
|
134
112
|
}
|
|
135
113
|
|
|
136
114
|
private onRequestedEndAR() {
|
|
@@ -147,30 +125,41 @@ export class AROverlayHandler {
|
|
|
147
125
|
private createFallbackCloseARButton(element: HTMLElement) {
|
|
148
126
|
const quitARSlot = document.createElement("slot");
|
|
149
127
|
quitARSlot.setAttribute("name", "quit-ar");
|
|
150
|
-
this.appendElement(quitARSlot, element);
|
|
151
|
-
if(debug) quitARSlot.addEventListener('click', () => console.log("Clicked fallback close button"));
|
|
152
|
-
quitARSlot.addEventListener('click', this.closeARCallback);
|
|
128
|
+
this.appendElement(quitARSlot, element);
|
|
129
|
+
if (debug) quitARSlot.addEventListener('click', () => console.log("Clicked fallback close button"));
|
|
130
|
+
quitARSlot.addEventListener('click', this.closeARCallback);
|
|
153
131
|
this._createdAROnlyElements.push(quitARSlot);
|
|
154
132
|
// for mozilla XR reparenting we have to make sure the close button is clickable so we set it on the element directly
|
|
155
133
|
// it's in general perhaps more safe to set it on the element to ensure it's clickable
|
|
156
134
|
quitARSlot.style.pointerEvents = "auto";
|
|
157
135
|
|
|
136
|
+
// we need another container to make sure the button is always on top
|
|
137
|
+
const fixedButtonContainer = document.createElement("div");
|
|
138
|
+
fixedButtonContainer.style.cssText = `
|
|
139
|
+
position: fixed;
|
|
140
|
+
top: 0;
|
|
141
|
+
right: 0;
|
|
142
|
+
z-index: 600;
|
|
143
|
+
pointer-events: all;
|
|
144
|
+
`;
|
|
145
|
+
this.appendElement(fixedButtonContainer, quitARSlot);
|
|
146
|
+
|
|
158
147
|
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
159
148
|
svg.classList.add("quit-ar-button");
|
|
160
149
|
svg.setAttribute('width', "38px");
|
|
161
150
|
svg.setAttribute('height', "38px");
|
|
162
|
-
|
|
151
|
+
fixedButtonContainer.appendChild(svg);
|
|
163
152
|
|
|
164
153
|
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
165
154
|
path.setAttribute('d', 'M 12,12 L 28,28 M 28,12 12,28');
|
|
166
|
-
path.setAttribute('stroke', '#
|
|
155
|
+
path.setAttribute('stroke', '#aaa');
|
|
167
156
|
path.setAttribute('stroke-width', "3px");
|
|
168
157
|
svg.appendChild(path);
|
|
169
|
-
if(debug) console.log("Created fallback close button", svg, element);
|
|
158
|
+
if (debug) console.log("Created fallback close button", svg, element);
|
|
170
159
|
}
|
|
171
160
|
|
|
172
161
|
private appendElement(element: Element, parent: HTMLElement) {
|
|
173
|
-
if(parent.shadowRoot) return parent.shadowRoot.appendChild(element);
|
|
162
|
+
if (parent.shadowRoot) return parent.shadowRoot.appendChild(element);
|
|
174
163
|
return parent.appendChild(element);
|
|
175
164
|
}
|
|
176
165
|
|
|
@@ -15,7 +15,7 @@ import { NEEDLE_render_objects } from "./NEEDLE_render_objects";
|
|
|
15
15
|
import { NEEDLE_progressive } from "./NEEDLE_progressive";
|
|
16
16
|
import { InternalUsageTrackerPlugin } from "./usage_tracker";
|
|
17
17
|
import { isUsageTrackingEnabled } from "../engine_assetdatabase";
|
|
18
|
-
import { GLTFLoaderPlugin } from "three/examples/jsm/loaders/GLTFLoader";
|
|
18
|
+
import { GLTFLoaderPlugin } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
19
19
|
// import { GLTFAnimationPointerExtension } from "three/examples/jsm/loaders/GLTFLoaderAnimationPointer";
|
|
20
20
|
|
|
21
21
|
// lazily import the GLTFAnimationPointerExtension in case it doesnt exist (e.g. using vanilla three)
|
|
@@ -352,7 +352,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
352
352
|
|
|
353
353
|
if (this.isMultiMaterialObject(this.gameObject)) {
|
|
354
354
|
for (const child of this.gameObject.children) {
|
|
355
|
-
this.context.addBeforeRenderListener(child, this.onBeforeRenderThree
|
|
355
|
+
this.context.addBeforeRenderListener(child, this.onBeforeRenderThree);
|
|
356
356
|
child.layers.mask = this.gameObject.layers.mask;
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -376,14 +376,13 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
376
376
|
}
|
|
377
377
|
// TODO: custom shader with sub materials
|
|
378
378
|
else if (this.isMeshOrSkinnedMesh(this.gameObject)) {
|
|
379
|
-
|
|
380
|
-
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree.bind(this));
|
|
379
|
+
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree);
|
|
381
380
|
|
|
382
381
|
if (this.renderOrder !== undefined && this.renderOrder.length > 0)
|
|
383
382
|
this.gameObject.renderOrder = this.renderOrder[0];
|
|
384
383
|
}
|
|
385
384
|
else {
|
|
386
|
-
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree
|
|
385
|
+
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree);
|
|
387
386
|
}
|
|
388
387
|
|
|
389
388
|
this.applyLightmapping();
|
|
@@ -415,7 +414,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
415
414
|
const mat = this.gameObject["material"];
|
|
416
415
|
if (!mat?.isMeshBasicMaterial) {
|
|
417
416
|
if (this._lightmaps.length <= 0) {
|
|
418
|
-
const rm = new RendererLightmap(this.gameObject, this.context);
|
|
417
|
+
const rm = new RendererLightmap(this.gameObject as any as Mesh, this.context);
|
|
419
418
|
this._lightmaps.push(rm);
|
|
420
419
|
}
|
|
421
420
|
const rm = this._lightmaps[0];
|
|
@@ -434,16 +433,12 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
434
433
|
if (!child["material"]?.isMeshBasicMaterial) {
|
|
435
434
|
let rm: RendererLightmap | undefined = undefined;
|
|
436
435
|
if (i >= this._lightmaps.length) {
|
|
437
|
-
rm = new RendererLightmap(child as
|
|
436
|
+
rm = new RendererLightmap(child as Mesh, this.context);
|
|
438
437
|
this._lightmaps.push(rm);
|
|
439
438
|
}
|
|
440
439
|
else
|
|
441
440
|
rm = this._lightmaps[i];
|
|
442
441
|
rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
443
|
-
// onBeforeRender is not called when the renderer is on a group
|
|
444
|
-
// this is an issue we probably also need to handle for custom shaders
|
|
445
|
-
// and need a better solution, but for now this fixes lightmaps for multimaterial objects
|
|
446
|
-
rm.bindOnBeforeRender();
|
|
447
442
|
}
|
|
448
443
|
}
|
|
449
444
|
}
|
|
@@ -529,7 +524,6 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
529
524
|
}
|
|
530
525
|
|
|
531
526
|
this.updateReflectionProbe();
|
|
532
|
-
|
|
533
527
|
}
|
|
534
528
|
|
|
535
529
|
onDisable() {
|
|
@@ -542,13 +536,22 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
542
536
|
|
|
543
537
|
onDestroy(): void {
|
|
544
538
|
this.handles = null;
|
|
539
|
+
|
|
540
|
+
if (this.isMultiMaterialObject(this.gameObject)) {
|
|
541
|
+
for (const child of this.gameObject.children) {
|
|
542
|
+
this.context.removeBeforeRenderListener(child, this.onBeforeRenderThree);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
this.context.removeBeforeRenderListener(this.gameObject, this.onBeforeRenderThree);
|
|
547
|
+
}
|
|
548
|
+
|
|
545
549
|
}
|
|
546
550
|
|
|
547
551
|
applyStencil() {
|
|
548
552
|
NEEDLE_render_objects.applyStencil(this);
|
|
549
553
|
}
|
|
550
554
|
|
|
551
|
-
|
|
552
555
|
onBeforeRender() {
|
|
553
556
|
if (!this.gameObject) {
|
|
554
557
|
return;
|
|
@@ -611,7 +614,9 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
611
614
|
}
|
|
612
615
|
|
|
613
616
|
}
|
|
614
|
-
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
private onBeforeRenderThree = (_renderer, _scene, _camera, _geometry, material, _group) => {
|
|
615
620
|
|
|
616
621
|
this.loadProgressiveTextures(material);
|
|
617
622
|
|
|
@@ -656,7 +661,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
656
661
|
|
|
657
662
|
if (this._lightmaps) {
|
|
658
663
|
for (const lm of this._lightmaps) {
|
|
659
|
-
lm.
|
|
664
|
+
lm.updateLightmapUniforms(material);
|
|
660
665
|
}
|
|
661
666
|
}
|
|
662
667
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behaviour, GameObject } from "./Component";
|
|
2
|
-
import { Material, Mesh, ShaderMaterial, Texture, Vector4 } from "three";
|
|
2
|
+
import { Material, Mesh, Shader, ShaderMaterial, Texture, Vector4 } from "three";
|
|
3
3
|
import { Context, OnRenderCallback } from "../engine/engine_setup";
|
|
4
4
|
import { getParam } from "../engine/engine_utils";
|
|
5
5
|
|
|
@@ -24,12 +24,12 @@ export class RendererLightmap {
|
|
|
24
24
|
lightmapScaleOffset: THREE.Vector4 = new Vector4(1, 1, 0, 0);
|
|
25
25
|
|
|
26
26
|
private context: Context;
|
|
27
|
-
private gameObject:
|
|
27
|
+
private gameObject: Mesh;
|
|
28
28
|
private lightmapTexture: Texture | null = null;
|
|
29
29
|
private lightmapScaleOffsetUniform = { value: new Vector4(1, 1, 0, 0) };
|
|
30
30
|
private lightmapUniform: { value: Texture | null } = { value: null };
|
|
31
31
|
|
|
32
|
-
constructor(gameObject:
|
|
32
|
+
constructor(gameObject: Mesh, context: Context) {
|
|
33
33
|
this.gameObject = gameObject;
|
|
34
34
|
this.context = context;
|
|
35
35
|
}
|
|
@@ -46,19 +46,21 @@ export class RendererLightmap {
|
|
|
46
46
|
this.applyLightmap();
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
updateLightmapUniforms(material: Material) {
|
|
50
|
+
const uniforms = material["uniforms"];
|
|
51
|
+
if (uniforms && uniforms.lightmap) {
|
|
52
|
+
this.lightmapScaleOffsetUniform.value = this.lightmapScaleOffset;
|
|
53
|
+
this.lightmapUniform.value = this.lightmapTexture;
|
|
54
|
+
uniforms.lightmap = this.lightmapUniform;
|
|
55
|
+
uniforms.lightmapScaleOffset = this.lightmapScaleOffsetUniform;
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
private onBeforeRenderThreeComplete = (_renderer, _scene, _camera, _geometry, material, _group) => {
|
|
55
|
-
this.onBeforeRenderThree(material);
|
|
56
|
-
}
|
|
57
59
|
|
|
58
60
|
private applyLightmap() {
|
|
59
|
-
|
|
60
61
|
if (this.gameObject.type === "Object3D") {
|
|
61
|
-
|
|
62
|
+
if (debug)
|
|
63
|
+
console.warn("Can not add lightmap. Is this object missing a renderer?", this.gameObject.name);
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -70,23 +72,27 @@ export class RendererLightmap {
|
|
|
70
72
|
console.assert(this.gameObject.type === "Mesh", "Lightmap only works on meshes", this);
|
|
71
73
|
|
|
72
74
|
const mesh = this.gameObject as unknown as Mesh;
|
|
73
|
-
// TODO: ensure uv2 exists
|
|
74
75
|
if (!mesh.geometry.getAttribute("uv1"))
|
|
75
76
|
mesh.geometry.setAttribute("uv1", mesh.geometry.getAttribute("uv"));
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
if (Array.isArray(this.gameObject.material)) {
|
|
79
|
+
const mats: Material[] = this.gameObject.material;
|
|
80
|
+
for (let i = 0; i < mats.length; i++) {
|
|
81
|
+
const mat = mats[i];
|
|
82
|
+
const cloned = mat.clone();
|
|
83
|
+
mats[i] = cloned;
|
|
84
|
+
cloned.onBeforeCompile = this.onBeforeCompile;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const mat: Material = this.gameObject.material.clone();
|
|
89
|
+
this.gameObject.material = mat;
|
|
90
|
+
this.gameObject.material.onBeforeCompile = this.onBeforeCompile;
|
|
91
|
+
}
|
|
86
92
|
|
|
87
93
|
if (this.lightmapIndex >= 0) {
|
|
88
94
|
const lightmap = this.lightmapTexture;
|
|
89
|
-
const mat = this.gameObject
|
|
95
|
+
const mat = this.gameObject.material as any;
|
|
90
96
|
if (mat && lightmap) {
|
|
91
97
|
if (!mat.uniforms) mat.uniforms = {};
|
|
92
98
|
mat.lightMap = lightmap;
|
|
@@ -95,15 +101,14 @@ export class RendererLightmap {
|
|
|
95
101
|
}
|
|
96
102
|
}
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
104
|
+
private onBeforeCompile = (shader: Shader, _) => {
|
|
105
|
+
if(debug) console.log("Lightmaps, before compile")
|
|
106
|
+
//@ts-ignore
|
|
107
|
+
shader.lightMapUv = "uv1";
|
|
108
|
+
this.lightmapScaleOffsetUniform.value = this.lightmapScaleOffset;
|
|
109
|
+
this.lightmapUniform.value = this.lightmapTexture;
|
|
110
|
+
shader.uniforms.lightmap = this.lightmapUniform;
|
|
111
|
+
shader.uniforms.lightmapScaleOffset = this.lightmapScaleOffsetUniform;
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
private setLightmapDebugMaterial() {
|
|
@@ -184,6 +184,7 @@ export { UIRootComponent } from "../ui/BaseUIComponent";
|
|
|
184
184
|
export { UsageMarker } from "../Interactable";
|
|
185
185
|
export { USDZExporter } from "../export/usdz/USDZExporter";
|
|
186
186
|
export { USDZText } from "../export/usdz/extensions/USDZText";
|
|
187
|
+
export { USDZUIExtension } from "../export/usdz/extensions/USDZUI";
|
|
187
188
|
export { VariantAction } from "../export/usdz/extensions/behavior/Actions";
|
|
188
189
|
export { VelocityOverLifetimeModule } from "../ParticleSystemModules";
|
|
189
190
|
export { VerticalLayoutGroup } from "../ui/Layout";
|
|
@@ -657,7 +657,7 @@ function addResources( object, context: USDZExporterContext ) {
|
|
|
657
657
|
|
|
658
658
|
if ( geometry ) {
|
|
659
659
|
|
|
660
|
-
if ( material.isMeshStandardMaterial
|
|
660
|
+
if ( material.isMeshStandardMaterial || material.isMeshBasicMaterial ) { // TODO convert unlit to lit+emissive
|
|
661
661
|
|
|
662
662
|
const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usd';
|
|
663
663
|
|
|
@@ -1124,7 +1124,7 @@ ${array.join( '' )}
|
|
|
1124
1124
|
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
-
function buildMaterial( material:
|
|
1127
|
+
function buildMaterial( material: MeshBasicMaterial, textures, quickLookCompatible = false ) {
|
|
1128
1128
|
|
|
1129
1129
|
// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
|
|
1130
1130
|
|
|
@@ -1182,7 +1182,9 @@ function buildMaterial( material: MeshStandardMaterial, textures, quickLookCompa
|
|
|
1182
1182
|
|
|
1183
1183
|
const needsTextureScale = mapType !== 'normal' && (color && (color.r !== 1 || color.g !== 1 || color.b !== 1 || opacity !== 1)) || false;
|
|
1184
1184
|
const needsNormalScaleAndBias = mapType === 'normal';
|
|
1185
|
-
const normalScaleValueString =
|
|
1185
|
+
const normalScaleValueString = material instanceof MeshStandardMaterial
|
|
1186
|
+
? (material.normalScale ? material.normalScale.x * 2 : 2).toFixed( PRECISION )
|
|
1187
|
+
: "1";
|
|
1186
1188
|
|
|
1187
1189
|
return `
|
|
1188
1190
|
${needsTextureTransform ? `def Shader "Transform2d_${mapType}" (
|
|
@@ -1254,72 +1256,76 @@ function buildMaterial( material: MeshStandardMaterial, textures, quickLookCompa
|
|
|
1254
1256
|
|
|
1255
1257
|
}
|
|
1256
1258
|
|
|
1257
|
-
if ( material.
|
|
1259
|
+
if ( material.aoMap ) {
|
|
1258
1260
|
|
|
1259
|
-
inputs.push( `${pad}
|
|
1261
|
+
inputs.push( `${pad}float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>` );
|
|
1260
1262
|
|
|
1261
|
-
samplers.push( buildTexture( material.
|
|
1263
|
+
samplers.push( buildTexture( material.aoMap, 'occlusion' ) );
|
|
1264
|
+
|
|
1265
|
+
}
|
|
1262
1266
|
|
|
1263
|
-
|
|
1267
|
+
if ( material.alphaMap ) {
|
|
1268
|
+
|
|
1269
|
+
inputs.push( `${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>` );
|
|
1270
|
+
inputs.push( `${pad}float inputs:opacityThreshold = 0.0001` );
|
|
1264
1271
|
|
|
1265
|
-
|
|
1272
|
+
samplers.push( buildTexture( material.alphaMap, 'opacity' ) );
|
|
1266
1273
|
|
|
1267
1274
|
} else {
|
|
1268
|
-
|
|
1269
|
-
inputs.push( `${pad}
|
|
1275
|
+
|
|
1276
|
+
inputs.push( `${pad}float inputs:opacity = ${effectiveOpacity}` );
|
|
1270
1277
|
|
|
1271
1278
|
}
|
|
1272
1279
|
|
|
1273
|
-
if ( material
|
|
1280
|
+
if ( material instanceof MeshStandardMaterial ) {
|
|
1274
1281
|
|
|
1275
|
-
|
|
1282
|
+
if ( material.emissiveMap ) {
|
|
1276
1283
|
|
|
1277
|
-
|
|
1284
|
+
inputs.push( `${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>` );
|
|
1278
1285
|
|
|
1279
|
-
|
|
1286
|
+
samplers.push( buildTexture( material.emissiveMap, 'emissive' ) );
|
|
1280
1287
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
inputs.push( `${pad}float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>` );
|
|
1288
|
+
} else if ( material.emissive?.getHex() > 0 ) {
|
|
1284
1289
|
|
|
1285
|
-
|
|
1290
|
+
inputs.push( `${pad}color3f inputs:emissiveColor = ${buildColor( material.emissive )}` );
|
|
1286
1291
|
|
|
1287
|
-
|
|
1292
|
+
} else {
|
|
1293
|
+
|
|
1294
|
+
inputs.push( `${pad}color3f inputs:emissiveColor = (0, 0, 0)` );
|
|
1288
1295
|
|
|
1289
|
-
|
|
1296
|
+
}
|
|
1290
1297
|
|
|
1291
|
-
|
|
1298
|
+
if ( material.normalMap ) {
|
|
1292
1299
|
|
|
1293
|
-
|
|
1300
|
+
inputs.push( `${pad}normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>` );
|
|
1294
1301
|
|
|
1295
|
-
|
|
1302
|
+
samplers.push( buildTexture( material.normalMap, 'normal' ) );
|
|
1296
1303
|
|
|
1297
|
-
|
|
1304
|
+
}
|
|
1298
1305
|
|
|
1299
|
-
|
|
1306
|
+
if ( material.roughnessMap && material.roughness === 1 ) {
|
|
1300
1307
|
|
|
1301
|
-
|
|
1308
|
+
inputs.push( `${pad}float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>` );
|
|
1302
1309
|
|
|
1303
|
-
|
|
1310
|
+
samplers.push( buildTexture( material.roughnessMap, 'roughness' ) );
|
|
1304
1311
|
|
|
1305
|
-
|
|
1312
|
+
} else {
|
|
1306
1313
|
|
|
1307
|
-
|
|
1314
|
+
inputs.push( `${pad}float inputs:roughness = ${material.roughness !== undefined ? material.roughness : 1 }` );
|
|
1308
1315
|
|
|
1309
|
-
|
|
1316
|
+
}
|
|
1310
1317
|
|
|
1311
|
-
|
|
1318
|
+
if ( material.metalnessMap && material.metalness === 1 ) {
|
|
1312
1319
|
|
|
1313
|
-
|
|
1320
|
+
inputs.push( `${pad}float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>` );
|
|
1314
1321
|
|
|
1315
|
-
|
|
1316
|
-
inputs.push( `${pad}float inputs:opacityThreshold = 0.0001` );
|
|
1322
|
+
samplers.push( buildTexture( material.metalnessMap, 'metallic' ) );
|
|
1317
1323
|
|
|
1318
|
-
|
|
1324
|
+
} else {
|
|
1319
1325
|
|
|
1320
|
-
|
|
1326
|
+
inputs.push( `${pad}float inputs:metallic = ${material.metalness !== undefined ? material.metalness : 0 }` );
|
|
1321
1327
|
|
|
1322
|
-
|
|
1328
|
+
}
|
|
1323
1329
|
|
|
1324
1330
|
}
|
|
1325
1331
|
|
|
@@ -16,6 +16,7 @@ import { hasProLicense } from "../../../engine/engine_license";
|
|
|
16
16
|
import { BehaviorExtension } from "./extensions/behavior/Behaviour";
|
|
17
17
|
import { AudioExtension } from "./extensions/behavior/AudioExtension";
|
|
18
18
|
import { TextExtension } from "./extensions/USDZText";
|
|
19
|
+
import { USDZUIExtension } from "./extensions/USDZUI";
|
|
19
20
|
import { Renderer } from "../../Renderer"
|
|
20
21
|
|
|
21
22
|
const debug = getParam("debugusdz");
|
|
@@ -97,6 +98,7 @@ export class USDZExporter extends Behaviour {
|
|
|
97
98
|
this.extensions.push(new BehaviorExtension());
|
|
98
99
|
this.extensions.push(new AudioExtension());
|
|
99
100
|
this.extensions.push(new TextExtension());
|
|
101
|
+
this.extensions.push(new USDZUIExtension());
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -146,8 +146,13 @@ export class TextExtension implements IUSDExporterExtension {
|
|
|
146
146
|
return "text";
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
// HACK we should clean this up, text export has moved to USDZUI.ts and is
|
|
150
|
+
// integrated into the hierarchy now
|
|
151
|
+
onExportObject(_object: Object3D, _model: USDObject, _context: USDZExporterContext) {
|
|
150
152
|
|
|
153
|
+
return;
|
|
154
|
+
|
|
155
|
+
/*
|
|
151
156
|
const text = GameObject.getComponent(object, Text);
|
|
152
157
|
if (text) {
|
|
153
158
|
const rt = GameObject.getComponent(object, RectTransform);
|
|
@@ -186,6 +191,41 @@ export class TextExtension implements IUSDExporterExtension {
|
|
|
186
191
|
textObj.writeTo(undefined, writer);
|
|
187
192
|
});
|
|
188
193
|
}
|
|
194
|
+
*/
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
exportText(object: Object3D, newModel: USDObject, _context: USDZExporterContext) {
|
|
198
|
+
|
|
199
|
+
const text = GameObject.getComponent(object, Text);
|
|
200
|
+
if (!text) return;
|
|
201
|
+
|
|
202
|
+
const rt = GameObject.getComponent(object, RectTransform);
|
|
203
|
+
let width = 100;
|
|
204
|
+
let height = 100;
|
|
205
|
+
if (rt) {
|
|
206
|
+
width = rt.width;
|
|
207
|
+
height = rt.height;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
newModel.matrix = rotateYAxisMatrix.clone();
|
|
211
|
+
if (rt) // Not ideal but works for now:
|
|
212
|
+
newModel.matrix.premultiply(invertX);
|
|
213
|
+
|
|
214
|
+
const color = new Color().copySRGBToLinear(text.color);
|
|
215
|
+
newModel.material = new MeshStandardMaterial({ color: color, emissive: color });
|
|
216
|
+
|
|
217
|
+
newModel.addEventListener("serialize", (writer: USDWriter, _context: USDZExporterContext) => {
|
|
218
|
+
let txt = text.text;
|
|
219
|
+
txt = txt.replace(/\n/g, "\\n");
|
|
220
|
+
const textObj = TextBuilder.multiLine(txt, width, height, HorizontalAlignment.center, VerticalAlignment.bottom, TextWrapMode.flowing);
|
|
221
|
+
this.setTextAlignment(textObj, text.alignment);
|
|
222
|
+
this.setOverflow(textObj, text);
|
|
223
|
+
if (newModel.material)
|
|
224
|
+
textObj.material = newModel.material;
|
|
225
|
+
textObj.pointSize = this.convertToTextSize(text.fontSize);
|
|
226
|
+
textObj.depth = .001;
|
|
227
|
+
textObj.writeTo(undefined, writer);
|
|
228
|
+
});
|
|
189
229
|
}
|
|
190
230
|
|
|
191
231
|
private convertToTextSize(pixel: number) {
|