@needle-tools/engine 3.7.7-beta → 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 +16 -0
- package/dist/needle-engine.js +473 -87019
- package/dist/needle-engine.light.js +473 -84478
- package/dist/needle-engine.light.min.js +1 -5805
- package/dist/needle-engine.light.umd.cjs +1 -5805
- package/dist/needle-engine.min.js +1 -5818
- package/dist/needle-engine.umd.cjs +1 -5818
- package/lib/engine/codegen/register_types.js +2 -0
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/debug/debug.d.ts +1 -1
- package/lib/engine/engine_context.d.ts +3 -1
- package/lib/engine/engine_context.js +18 -13
- 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/engine_lightdata.js +6 -7
- package/lib/engine/engine_lightdata.js.map +1 -1
- package/lib/engine/engine_networking_utils.d.ts +1 -1
- package/lib/engine/engine_networking_utils.js.map +1 -1
- package/lib/engine/engine_scenelighting.js +5 -5
- package/lib/engine/engine_scenelighting.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js +3 -3
- package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_render_objects.js +1 -1
- package/lib/engine/extensions/NEEDLE_render_objects.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js +4 -1
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
- package/lib/engine/extensions/extensions.d.ts +1 -1
- package/lib/engine/extensions/extensions.js +17 -3
- package/lib/engine/extensions/extensions.js.map +1 -1
- package/lib/engine-components/Camera.js +3 -3
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/GroundProjection.js +1 -1
- package/lib/engine-components/GroundProjection.js.map +1 -1
- package/lib/engine-components/Light.js +58 -50
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +1 -1
- package/lib/engine-components/OrbitControls.js +4 -3
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +2 -1
- package/lib/engine-components/ParticleSystem.js +11 -1
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.js +3 -3
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -1
- package/lib/engine-components/Renderer.js +16 -13
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/RendererLightmap.d.ts +5 -8
- package/lib/engine-components/RendererLightmap.js +50 -39
- 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.d.ts +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/BaseUIComponent.js +4 -0
- package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
- 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/Canvas.js +9 -1
- package/lib/engine-components/ui/Canvas.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/WebARCameraBackground.d.ts +1 -1
- package/lib/engine-components/webxr/WebARCameraBackground.js +2 -2
- package/lib/engine-components/webxr/WebARCameraBackground.js.map +1 -1
- package/lib/engine-components/webxr/WebXR.js +7 -6
- package/lib/engine-components/webxr/WebXR.js.map +1 -1
- package/lib/engine-components/webxr/WebXRPlaneTracking.d.ts +1 -1
- package/package.json +5 -5
- package/src/engine/codegen/register_types.js +2 -0
- package/src/engine/engine_context.ts +21 -14
- package/src/engine/engine_element.ts +15 -8
- package/src/engine/engine_element_overlay.ts +41 -52
- package/src/engine/engine_lightdata.ts +6 -8
- package/src/engine/engine_networking_utils.ts +1 -1
- package/src/engine/engine_scenelighting.ts +5 -5
- package/src/engine/extensions/NEEDLE_lightmaps.ts +3 -3
- package/src/engine/extensions/NEEDLE_render_objects.ts +10 -8
- package/src/engine/extensions/NEEDLE_techniques_webgl.ts +5 -1
- package/src/engine/extensions/extensions.ts +19 -4
- package/src/engine-components/Camera.ts +3 -3
- package/src/engine-components/GroundProjection.ts +1 -1
- package/src/engine-components/Light.ts +62 -57
- package/src/engine-components/OrbitControls.ts +4 -3
- package/src/engine-components/ParticleSystem.ts +14 -0
- package/src/engine-components/ReflectionProbe.ts +3 -3
- package/src/engine-components/Renderer.ts +21 -17
- package/src/engine-components/RendererLightmap.ts +55 -49
- 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/BaseUIComponent.ts +5 -0
- package/src/engine-components/ui/Button.ts +3 -1
- package/src/engine-components/ui/Canvas.ts +7 -1
- package/src/engine-components/ui/EventSystem.ts +3 -1
- package/src/engine-components/ui/Graphic.ts +3 -3
- package/src/engine-components/webxr/WebARCameraBackground.ts +3 -3
- package/src/engine-components/webxr/WebXR.ts +7 -7
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Behaviour, GameObject } from "./Component";
|
|
2
|
-
import
|
|
3
|
-
import { Texture } from "three";
|
|
2
|
+
import { Material, Mesh, Shader, ShaderMaterial, Texture, Vector4 } from "three";
|
|
4
3
|
import { Context, OnRenderCallback } from "../engine/engine_setup";
|
|
4
|
+
import { getParam } from "../engine/engine_utils";
|
|
5
|
+
|
|
6
|
+
const debug = getParam("debuglightmaps");
|
|
5
7
|
|
|
6
8
|
// this component is automatically added by the Renderer if the object has lightmap uvs AND we have a lightmap
|
|
7
9
|
// for multimaterial objects GLTF exports a "Group" with the renderer component
|
|
@@ -19,20 +21,20 @@ export class RendererLightmap {
|
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
lightmapIndex: number = -1;
|
|
22
|
-
lightmapScaleOffset: THREE.Vector4 = new
|
|
24
|
+
lightmapScaleOffset: THREE.Vector4 = new Vector4(1, 1, 0, 0);
|
|
23
25
|
|
|
24
26
|
private context: Context;
|
|
25
|
-
private gameObject:
|
|
26
|
-
private lightmapTexture:
|
|
27
|
-
private lightmapScaleOffsetUniform = { value: new
|
|
28
|
-
private lightmapUniform: { value:
|
|
27
|
+
private gameObject: Mesh;
|
|
28
|
+
private lightmapTexture: Texture | null = null;
|
|
29
|
+
private lightmapScaleOffsetUniform = { value: new Vector4(1, 1, 0, 0) };
|
|
30
|
+
private lightmapUniform: { value: Texture | null } = { value: null };
|
|
29
31
|
|
|
30
|
-
constructor(gameObject:
|
|
32
|
+
constructor(gameObject: Mesh, context: Context) {
|
|
31
33
|
this.gameObject = gameObject;
|
|
32
34
|
this.context = context;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
init(lightmapIndex: number, lightmapScaleOffset:
|
|
37
|
+
init(lightmapIndex: number, lightmapScaleOffset: Vector4, lightmapTexture: Texture) {
|
|
36
38
|
console.assert(this.gameObject !== undefined && this.gameObject !== null, "Missing gameobject", this);
|
|
37
39
|
|
|
38
40
|
this.lightmapIndex = lightmapIndex;
|
|
@@ -40,24 +42,25 @@ export class RendererLightmap {
|
|
|
40
42
|
this.lightmapScaleOffset = lightmapScaleOffset;
|
|
41
43
|
this.lightmapTexture = lightmapTexture;
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
if (debugLightmaps) this.setLightmapDebugMaterial();
|
|
45
|
+
if (debug) this.setLightmapDebugMaterial();
|
|
45
46
|
this.applyLightmap();
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
+
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
private onBeforeRenderThreeComplete = (_renderer, _scene, _camera, _geometry, material, _group) => {
|
|
54
|
-
this.onBeforeRenderThree(material);
|
|
55
|
-
}
|
|
56
59
|
|
|
57
60
|
private applyLightmap() {
|
|
58
|
-
|
|
59
61
|
if (this.gameObject.type === "Object3D") {
|
|
60
|
-
|
|
62
|
+
if (debug)
|
|
63
|
+
console.warn("Can not add lightmap. Is this object missing a renderer?", this.gameObject.name);
|
|
61
64
|
return;
|
|
62
65
|
}
|
|
63
66
|
|
|
@@ -68,23 +71,28 @@ export class RendererLightmap {
|
|
|
68
71
|
|
|
69
72
|
console.assert(this.gameObject.type === "Mesh", "Lightmap only works on meshes", this);
|
|
70
73
|
|
|
71
|
-
const mesh = this.gameObject as unknown as
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
74
|
+
const mesh = this.gameObject as unknown as Mesh;
|
|
75
|
+
if (!mesh.geometry.getAttribute("uv1"))
|
|
76
|
+
mesh.geometry.setAttribute("uv1", mesh.geometry.getAttribute("uv"));
|
|
77
|
+
|
|
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
|
+
}
|
|
84
92
|
|
|
85
93
|
if (this.lightmapIndex >= 0) {
|
|
86
94
|
const lightmap = this.lightmapTexture;
|
|
87
|
-
const mat = this.gameObject
|
|
95
|
+
const mat = this.gameObject.material as any;
|
|
88
96
|
if (mat && lightmap) {
|
|
89
97
|
if (!mat.uniforms) mat.uniforms = {};
|
|
90
98
|
mat.lightMap = lightmap;
|
|
@@ -93,27 +101,25 @@ export class RendererLightmap {
|
|
|
93
101
|
}
|
|
94
102
|
}
|
|
95
103
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
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;
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
private setLightmapDebugMaterial() {
|
|
108
115
|
|
|
109
116
|
// debug lightmaps
|
|
110
|
-
this.gameObject["material"] = new
|
|
117
|
+
this.gameObject["material"] = new ShaderMaterial({
|
|
111
118
|
vertexShader: `
|
|
112
|
-
|
|
113
|
-
varying vec2 vUv2;
|
|
119
|
+
varying vec2 vUv1;
|
|
114
120
|
void main()
|
|
115
121
|
{
|
|
116
|
-
|
|
122
|
+
vUv1 = uv1;
|
|
117
123
|
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
|
118
124
|
}
|
|
119
125
|
`,
|
|
@@ -121,7 +127,7 @@ export class RendererLightmap {
|
|
|
121
127
|
uniform sampler2D lightmap;
|
|
122
128
|
uniform float lightMapIntensity;
|
|
123
129
|
uniform vec4 lightmapScaleOffset;
|
|
124
|
-
varying vec2
|
|
130
|
+
varying vec2 vUv1;
|
|
125
131
|
|
|
126
132
|
// took from threejs 05fc79cd52b79e8c3e8dec1e7dca72c5c39983a4
|
|
127
133
|
vec4 conv_sRGBToLinear( in vec4 value ) {
|
|
@@ -129,7 +135,7 @@ export class RendererLightmap {
|
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
void main() {
|
|
132
|
-
vec2 lUv =
|
|
138
|
+
vec2 lUv = vUv1.xy * lightmapScaleOffset.xy + vec2(lightmapScaleOffset.z, (1. - (lightmapScaleOffset.y + lightmapScaleOffset.w)));
|
|
133
139
|
|
|
134
140
|
vec4 lightMapTexel = texture2D( lightmap, lUv);
|
|
135
141
|
// The range of RGBM lightmaps goes from 0 to 34.49 (5^2.2) in linear space, and from 0 to 5 in gamma space.
|
|
@@ -138,7 +144,7 @@ export class RendererLightmap {
|
|
|
138
144
|
//lightMapTexel = conv_sRGBToLinear(lightMapTexel);
|
|
139
145
|
// lightMapTexel.rgb = vec3(1.);
|
|
140
146
|
|
|
141
|
-
// gl_FragColor = vec4(
|
|
147
|
+
// gl_FragColor = vec4(vUv1.xy, 0, 1);
|
|
142
148
|
gl_FragColor = lightMapTexel;
|
|
143
149
|
}
|
|
144
150
|
`,
|
|
@@ -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) {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { IUSDExporterExtension } from "../Extension";
|
|
2
|
+
import { USDObject, USDZExporterContext } from "../ThreeUSDZExporter";
|
|
3
|
+
import { GameObject } from "../../../Component";
|
|
4
|
+
import { Canvas } from "../../../ui/Canvas";
|
|
5
|
+
import { CanvasGroup } from "../../../ui/CanvasGroup";
|
|
6
|
+
import { $shadowDomOwner } from "../../../ui/BaseUIComponent";
|
|
7
|
+
import { RectTransform } from "../../../ui/RectTransform";
|
|
8
|
+
import { Color, Mesh, MeshBasicMaterial, Object3D } from "three";
|
|
9
|
+
import { TextExtension } from "./USDZText";
|
|
10
|
+
import { RenderMode } from "../../../ui/Canvas";
|
|
11
|
+
|
|
12
|
+
export class USDZUIExtension implements IUSDExporterExtension {
|
|
13
|
+
get extensionName(): string {
|
|
14
|
+
return "tmui";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// TODO would probably be better to export each object instead of the entire Canvas
|
|
18
|
+
// so that we don't export them twice (once as regular hierarchy, once as part of Canvas export)
|
|
19
|
+
onExportObject(object: Object3D, model: USDObject, _context: USDZExporterContext) {
|
|
20
|
+
const canvas = GameObject.getComponent(object, Canvas);
|
|
21
|
+
|
|
22
|
+
if (canvas && canvas.activeAndEnabled && canvas.renderMode === RenderMode.WorldSpace) {
|
|
23
|
+
const textExt = new TextExtension();
|
|
24
|
+
const rt = GameObject.getComponent(object, RectTransform);
|
|
25
|
+
const canvasGroup = GameObject.getComponent(object, CanvasGroup);
|
|
26
|
+
|
|
27
|
+
let width = 100;
|
|
28
|
+
let height = 100;
|
|
29
|
+
if (rt) {
|
|
30
|
+
width = rt.width;
|
|
31
|
+
height = rt.height;
|
|
32
|
+
|
|
33
|
+
const shadowRootModel = USDObject.createEmpty();
|
|
34
|
+
const shadowComponent = rt.shadowComponent;
|
|
35
|
+
model.add(shadowRootModel);
|
|
36
|
+
|
|
37
|
+
if (shadowComponent) {
|
|
38
|
+
const mat = shadowComponent.matrix;
|
|
39
|
+
shadowRootModel.matrix.copy(mat);
|
|
40
|
+
// shadowRootModel.matrix.premultiply(invertX);
|
|
41
|
+
|
|
42
|
+
// TODO build map of parent GOs to USDObjects so we can reparent while traversing
|
|
43
|
+
const usdObjectMap = new Map<Object3D, USDObject>();
|
|
44
|
+
const opacityMap = new Map<Object3D, number>();
|
|
45
|
+
usdObjectMap.set(shadowComponent, shadowRootModel);
|
|
46
|
+
opacityMap.set(shadowComponent, canvasGroup ? canvasGroup.alpha : 1);
|
|
47
|
+
|
|
48
|
+
shadowComponent.traverse((child) => {
|
|
49
|
+
if (child === shadowComponent) return;
|
|
50
|
+
|
|
51
|
+
const childModel = USDObject.createEmpty();
|
|
52
|
+
childModel.matrix.copy(child.matrix);
|
|
53
|
+
|
|
54
|
+
const childParent = child.parent;
|
|
55
|
+
const isText = childParent && typeof childParent["textContent"] === "string" && childParent["textContent"].length;
|
|
56
|
+
let hierarchyOpacity = opacityMap.get(childParent!) || 1;
|
|
57
|
+
|
|
58
|
+
// TODO CanvasGroup doesn't render something but modifies opacity
|
|
59
|
+
// get CanvasGroup and modify alpha here
|
|
60
|
+
|
|
61
|
+
const canvasGroup = GameObject.getComponent(child, CanvasGroup);
|
|
62
|
+
if (canvasGroup)
|
|
63
|
+
hierarchyOpacity *= canvasGroup.alpha;
|
|
64
|
+
|
|
65
|
+
if (child instanceof Mesh && isText) {
|
|
66
|
+
// get shadoDomOwner so we can export Text from the text extension directly
|
|
67
|
+
const shadowDomOwner = child[$shadowDomOwner].gameObject;
|
|
68
|
+
textExt.exportText(shadowDomOwner, childModel, _context);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (child instanceof Mesh && !isText)
|
|
72
|
+
{
|
|
73
|
+
// UI behaves weird: it seems it's always flipped right now,
|
|
74
|
+
// and three magically fixes it when rendering
|
|
75
|
+
// see https://github.com/mrdoob/three.js/pull/12720#issue-275923930
|
|
76
|
+
// https://github.com/mrdoob/three.js/issues/17361
|
|
77
|
+
// So we need to fix the winding order after applying the negative scale.
|
|
78
|
+
const clonedGeo = child.geometry.clone();
|
|
79
|
+
clonedGeo.scale(1, 1, -1);
|
|
80
|
+
this.flipWindingOrder(clonedGeo);
|
|
81
|
+
childModel.geometry = clonedGeo;
|
|
82
|
+
|
|
83
|
+
const color = new Color();
|
|
84
|
+
const ownOpacity = child.material.opacity;
|
|
85
|
+
color.copy(child.material.color);
|
|
86
|
+
|
|
87
|
+
// Calculate opacity from parent chain and own alpha
|
|
88
|
+
childModel.material = new MeshBasicMaterial({
|
|
89
|
+
color: color,
|
|
90
|
+
opacity: ownOpacity * hierarchyOpacity,
|
|
91
|
+
map: child.material.map,
|
|
92
|
+
transparent: true,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
usdObjectMap.set(child, childModel);
|
|
97
|
+
opacityMap.set(child, hierarchyOpacity);
|
|
98
|
+
|
|
99
|
+
const parentUsdzObject = usdObjectMap.get(childParent!);
|
|
100
|
+
if (!parentUsdzObject) {
|
|
101
|
+
console.error("Error when exporting UI: shadow component parent not found!", child, child.parent);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
parentUsdzObject.add(childModel);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private flipWindingOrder(geometry) {
|
|
112
|
+
const index = geometry.index.array
|
|
113
|
+
for (let i = 0, il = index.length / 3; i < il; i++) {
|
|
114
|
+
let x = index[i * 3]
|
|
115
|
+
index[i * 3] = index[i * 3 + 2]
|
|
116
|
+
index[i * 3 + 2] = x
|
|
117
|
+
}
|
|
118
|
+
geometry.index.needsUpdate = true
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -6,8 +6,11 @@ import { showGizmos } from '../../engine/engine_default_parameters';
|
|
|
6
6
|
import { AxesHelper, Object3D } from 'three';
|
|
7
7
|
import { ICanvas, IGraphic } from './Interfaces';
|
|
8
8
|
import { ShadowCastingMode } from '../Renderer';
|
|
9
|
+
import { getParam } from '../../engine/engine_utils';
|
|
9
10
|
export const includesDir = "./include";
|
|
10
11
|
|
|
12
|
+
const debug = getParam("debugshadowcomponents");
|
|
13
|
+
|
|
11
14
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
|
|
12
15
|
|
|
13
16
|
|
|
@@ -128,6 +131,8 @@ export class BaseUIComponent extends Behaviour {
|
|
|
128
131
|
// otherwise it will fail when object are enabled at runtime
|
|
129
132
|
if (needsUpdate)
|
|
130
133
|
ThreeMeshUI.update();
|
|
134
|
+
|
|
135
|
+
if(debug) console.log(this.shadowComponent)
|
|
131
136
|
}
|
|
132
137
|
|
|
133
138
|
|
|
@@ -116,8 +116,10 @@ export class Button extends Behaviour implements IPointerEventHandler {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
onPointerClick(
|
|
119
|
+
onPointerClick(args: PointerEventData) {
|
|
120
120
|
if (!this.interactable) return;
|
|
121
|
+
// Button clicks should only run with left mouse button
|
|
122
|
+
if(args.pointerId !== 0) return;
|
|
121
123
|
if (debug) {
|
|
122
124
|
console.warn("Button Click", this.onClick);
|
|
123
125
|
showBalloonMessage("CLICKED button " + this.name + " at " + this.context.time.frameCount);
|
|
@@ -190,6 +190,7 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
onBeforeRenderRoutine = () => {
|
|
193
|
+
if(this.context.isInVR) return;
|
|
193
194
|
this.previousParent = this.gameObject.parent;
|
|
194
195
|
// console.log(this.previousParent?.name + "/" + this.gameObject.name);
|
|
195
196
|
|
|
@@ -208,6 +209,7 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
onAfterRenderRoutine = () => {
|
|
212
|
+
if(this.context.isInVR) return;
|
|
211
213
|
if ((this.screenspace || this.renderOnTop) && this.previousParent && this.context.mainCamera) {
|
|
212
214
|
if (this.screenspace) {
|
|
213
215
|
const camObj = this.context.mainCamera;
|
|
@@ -215,7 +217,10 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
215
217
|
} else {
|
|
216
218
|
this.previousParent.add(this.gameObject);
|
|
217
219
|
}
|
|
220
|
+
const prevAutoClearDepth = this.context.renderer.autoClear;
|
|
221
|
+
const prevAutoClearColor = this.context.renderer.autoClearColor;
|
|
218
222
|
this.context.renderer.autoClear = false;
|
|
223
|
+
this.context.renderer.autoClearColor = false;
|
|
219
224
|
this.context.renderer.clearDepth();
|
|
220
225
|
this.onUpdateRenderMode(true);
|
|
221
226
|
this.handleLayoutUpdates();
|
|
@@ -223,7 +228,8 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
223
228
|
// this.handleLayoutUpdates();
|
|
224
229
|
EventSystem.ensureUpdateMeshUI(ThreeMeshUI, this.context);
|
|
225
230
|
this.context.renderer.render(this.gameObject, this.context.mainCamera);
|
|
226
|
-
this.context.renderer.autoClear =
|
|
231
|
+
this.context.renderer.autoClear = prevAutoClearDepth;
|
|
232
|
+
this.context.renderer.autoClearColor = prevAutoClearColor;
|
|
227
233
|
this.previousParent.add(this.gameObject);
|
|
228
234
|
}
|
|
229
235
|
this._lastMatrixWorld?.copy(this.gameObject.matrixWorld);
|
|
@@ -127,6 +127,7 @@ export class EventSystem extends Behaviour {
|
|
|
127
127
|
MeshUIHelper.resetLastSelected();
|
|
128
128
|
const opts = new PointerEventData(this.context.input);
|
|
129
129
|
opts.inputSource = ctrl;
|
|
130
|
+
opts.pointerId = 0;
|
|
130
131
|
opts.isDown = ctrl.selectionDown;
|
|
131
132
|
opts.isUp = ctrl.selectionUp;
|
|
132
133
|
opts.isPressed = ctrl.selectionPressed;
|
|
@@ -136,10 +137,11 @@ export class EventSystem extends Behaviour {
|
|
|
136
137
|
args.grab = null;
|
|
137
138
|
};
|
|
138
139
|
}
|
|
139
|
-
this._selectEndFn ??= (ctrl, args: { grab: THREE.Object3D }) => {
|
|
140
|
+
this._selectEndFn ??= (ctrl: WebXRController, args: { grab: THREE.Object3D }) => {
|
|
140
141
|
if (!args.grab) return;
|
|
141
142
|
const opts = new PointerEventData(this.context.input);
|
|
142
143
|
opts.inputSource = ctrl;
|
|
144
|
+
opts.pointerId = 0;
|
|
143
145
|
opts.isDown = ctrl.selectionDown;
|
|
144
146
|
opts.isUp = ctrl.selectionUp;
|
|
145
147
|
opts.isPressed = ctrl.selectionPressed;
|
|
@@ -3,7 +3,7 @@ import * as ThreeMeshUI from 'three-mesh-ui'
|
|
|
3
3
|
import { RGBAColor } from "../js-extensions/RGBAColor"
|
|
4
4
|
import { BaseUIComponent } from "./BaseUIComponent";
|
|
5
5
|
import { serializable } from '../../engine/engine_serialization_decorator';
|
|
6
|
-
import { Color,
|
|
6
|
+
import { Color, LinearSRGBColorSpace, SRGBColorSpace, Texture } from 'three';
|
|
7
7
|
import { RectTransform } from './RectTransform';
|
|
8
8
|
import { onChange, scheduleAction } from "./Utils"
|
|
9
9
|
import { GameObject } from '../Component';
|
|
@@ -191,12 +191,12 @@ export class Graphic extends BaseUIComponent implements IGraphic, IRectTransform
|
|
|
191
191
|
this.setOptions({ backgroundOpacity: 0 });
|
|
192
192
|
if (tex) {
|
|
193
193
|
// workaround for https://github.com/needle-tools/needle-engine-support/issues/109
|
|
194
|
-
if (tex.
|
|
194
|
+
if (tex.colorSpace === SRGBColorSpace) {
|
|
195
195
|
if (Graphic.textureCache.has(tex)) {
|
|
196
196
|
tex = Graphic.textureCache.get(tex)!;
|
|
197
197
|
} else {
|
|
198
198
|
const clone = tex.clone();
|
|
199
|
-
clone.
|
|
199
|
+
clone.colorSpace = LinearSRGBColorSpace;
|
|
200
200
|
Graphic.textureCache.set(tex, clone);
|
|
201
201
|
tex = clone;
|
|
202
202
|
}
|