@babylonjs/serializers 7.28.0 → 7.30.0
Sign up to get free protection for your applications and to get access to all the features.
- package/USDZ/index.d.ts +1 -0
- package/USDZ/index.js +3 -0
- package/USDZ/index.js.map +1 -0
- package/USDZ/usdzExporter.d.ts +50 -0
- package/USDZ/usdzExporter.js +549 -0
- package/USDZ/usdzExporter.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/legacy/legacy-usdzSerializer.d.ts +1 -0
- package/legacy/legacy-usdzSerializer.js +14 -0
- package/legacy/legacy-usdzSerializer.js.map +1 -0
- package/legacy/legacy.d.ts +1 -0
- package/legacy/legacy.js +1 -0
- package/legacy/legacy.js.map +1 -1
- package/package.json +3 -3
package/USDZ/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./usdzExporter";
|
package/USDZ/index.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../dev/serializers/src/USDZ/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,cAAc,gBAAgB,CAAC","sourcesContent":["/* eslint-disable import/no-internal-modules */\r\nexport * from \"./usdzExporter\";\r\n"]}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import type { Mesh } from "@babylonjs/core/Meshes/mesh.js";
|
2
|
+
import type { Scene } from "@babylonjs/core/scene.js";
|
3
|
+
/**
|
4
|
+
* Options for the USDZ export
|
5
|
+
*/
|
6
|
+
export interface IUSDZExportOptions {
|
7
|
+
/**
|
8
|
+
* URL to load the fflate library from
|
9
|
+
*/
|
10
|
+
fflateUrl?: string;
|
11
|
+
/**
|
12
|
+
* Include anchoring properties in the USDZ file
|
13
|
+
*/
|
14
|
+
includeAnchoringProperties?: boolean;
|
15
|
+
/**
|
16
|
+
* Anchoring type (plane by default)
|
17
|
+
*/
|
18
|
+
anchoringType?: string;
|
19
|
+
/**
|
20
|
+
* Plane anchoring alignment (horizontal by default)
|
21
|
+
*/
|
22
|
+
planeAnchoringAlignment?: string;
|
23
|
+
/**
|
24
|
+
* Model file name (model.usda by default)
|
25
|
+
*/
|
26
|
+
modelFileName?: string;
|
27
|
+
/**
|
28
|
+
* Precision to use for number (5 by default)
|
29
|
+
*/
|
30
|
+
precision?: number;
|
31
|
+
/**
|
32
|
+
* Export the camera (false by default)
|
33
|
+
*/
|
34
|
+
exportCamera?: boolean;
|
35
|
+
/**
|
36
|
+
* Camera sensor width (35 by default)
|
37
|
+
*/
|
38
|
+
cameraSensorWidth?: number;
|
39
|
+
}
|
40
|
+
/**
|
41
|
+
*
|
42
|
+
* @param scene scene to export
|
43
|
+
* @param options options to configure the export
|
44
|
+
* @param meshPredicate predicate to filter the meshes to export
|
45
|
+
* @returns a uint8 array containing the USDZ file
|
46
|
+
* #H2G5XW#3 - Simple sphere
|
47
|
+
* #H2G5XW#4 - Red sphere
|
48
|
+
* #5N3RWK#4 - Boombox
|
49
|
+
*/
|
50
|
+
export declare function USDZExportAsync(scene: Scene, options: Partial<IUSDZExportOptions>, meshPredicate?: (m: Mesh) => boolean): Promise<Uint8Array>;
|
@@ -0,0 +1,549 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
2
|
+
import { VertexBuffer } from "@babylonjs/core/Buffers/buffer.js";
|
3
|
+
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
4
|
+
import { Color3 } from "@babylonjs/core/Maths/math.color.js";
|
5
|
+
import { Matrix, Vector2 } from "@babylonjs/core/Maths/math.vector.js";
|
6
|
+
import { DumpTools } from "@babylonjs/core/Misc/dumpTools.js";
|
7
|
+
import { Tools } from "@babylonjs/core/Misc/tools.js";
|
8
|
+
function BuildHeader() {
|
9
|
+
return `#usda 1.0
|
10
|
+
(
|
11
|
+
customLayerData = {
|
12
|
+
string creator = "Babylon.js USDZExportAsync"
|
13
|
+
}
|
14
|
+
defaultPrim = "Root"
|
15
|
+
metersPerUnit = 1
|
16
|
+
upAxis = "Y"
|
17
|
+
)`;
|
18
|
+
}
|
19
|
+
function BuildSceneStart(options) {
|
20
|
+
const alignment = options.includeAnchoringProperties === true
|
21
|
+
? `
|
22
|
+
token preliminary:anchoring:type = "${options.anchoringType}"
|
23
|
+
token preliminary:planeAnchoring:alignment = "${options.planeAnchoringAlignment}"`
|
24
|
+
: "";
|
25
|
+
return `def Xform "Root"
|
26
|
+
{
|
27
|
+
def Scope "Scenes" (
|
28
|
+
kind = "sceneLibrary"
|
29
|
+
)
|
30
|
+
{
|
31
|
+
def Xform "Scene" (
|
32
|
+
customData = {
|
33
|
+
bool preliminary_collidesWithEnvironment = 0
|
34
|
+
string sceneName = "Scene"
|
35
|
+
}
|
36
|
+
sceneName = "Scene"
|
37
|
+
)
|
38
|
+
{${alignment}
|
39
|
+
`;
|
40
|
+
}
|
41
|
+
function BuildSceneEnd() {
|
42
|
+
return `
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}`;
|
46
|
+
}
|
47
|
+
function BuildMeshVertexCount(geometry) {
|
48
|
+
const count = geometry.getIndices()?.length ? geometry.getTotalIndices() : geometry.getTotalVertices();
|
49
|
+
return Array(count / 3)
|
50
|
+
.fill(3)
|
51
|
+
.join(", ");
|
52
|
+
}
|
53
|
+
function BuildMeshVertexIndices(geometry) {
|
54
|
+
const index = geometry.getIndices();
|
55
|
+
const array = [];
|
56
|
+
if (index !== null) {
|
57
|
+
for (let i = 0; i < index.length; i++) {
|
58
|
+
array.push(index[i]);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
const length = geometry.getTotalVertices();
|
63
|
+
for (let i = 0; i < length; i++) {
|
64
|
+
array.push(i);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
return array.join(", ");
|
68
|
+
}
|
69
|
+
function BuildVector3Array(attribute, options, stride = 3) {
|
70
|
+
const array = [];
|
71
|
+
for (let i = 0; i < attribute.length / stride; i++) {
|
72
|
+
const x = attribute[i * stride];
|
73
|
+
const y = attribute[i * stride + 1];
|
74
|
+
const z = attribute[i * stride + 2];
|
75
|
+
array.push(`(${x.toPrecision(options.precision)}, ${y.toPrecision(options.precision)}, ${z.toPrecision(options.precision)})`);
|
76
|
+
}
|
77
|
+
return array.join(", ");
|
78
|
+
}
|
79
|
+
function BuildVector2Array(attribute, options) {
|
80
|
+
const array = [];
|
81
|
+
for (let i = 0; i < attribute.length / 2; i++) {
|
82
|
+
const x = attribute[i * 2];
|
83
|
+
const y = attribute[i * 2 + 1];
|
84
|
+
array.push(`(${x.toPrecision(options.precision)}, ${(1 - y).toPrecision(options.precision)})`);
|
85
|
+
}
|
86
|
+
return array.join(", ");
|
87
|
+
}
|
88
|
+
function BuildAdditionalAttributes(geometry, options) {
|
89
|
+
let string = "";
|
90
|
+
for (let i = 0; i < 4; i++) {
|
91
|
+
const id = i > 0 ? i : "";
|
92
|
+
const uvAttribute = geometry.getVerticesData(VertexBuffer.UVKind + (id ? id : ""));
|
93
|
+
if (uvAttribute) {
|
94
|
+
string += `
|
95
|
+
texCoord2f[] primvars:st${id} = [${BuildVector2Array(uvAttribute, options)}] (
|
96
|
+
interpolation = "vertex"
|
97
|
+
)`;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
// vertex colors
|
101
|
+
const colorAttribute = geometry.getVerticesData(VertexBuffer.ColorKind);
|
102
|
+
if (colorAttribute) {
|
103
|
+
string += `
|
104
|
+
color3f[] primvars:displayColor = [${BuildVector3Array(colorAttribute, options, 4)}] (
|
105
|
+
interpolation = "vertex"
|
106
|
+
)`;
|
107
|
+
}
|
108
|
+
return string;
|
109
|
+
}
|
110
|
+
function BuildMesh(geometry, options) {
|
111
|
+
const name = "Geometry";
|
112
|
+
const position = geometry.getVerticesData(VertexBuffer.PositionKind);
|
113
|
+
const normal = geometry.getVerticesData(VertexBuffer.PositionKind);
|
114
|
+
if (!position || !normal) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
return `
|
118
|
+
def Mesh "${name}"
|
119
|
+
{
|
120
|
+
int[] faceVertexCounts = [${BuildMeshVertexCount(geometry)}]
|
121
|
+
int[] faceVertexIndices = [${BuildMeshVertexIndices(geometry)}]
|
122
|
+
normal3f[] normals = [${BuildVector3Array(normal, options)}] (
|
123
|
+
interpolation = "vertex"
|
124
|
+
)
|
125
|
+
point3f[] points = [${BuildVector3Array(position, options)}]
|
126
|
+
${BuildAdditionalAttributes(geometry, options)}
|
127
|
+
uniform token subdivisionScheme = "none"
|
128
|
+
}
|
129
|
+
`;
|
130
|
+
}
|
131
|
+
function BuildMeshObject(geometry, options) {
|
132
|
+
const mesh = BuildMesh(geometry, options);
|
133
|
+
return `
|
134
|
+
def "Geometry"
|
135
|
+
{
|
136
|
+
${mesh}
|
137
|
+
}
|
138
|
+
`;
|
139
|
+
}
|
140
|
+
function BuildUSDFileAsString(dataToInsert) {
|
141
|
+
let output = BuildHeader();
|
142
|
+
output += dataToInsert;
|
143
|
+
return fflate.strToU8(output);
|
144
|
+
}
|
145
|
+
function BuildMatrix(matrix) {
|
146
|
+
const array = matrix.m;
|
147
|
+
return `( ${BuildMatrixRow(array, 0)}, ${BuildMatrixRow(array, 4)}, ${BuildMatrixRow(array, 8)}, ${BuildMatrixRow(array, 12)} )`;
|
148
|
+
}
|
149
|
+
function BuildMatrixRow(array, offset) {
|
150
|
+
return `(${array[offset + 0]}, ${array[offset + 1]}, ${array[offset + 2]}, ${array[offset + 3]})`;
|
151
|
+
}
|
152
|
+
function BuildXform(mesh) {
|
153
|
+
const name = "Object_" + mesh.uniqueId;
|
154
|
+
const matrix = mesh.getWorldMatrix().clone();
|
155
|
+
if (matrix.determinant() < 0) {
|
156
|
+
matrix.multiplyToRef(Matrix.Scaling(-1, 1, 1), matrix);
|
157
|
+
}
|
158
|
+
const transform = BuildMatrix(matrix);
|
159
|
+
return `def Xform "${name}" (
|
160
|
+
prepend references = @./geometries/Geometry_${mesh.geometry.uniqueId}.usda@</Geometry>
|
161
|
+
prepend apiSchemas = ["MaterialBindingAPI"]
|
162
|
+
)
|
163
|
+
{
|
164
|
+
matrix4d xformOp:transform = ${transform}
|
165
|
+
uniform token[] xformOpOrder = ["xformOp:transform"]
|
166
|
+
|
167
|
+
rel material:binding = </Materials/Material_${mesh.material.uniqueId}>
|
168
|
+
}
|
169
|
+
|
170
|
+
`;
|
171
|
+
}
|
172
|
+
function BuildMaterials(materials, textureToExports, options) {
|
173
|
+
const array = [];
|
174
|
+
for (const uuid in materials) {
|
175
|
+
const material = materials[uuid];
|
176
|
+
array.push(BuildMaterial(material, textureToExports, options));
|
177
|
+
}
|
178
|
+
return `
|
179
|
+
def "Materials"
|
180
|
+
{
|
181
|
+
${array.join("")}
|
182
|
+
}
|
183
|
+
|
184
|
+
`;
|
185
|
+
}
|
186
|
+
function BuildWrapping(wrapping) {
|
187
|
+
switch (wrapping) {
|
188
|
+
case Constants.TEXTURE_CLAMP_ADDRESSMODE:
|
189
|
+
return "clamp";
|
190
|
+
case Constants.TEXTURE_MIRROR_ADDRESSMODE:
|
191
|
+
return "mirror";
|
192
|
+
case Constants.TEXTURE_WRAP_ADDRESSMODE:
|
193
|
+
default:
|
194
|
+
return "repeat";
|
195
|
+
}
|
196
|
+
}
|
197
|
+
function BuildColor4(color) {
|
198
|
+
return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
|
199
|
+
}
|
200
|
+
function BuildVector2(vector) {
|
201
|
+
return `(${vector.x}, ${vector.y})`;
|
202
|
+
}
|
203
|
+
function BuildColor(color) {
|
204
|
+
return `(${color.r}, ${color.g}, ${color.b})`;
|
205
|
+
}
|
206
|
+
function BuildTexture(texture, material, mapType, color, textureToExports, options) {
|
207
|
+
const id = texture.getInternalTexture().uniqueId + "_" + texture.invertY;
|
208
|
+
textureToExports[id] = texture;
|
209
|
+
const uv = texture.coordinatesIndex > 0 ? "st" + texture.coordinatesIndex : "st";
|
210
|
+
const repeat = new Vector2(texture.uScale, texture.vScale);
|
211
|
+
const offset = new Vector2(texture.uOffset, texture.vOffset);
|
212
|
+
const rotation = texture.wAng;
|
213
|
+
// rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot
|
214
|
+
const xRotationOffset = Math.sin(rotation);
|
215
|
+
const yRotationOffset = Math.cos(rotation);
|
216
|
+
// texture coordinates start in the opposite corner, need to correct
|
217
|
+
offset.y = 1 - offset.y - repeat.y;
|
218
|
+
offset.x += xRotationOffset * repeat.x;
|
219
|
+
offset.y += (1 - yRotationOffset) * repeat.y;
|
220
|
+
return `
|
221
|
+
def Shader "PrimvarReader_${mapType}"
|
222
|
+
{
|
223
|
+
uniform token info:id = "UsdPrimvarReader_float2"
|
224
|
+
float2 inputs:fallback = (0.0, 0.0)
|
225
|
+
token inputs:varname = "${uv}"
|
226
|
+
float2 outputs:result
|
227
|
+
}
|
228
|
+
|
229
|
+
def Shader "Transform2d_${mapType}"
|
230
|
+
{
|
231
|
+
uniform token info:id = "UsdTransform2d"
|
232
|
+
token inputs:in.connect = </Materials/Material_${material.uniqueId}/PrimvarReader_${mapType}.outputs:result>
|
233
|
+
float inputs:rotation = ${(rotation * (180 / Math.PI)).toFixed(options.precision)}
|
234
|
+
float2 inputs:scale = ${BuildVector2(repeat)}
|
235
|
+
float2 inputs:translation = ${BuildVector2(offset)}
|
236
|
+
float2 outputs:result
|
237
|
+
}
|
238
|
+
|
239
|
+
def Shader "Texture_${texture.uniqueId}_${mapType}"
|
240
|
+
{
|
241
|
+
uniform token info:id = "UsdUVTexture"
|
242
|
+
asset inputs:file = @textures/Texture_${id}.png@
|
243
|
+
float2 inputs:st.connect = </Materials/Material_${material.uniqueId}/Transform2d_${mapType}.outputs:result>
|
244
|
+
${color ? "float4 inputs:scale = " + BuildColor4(color) : ""}
|
245
|
+
token inputs:sourceColorSpace = "${texture.gammaSpace ? "raw" : "sRGB"}"
|
246
|
+
token inputs:wrapS = "${BuildWrapping(texture.wrapU)}"
|
247
|
+
token inputs:wrapT = "${BuildWrapping(texture.wrapV)}"
|
248
|
+
float outputs:r
|
249
|
+
float outputs:g
|
250
|
+
float outputs:b
|
251
|
+
float3 outputs:rgb
|
252
|
+
${material.needAlphaBlending() ? "float outputs:a" : ""}
|
253
|
+
}`;
|
254
|
+
}
|
255
|
+
function ExtractTextureInformations(material) {
|
256
|
+
const className = material.getClassName();
|
257
|
+
switch (className) {
|
258
|
+
case "StandardMaterial":
|
259
|
+
return {
|
260
|
+
diffuseMap: material.diffuseTexture,
|
261
|
+
diffuse: material.diffuseColor,
|
262
|
+
alphaCutOff: material.alphaCutOff,
|
263
|
+
emissiveMap: material.emissiveTexture,
|
264
|
+
emissive: material.emissiveColor,
|
265
|
+
roughnessMap: null,
|
266
|
+
normalMap: null,
|
267
|
+
metalnessMap: null,
|
268
|
+
roughness: 1,
|
269
|
+
metalness: 0,
|
270
|
+
aoMap: null,
|
271
|
+
aoMapIntensity: 0,
|
272
|
+
alphaMap: material.opacityTexture,
|
273
|
+
ior: 1,
|
274
|
+
};
|
275
|
+
case "PBRMaterial":
|
276
|
+
return {
|
277
|
+
diffuseMap: material.albedoTexture,
|
278
|
+
diffuse: material.albedoColor,
|
279
|
+
alphaCutOff: material.alphaCutOff,
|
280
|
+
emissiveMap: material.emissiveTexture,
|
281
|
+
emissive: material.emissiveColor,
|
282
|
+
normalMap: material.bumpTexture,
|
283
|
+
roughnessMap: material.metallicTexture,
|
284
|
+
roughnessChannel: material.useRoughnessFromMetallicTextureAlpha ? "a" : "g",
|
285
|
+
roughness: material.roughness || 1,
|
286
|
+
metalnessMap: material.metallicTexture,
|
287
|
+
metalnessChannel: material.useMetallnessFromMetallicTextureBlue ? "b" : "r",
|
288
|
+
metalness: material.metallic || 0,
|
289
|
+
aoMap: material.ambientTexture,
|
290
|
+
aoMapChannel: material.useAmbientInGrayScale ? "r" : "rgb",
|
291
|
+
aoMapIntensity: material.ambientTextureStrength,
|
292
|
+
alphaMap: material.opacityTexture,
|
293
|
+
ior: material.indexOfRefraction,
|
294
|
+
};
|
295
|
+
case "PBRMetallicRoughnessMaterial":
|
296
|
+
return {
|
297
|
+
diffuseMap: material.baseTexture,
|
298
|
+
diffuse: material.baseColor,
|
299
|
+
alphaCutOff: material.alphaCutOff,
|
300
|
+
emissiveMap: material.emissiveTexture,
|
301
|
+
emissive: material.emissiveColor,
|
302
|
+
normalMap: material.normalTexture,
|
303
|
+
roughnessMap: material.metallicTexture,
|
304
|
+
roughnessChannel: material.useRoughnessFromMetallicTextureAlpha ? "a" : "g",
|
305
|
+
roughness: material.roughness || 1,
|
306
|
+
metalnessMap: material.metallicTexture,
|
307
|
+
metalnessChannel: material.useMetallnessFromMetallicTextureBlue ? "b" : "r",
|
308
|
+
metalness: material.metallic || 0,
|
309
|
+
aoMap: material.ambientTexture,
|
310
|
+
aoMapChannel: material.useAmbientInGrayScale ? "r" : "rgb",
|
311
|
+
aoMapIntensity: material.ambientTextureStrength,
|
312
|
+
alphaMap: material.opacityTexture,
|
313
|
+
ior: material.indexOfRefraction,
|
314
|
+
};
|
315
|
+
default:
|
316
|
+
return {
|
317
|
+
diffuseMap: null,
|
318
|
+
diffuse: null,
|
319
|
+
emissiveMap: null,
|
320
|
+
emissemissiveiveColor: null,
|
321
|
+
normalMap: null,
|
322
|
+
roughnessMap: null,
|
323
|
+
metalnessMap: null,
|
324
|
+
alphaCutOff: 0,
|
325
|
+
roughness: 0,
|
326
|
+
metalness: 0,
|
327
|
+
aoMap: null,
|
328
|
+
aoMapIntensity: 0,
|
329
|
+
alphaMap: null,
|
330
|
+
ior: 1,
|
331
|
+
};
|
332
|
+
}
|
333
|
+
}
|
334
|
+
function BuildMaterial(material, textureToExports, options) {
|
335
|
+
// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
|
336
|
+
const pad = " ";
|
337
|
+
const inputs = [];
|
338
|
+
const samplers = [];
|
339
|
+
const { diffuseMap, diffuse, alphaCutOff, emissiveMap, emissive, normalMap, roughnessMap, roughnessChannel, roughness, metalnessMap, metalnessChannel, metalness, aoMap, aoMapChannel, aoMapIntensity, alphaMap, ior, } = ExtractTextureInformations(material);
|
340
|
+
if (diffuseMap !== null) {
|
341
|
+
inputs.push(`${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:rgb>`);
|
342
|
+
if (material.needAlphaBlending()) {
|
343
|
+
inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:a>`);
|
344
|
+
}
|
345
|
+
else if (material.needAlphaTesting()) {
|
346
|
+
inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:a>`);
|
347
|
+
inputs.push(`${pad}float inputs:opacityThreshold = ${alphaCutOff}`);
|
348
|
+
}
|
349
|
+
samplers.push(BuildTexture(diffuseMap, material, "diffuse", diffuse, textureToExports, options));
|
350
|
+
}
|
351
|
+
else {
|
352
|
+
inputs.push(`${pad}color3f inputs:diffuseColor = ${BuildColor(diffuse || Color3.White())}`);
|
353
|
+
}
|
354
|
+
if (emissiveMap !== null) {
|
355
|
+
inputs.push(`${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.uniqueId}/Texture_${emissiveMap.uniqueId}_emissive.outputs:rgb>`);
|
356
|
+
samplers.push(BuildTexture(emissiveMap, material, "emissive", emissive, textureToExports, options));
|
357
|
+
}
|
358
|
+
else if (emissive && emissive.toLuminance() > 0) {
|
359
|
+
inputs.push(`${pad}color3f inputs:emissiveColor = ${BuildColor(emissive)}`);
|
360
|
+
}
|
361
|
+
if (normalMap !== null) {
|
362
|
+
inputs.push(`${pad}normal3f inputs:normal.connect = </Materials/Material_${material.uniqueId}/Texture_${normalMap.uniqueId}_normal.outputs:rgb>`);
|
363
|
+
samplers.push(BuildTexture(normalMap, material, "normal", null, textureToExports, options));
|
364
|
+
}
|
365
|
+
if (aoMap !== null) {
|
366
|
+
inputs.push(`${pad}float inputs:occlusion.connect = </Materials/Material_${material.uniqueId}/Texture_${aoMap.uniqueId}_occlusion.outputs:${aoMapChannel}>`);
|
367
|
+
samplers.push(BuildTexture(aoMap, material, "occlusion", new Color3(aoMapIntensity, aoMapIntensity, aoMapIntensity), textureToExports, options));
|
368
|
+
}
|
369
|
+
if (roughnessMap !== null) {
|
370
|
+
inputs.push(`${pad}float inputs:roughness.connect = </Materials/Material_${material.uniqueId}/Texture_${roughnessMap.uniqueId}_roughness.outputs:${roughnessChannel}>`);
|
371
|
+
samplers.push(BuildTexture(roughnessMap, material, "roughness", new Color3(roughness, roughness, roughness), textureToExports, options));
|
372
|
+
}
|
373
|
+
else {
|
374
|
+
inputs.push(`${pad}float inputs:roughness = ${roughness}`);
|
375
|
+
}
|
376
|
+
if (metalnessMap !== null) {
|
377
|
+
inputs.push(`${pad}float inputs:metallic.connect = </Materials/Material_${material.uniqueId}/Texture_${metalnessMap.uniqueId}_metallic.outputs:${metalnessChannel}>`);
|
378
|
+
samplers.push(BuildTexture(metalnessMap, material, "metallic", new Color3(metalness, metalness, metalness), textureToExports, options));
|
379
|
+
}
|
380
|
+
else {
|
381
|
+
inputs.push(`${pad}float inputs:metallic = ${metalness}`);
|
382
|
+
}
|
383
|
+
if (alphaMap !== null) {
|
384
|
+
inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${alphaMap.uniqueId}_opacity.outputs:r>`);
|
385
|
+
inputs.push(`${pad}float inputs:opacityThreshold = 0.0001`);
|
386
|
+
samplers.push(BuildTexture(alphaMap, material, "opacity", null, textureToExports, options));
|
387
|
+
}
|
388
|
+
else {
|
389
|
+
inputs.push(`${pad}float inputs:opacity = ${material.alpha}`);
|
390
|
+
}
|
391
|
+
inputs.push(`${pad}float inputs:ior = ${ior}`);
|
392
|
+
return `
|
393
|
+
def Material "Material_${material.uniqueId}"
|
394
|
+
{
|
395
|
+
def Shader "PreviewSurface"
|
396
|
+
{
|
397
|
+
uniform token info:id = "UsdPreviewSurface"
|
398
|
+
${inputs.join("\n")}
|
399
|
+
int inputs:useSpecularWorkflow = 0
|
400
|
+
token outputs:surface
|
401
|
+
}
|
402
|
+
|
403
|
+
token outputs:surface.connect = </Materials/Material_${material.uniqueId}/PreviewSurface.outputs:surface>
|
404
|
+
|
405
|
+
${samplers.join("\n")}
|
406
|
+
|
407
|
+
}
|
408
|
+
`;
|
409
|
+
}
|
410
|
+
function BuildCamera(camera, options) {
|
411
|
+
const name = "Camera_" + camera.uniqueId;
|
412
|
+
const matrix = Matrix.RotationY(Math.PI).multiply(camera.getWorldMatrix()); // work towards positive z
|
413
|
+
const transform = BuildMatrix(matrix);
|
414
|
+
if (camera.mode === Constants.ORTHOGRAPHIC_CAMERA) {
|
415
|
+
return `def Camera "${name}"
|
416
|
+
{
|
417
|
+
matrix4d xformOp:transform = ${transform}
|
418
|
+
uniform token[] xformOpOrder = ["xformOp:transform"]
|
419
|
+
|
420
|
+
float2 clippingRange = (${camera.minZ.toPrecision(options.precision)}, ${camera.maxZ.toPrecision(options.precision)})
|
421
|
+
float horizontalAperture = ${((Math.abs(camera.orthoLeft || 1) + Math.abs(camera.orthoRight || 1)) * 10).toPrecision(options.precision)}
|
422
|
+
float verticalAperture = ${((Math.abs(camera.orthoTop || 1) + Math.abs(camera.orthoBottom || 1)) * 10).toPrecision(options.precision)}
|
423
|
+
token projection = "orthographic"
|
424
|
+
}
|
425
|
+
|
426
|
+
`;
|
427
|
+
}
|
428
|
+
else {
|
429
|
+
const aspect = camera.getEngine().getAspectRatio(camera);
|
430
|
+
const sensorwidth = options.cameraSensorWidth || 35;
|
431
|
+
return `def Camera "${name}"
|
432
|
+
{
|
433
|
+
matrix4d xformOp:transform = ${transform}
|
434
|
+
uniform token[] xformOpOrder = ["xformOp:transform"]
|
435
|
+
|
436
|
+
float2 clippingRange = (${camera.minZ.toPrecision(options.precision)}, ${camera.maxZ.toPrecision(options.precision)})
|
437
|
+
float focalLength = ${(sensorwidth / (2 * Math.tan(camera.fov * 0.5))).toPrecision(options.precision)}
|
438
|
+
token projection = "perspective"
|
439
|
+
float horizontalAperture = ${(sensorwidth * aspect).toPrecision(options.precision)}
|
440
|
+
float verticalAperture = ${(sensorwidth / aspect).toPrecision(options.precision)}
|
441
|
+
}
|
442
|
+
|
443
|
+
`;
|
444
|
+
}
|
445
|
+
}
|
446
|
+
/**
|
447
|
+
*
|
448
|
+
* @param scene scene to export
|
449
|
+
* @param options options to configure the export
|
450
|
+
* @param meshPredicate predicate to filter the meshes to export
|
451
|
+
* @returns a uint8 array containing the USDZ file
|
452
|
+
* #H2G5XW#3 - Simple sphere
|
453
|
+
* #H2G5XW#4 - Red sphere
|
454
|
+
* #5N3RWK#4 - Boombox
|
455
|
+
*/
|
456
|
+
export async function USDZExportAsync(scene, options, meshPredicate) {
|
457
|
+
const localOptions = {
|
458
|
+
fflateUrl: "https://unpkg.com/fflate@0.8.2",
|
459
|
+
includeAnchoringProperties: true,
|
460
|
+
anchoringType: "plane",
|
461
|
+
planeAnchoringAlignment: "horizontal",
|
462
|
+
modelFileName: "model.usda",
|
463
|
+
precision: 5,
|
464
|
+
exportCamera: false,
|
465
|
+
cameraSensorWidth: 35,
|
466
|
+
...options,
|
467
|
+
};
|
468
|
+
// Get the fflate library
|
469
|
+
if (typeof fflate === "undefined") {
|
470
|
+
await Tools.LoadScriptAsync(localOptions.fflateUrl);
|
471
|
+
}
|
472
|
+
// Start the export
|
473
|
+
const files = {};
|
474
|
+
// model file should be first in USDZ archive so we init it here
|
475
|
+
files[localOptions.modelFileName] = null;
|
476
|
+
let output = BuildHeader();
|
477
|
+
output += BuildSceneStart(localOptions);
|
478
|
+
const materialToExports = {};
|
479
|
+
// Meshes
|
480
|
+
for (const abstractMesh of scene.meshes) {
|
481
|
+
if (abstractMesh.getTotalVertices() === 0) {
|
482
|
+
continue;
|
483
|
+
}
|
484
|
+
const mesh = abstractMesh;
|
485
|
+
const geometry = mesh.geometry;
|
486
|
+
const material = mesh.material;
|
487
|
+
if (!material || !geometry || (meshPredicate && !meshPredicate(mesh))) {
|
488
|
+
continue;
|
489
|
+
}
|
490
|
+
const supportedMaterials = ["StandardMaterial", "PBRMaterial", "PBRMetallicRoughnessMaterial"];
|
491
|
+
if (supportedMaterials.indexOf(material.getClassName()) !== -1) {
|
492
|
+
const geometryFileName = "geometries/Geometry_" + geometry.uniqueId + ".usda";
|
493
|
+
if (!(geometryFileName in files)) {
|
494
|
+
const meshObject = BuildMeshObject(geometry, localOptions);
|
495
|
+
files[geometryFileName] = BuildUSDFileAsString(meshObject);
|
496
|
+
}
|
497
|
+
if (!(material.uniqueId in materialToExports)) {
|
498
|
+
materialToExports[material.uniqueId] = material;
|
499
|
+
}
|
500
|
+
output += BuildXform(mesh);
|
501
|
+
}
|
502
|
+
else {
|
503
|
+
Tools.Warn("USDZExportAsync does not support this material type: " + material.getClassName());
|
504
|
+
}
|
505
|
+
}
|
506
|
+
// Camera
|
507
|
+
if (scene.activeCamera && localOptions.exportCamera) {
|
508
|
+
output += BuildCamera(scene.activeCamera, localOptions);
|
509
|
+
}
|
510
|
+
// Close scene
|
511
|
+
output += BuildSceneEnd();
|
512
|
+
// Materials
|
513
|
+
const textureToExports = {};
|
514
|
+
output += BuildMaterials(materialToExports, textureToExports, localOptions);
|
515
|
+
// Compress
|
516
|
+
files[localOptions.modelFileName] = fflate.strToU8(output);
|
517
|
+
// Textures
|
518
|
+
for (const id in textureToExports) {
|
519
|
+
const texture = textureToExports[id];
|
520
|
+
const size = texture.getSize();
|
521
|
+
const textureData = await texture.readPixels();
|
522
|
+
if (!textureData) {
|
523
|
+
throw new Error("Texture data is not available");
|
524
|
+
}
|
525
|
+
const fileContent = await DumpTools.DumpDataAsync(size.width, size.height, textureData, "image/png", undefined, false, true);
|
526
|
+
files[`textures/Texture_${id}.png`] = new Uint8Array(fileContent).slice(); // This is to avoid getting a link and not a copy
|
527
|
+
}
|
528
|
+
// 64 byte alignment
|
529
|
+
// https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
|
530
|
+
let offset = 0;
|
531
|
+
for (const filename in files) {
|
532
|
+
const file = files[filename];
|
533
|
+
if (!file) {
|
534
|
+
continue;
|
535
|
+
}
|
536
|
+
const headerSize = 34 + filename.length;
|
537
|
+
offset += headerSize;
|
538
|
+
const offsetMod64 = offset & 63;
|
539
|
+
if (offsetMod64 !== 4) {
|
540
|
+
const padLength = 64 - offsetMod64;
|
541
|
+
const padding = new Uint8Array(padLength);
|
542
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
543
|
+
files[filename] = [file, { extra: { 12345: padding } }];
|
544
|
+
}
|
545
|
+
offset = file.length;
|
546
|
+
}
|
547
|
+
return fflate.zipSync(files, { level: 0 });
|
548
|
+
}
|
549
|
+
//# sourceMappingURL=usdzExporter.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"usdzExporter.js","sourceRoot":"","sources":["../../../../dev/serializers/src/USDZ/usdzExporter.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { PBRMetallicRoughnessMaterial } from \"core/Materials/PBR/pbrMetallicRoughnessMaterial\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Matrix, Vector2 } from \"core/Maths/math.vector\";\r\nimport type { Geometry } from \"core/Meshes/geometry\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\nimport { DumpTools } from \"core/Misc/dumpTools\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { FloatArray, Nullable } from \"core/types\";\r\n\r\n/**\r\n * Ported from https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/USDZExporter.js\r\n * Thanks a lot to the three.js team for their amazing work!\r\n */\r\n\r\n// FFlate access\r\ndeclare const fflate: any;\r\n\r\n/**\r\n * Options for the USDZ export\r\n */\r\nexport interface IUSDZExportOptions {\r\n /**\r\n * URL to load the fflate library from\r\n */\r\n fflateUrl?: string;\r\n /**\r\n * Include anchoring properties in the USDZ file\r\n */\r\n includeAnchoringProperties?: boolean;\r\n /**\r\n * Anchoring type (plane by default)\r\n */\r\n anchoringType?: string;\r\n /**\r\n * Plane anchoring alignment (horizontal by default)\r\n */\r\n planeAnchoringAlignment?: string;\r\n /**\r\n * Model file name (model.usda by default)\r\n */\r\n modelFileName?: string;\r\n /**\r\n * Precision to use for number (5 by default)\r\n */\r\n precision?: number;\r\n /**\r\n * Export the camera (false by default)\r\n */\r\n exportCamera?: boolean;\r\n /**\r\n * Camera sensor width (35 by default)\r\n */\r\n cameraSensorWidth?: number;\r\n}\r\n\r\nfunction BuildHeader() {\r\n return `#usda 1.0\r\n (\r\n customLayerData = {\r\n string creator = \"Babylon.js USDZExportAsync\"\r\n }\r\n defaultPrim = \"Root\"\r\n metersPerUnit = 1\r\n upAxis = \"Y\"\r\n )`;\r\n}\r\n\r\nfunction BuildSceneStart(options: IUSDZExportOptions) {\r\n const alignment =\r\n options.includeAnchoringProperties === true\r\n ? `\r\n\t\ttoken preliminary:anchoring:type = \"${options.anchoringType}\"\r\n\t\ttoken preliminary:planeAnchoring:alignment = \"${options.planeAnchoringAlignment}\"`\r\n : \"\";\r\n return `def Xform \"Root\"\r\n {\r\n def Scope \"Scenes\" (\r\n kind = \"sceneLibrary\"\r\n )\r\n {\r\n def Xform \"Scene\" (\r\n customData = {\r\n bool preliminary_collidesWithEnvironment = 0\r\n string sceneName = \"Scene\"\r\n }\r\n sceneName = \"Scene\"\r\n )\r\n {${alignment}\r\n `;\r\n}\r\n\r\nfunction BuildSceneEnd() {\r\n return `\r\n }\r\n }\r\n }`;\r\n}\r\n\r\nfunction BuildMeshVertexCount(geometry: Geometry) {\r\n const count = geometry.getIndices()?.length ? geometry.getTotalIndices() : geometry.getTotalVertices();\r\n\r\n return Array(count / 3)\r\n .fill(3)\r\n .join(\", \");\r\n}\r\n\r\nfunction BuildMeshVertexIndices(geometry: Geometry) {\r\n const index = geometry.getIndices();\r\n const array = [];\r\n\r\n if (index !== null) {\r\n for (let i = 0; i < index.length; i++) {\r\n array.push(index[i]);\r\n }\r\n } else {\r\n const length = geometry.getTotalVertices();\r\n\r\n for (let i = 0; i < length; i++) {\r\n array.push(i);\r\n }\r\n }\r\n\r\n return array.join(\", \");\r\n}\r\n\r\nfunction BuildVector3Array(attribute: FloatArray, options: IUSDZExportOptions, stride = 3) {\r\n const array = [];\r\n\r\n for (let i = 0; i < attribute.length / stride; i++) {\r\n const x = attribute[i * stride];\r\n const y = attribute[i * stride + 1];\r\n const z = attribute[i * stride + 2];\r\n\r\n array.push(`(${x.toPrecision(options.precision)}, ${y.toPrecision(options.precision)}, ${z.toPrecision(options.precision)})`);\r\n }\r\n\r\n return array.join(\", \");\r\n}\r\n\r\nfunction BuildVector2Array(attribute: FloatArray, options: IUSDZExportOptions) {\r\n const array = [];\r\n\r\n for (let i = 0; i < attribute.length / 2; i++) {\r\n const x = attribute[i * 2];\r\n const y = attribute[i * 2 + 1];\r\n\r\n array.push(`(${x.toPrecision(options.precision)}, ${(1 - y).toPrecision(options.precision)})`);\r\n }\r\n\r\n return array.join(\", \");\r\n}\r\n\r\nfunction BuildAdditionalAttributes(geometry: Geometry, options: IUSDZExportOptions) {\r\n let string = \"\";\r\n\r\n for (let i = 0; i < 4; i++) {\r\n const id = i > 0 ? i : \"\";\r\n const uvAttribute = geometry.getVerticesData(VertexBuffer.UVKind + (id ? id : \"\"));\r\n\r\n if (uvAttribute) {\r\n string += `\r\n\t\ttexCoord2f[] primvars:st${id} = [${BuildVector2Array(uvAttribute, options)}] (\r\n\t\t\tinterpolation = \"vertex\"\r\n\t\t)`;\r\n }\r\n }\r\n\r\n // vertex colors\r\n\r\n const colorAttribute = geometry.getVerticesData(VertexBuffer.ColorKind);\r\n\r\n if (colorAttribute) {\r\n string += `\r\n\tcolor3f[] primvars:displayColor = [${BuildVector3Array(colorAttribute, options, 4)}] (\r\n\t\tinterpolation = \"vertex\"\r\n\t\t)`;\r\n }\r\n\r\n return string;\r\n}\r\n\r\nfunction BuildMesh(geometry: Geometry, options: IUSDZExportOptions) {\r\n const name = \"Geometry\";\r\n const position = geometry.getVerticesData(VertexBuffer.PositionKind);\r\n const normal = geometry.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n if (!position || !normal) {\r\n return;\r\n }\r\n\r\n return `\r\n\tdef Mesh \"${name}\"\r\n\t{\r\n\t\tint[] faceVertexCounts = [${BuildMeshVertexCount(geometry)}]\r\n\t\tint[] faceVertexIndices = [${BuildMeshVertexIndices(geometry)}]\r\n\t\tnormal3f[] normals = [${BuildVector3Array(normal, options)}] (\r\n\t\t\tinterpolation = \"vertex\"\r\n\t\t)\r\n\t\tpoint3f[] points = [${BuildVector3Array(position, options)}]\r\n ${BuildAdditionalAttributes(geometry, options)}\r\n\t\tuniform token subdivisionScheme = \"none\"\r\n\t}\r\n`;\r\n}\r\n\r\nfunction BuildMeshObject(geometry: Geometry, options: IUSDZExportOptions) {\r\n const mesh = BuildMesh(geometry, options);\r\n return `\r\n def \"Geometry\"\r\n {\r\n ${mesh}\r\n }\r\n `;\r\n}\r\n\r\nfunction BuildUSDFileAsString(dataToInsert: string) {\r\n let output = BuildHeader();\r\n output += dataToInsert;\r\n return fflate.strToU8(output);\r\n}\r\n\r\nfunction BuildMatrix(matrix: Matrix) {\r\n const array = matrix.m as number[];\r\n\r\n return `( ${BuildMatrixRow(array, 0)}, ${BuildMatrixRow(array, 4)}, ${BuildMatrixRow(array, 8)}, ${BuildMatrixRow(array, 12)} )`;\r\n}\r\n\r\nfunction BuildMatrixRow(array: number[], offset: number) {\r\n return `(${array[offset + 0]}, ${array[offset + 1]}, ${array[offset + 2]}, ${array[offset + 3]})`;\r\n}\r\n\r\nfunction BuildXform(mesh: Mesh) {\r\n const name = \"Object_\" + mesh.uniqueId;\r\n const matrix = mesh.getWorldMatrix().clone();\r\n\r\n if (matrix.determinant() < 0) {\r\n matrix.multiplyToRef(Matrix.Scaling(-1, 1, 1), matrix);\r\n }\r\n const transform = BuildMatrix(matrix);\r\n\r\n return `def Xform \"${name}\" (\r\n\tprepend references = @./geometries/Geometry_${mesh.geometry!.uniqueId}.usda@</Geometry>\r\n\tprepend apiSchemas = [\"MaterialBindingAPI\"]\r\n)\r\n{\r\n\tmatrix4d xformOp:transform = ${transform}\r\n\tuniform token[] xformOpOrder = [\"xformOp:transform\"]\t\r\n\r\n rel material:binding = </Materials/Material_${mesh.material!.uniqueId}>\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction BuildMaterials(materials: { [key: string]: Material }, textureToExports: { [key: string]: BaseTexture }, options: IUSDZExportOptions) {\r\n const array = [];\r\n\r\n for (const uuid in materials) {\r\n const material = materials[uuid];\r\n\r\n array.push(BuildMaterial(material, textureToExports, options));\r\n }\r\n\r\n return `\r\n def \"Materials\"\r\n{\r\n${array.join(\"\")}\r\n}\r\n\r\n`;\r\n}\r\n\r\nfunction BuildWrapping(wrapping: number) {\r\n switch (wrapping) {\r\n case Constants.TEXTURE_CLAMP_ADDRESSMODE:\r\n return \"clamp\";\r\n case Constants.TEXTURE_MIRROR_ADDRESSMODE:\r\n return \"mirror\";\r\n case Constants.TEXTURE_WRAP_ADDRESSMODE:\r\n default:\r\n return \"repeat\";\r\n }\r\n}\r\n\r\nfunction BuildColor4(color: Color3) {\r\n return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;\r\n}\r\n\r\nfunction BuildVector2(vector: Vector2) {\r\n return `(${vector.x}, ${vector.y})`;\r\n}\r\n\r\nfunction BuildColor(color: Color3) {\r\n return `(${color.r}, ${color.g}, ${color.b})`;\r\n}\r\n\r\nfunction BuildTexture(\r\n texture: Texture,\r\n material: Material,\r\n mapType: string,\r\n color: Nullable<Color3>,\r\n textureToExports: { [key: string]: BaseTexture },\r\n options: IUSDZExportOptions\r\n) {\r\n const id = texture.getInternalTexture()!.uniqueId + \"_\" + texture.invertY;\r\n\r\n textureToExports[id] = texture;\r\n\r\n const uv = texture.coordinatesIndex > 0 ? \"st\" + texture.coordinatesIndex : \"st\";\r\n const repeat = new Vector2(texture.uScale, texture.vScale);\r\n const offset = new Vector2(texture.uOffset, texture.vOffset);\r\n const rotation = texture.wAng;\r\n\r\n // rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot\r\n const xRotationOffset = Math.sin(rotation);\r\n const yRotationOffset = Math.cos(rotation);\r\n\r\n // texture coordinates start in the opposite corner, need to correct\r\n offset.y = 1 - offset.y - repeat.y;\r\n\r\n offset.x += xRotationOffset * repeat.x;\r\n offset.y += (1 - yRotationOffset) * repeat.y;\r\n\r\n return `\r\n def Shader \"PrimvarReader_${mapType}\"\r\n {\r\n uniform token info:id = \"UsdPrimvarReader_float2\"\r\n float2 inputs:fallback = (0.0, 0.0)\r\n token inputs:varname = \"${uv}\"\r\n float2 outputs:result\r\n }\r\n\r\n def Shader \"Transform2d_${mapType}\"\r\n {\r\n uniform token info:id = \"UsdTransform2d\"\r\n token inputs:in.connect = </Materials/Material_${material.uniqueId}/PrimvarReader_${mapType}.outputs:result>\r\n float inputs:rotation = ${(rotation * (180 / Math.PI)).toFixed(options.precision)}\r\n float2 inputs:scale = ${BuildVector2(repeat)}\r\n float2 inputs:translation = ${BuildVector2(offset)}\r\n float2 outputs:result\r\n }\r\n\r\n def Shader \"Texture_${texture.uniqueId}_${mapType}\"\r\n {\r\n uniform token info:id = \"UsdUVTexture\"\r\n asset inputs:file = @textures/Texture_${id}.png@\r\n float2 inputs:st.connect = </Materials/Material_${material.uniqueId}/Transform2d_${mapType}.outputs:result>\r\n ${color ? \"float4 inputs:scale = \" + BuildColor4(color) : \"\"}\r\n token inputs:sourceColorSpace = \"${texture.gammaSpace ? \"raw\" : \"sRGB\"}\"\r\n token inputs:wrapS = \"${BuildWrapping(texture.wrapU)}\"\r\n token inputs:wrapT = \"${BuildWrapping(texture.wrapV)}\"\r\n float outputs:r\r\n float outputs:g\r\n float outputs:b\r\n float3 outputs:rgb\r\n ${material.needAlphaBlending() ? \"float outputs:a\" : \"\"}\r\n }`;\r\n}\r\n\r\nfunction ExtractTextureInformations(material: Material) {\r\n const className = material.getClassName();\r\n\r\n switch (className) {\r\n case \"StandardMaterial\":\r\n return {\r\n diffuseMap: (material as StandardMaterial).diffuseTexture,\r\n diffuse: (material as StandardMaterial).diffuseColor,\r\n alphaCutOff: (material as StandardMaterial).alphaCutOff,\r\n emissiveMap: (material as StandardMaterial).emissiveTexture,\r\n emissive: (material as StandardMaterial).emissiveColor,\r\n roughnessMap: null,\r\n normalMap: null,\r\n metalnessMap: null,\r\n roughness: 1,\r\n metalness: 0,\r\n aoMap: null,\r\n aoMapIntensity: 0,\r\n alphaMap: (material as StandardMaterial).opacityTexture,\r\n ior: 1,\r\n };\r\n case \"PBRMaterial\":\r\n return {\r\n diffuseMap: (material as PBRMaterial).albedoTexture,\r\n diffuse: (material as PBRMaterial).albedoColor,\r\n alphaCutOff: (material as PBRMaterial).alphaCutOff,\r\n emissiveMap: (material as PBRMaterial).emissiveTexture,\r\n emissive: (material as PBRMaterial).emissiveColor,\r\n normalMap: (material as PBRMaterial).bumpTexture,\r\n roughnessMap: (material as PBRMaterial).metallicTexture,\r\n roughnessChannel: (material as PBRMaterial).useRoughnessFromMetallicTextureAlpha ? \"a\" : \"g\",\r\n roughness: (material as PBRMaterial).roughness || 1,\r\n metalnessMap: (material as PBRMaterial).metallicTexture,\r\n metalnessChannel: (material as PBRMaterial).useMetallnessFromMetallicTextureBlue ? \"b\" : \"r\",\r\n metalness: (material as PBRMaterial).metallic || 0,\r\n aoMap: (material as PBRMaterial).ambientTexture,\r\n aoMapChannel: (material as PBRMaterial).useAmbientInGrayScale ? \"r\" : \"rgb\",\r\n aoMapIntensity: (material as PBRMaterial).ambientTextureStrength,\r\n alphaMap: (material as PBRMaterial).opacityTexture,\r\n ior: (material as PBRMaterial).indexOfRefraction,\r\n };\r\n case \"PBRMetallicRoughnessMaterial\":\r\n return {\r\n diffuseMap: (material as PBRMetallicRoughnessMaterial).baseTexture,\r\n diffuse: (material as PBRMetallicRoughnessMaterial).baseColor,\r\n alphaCutOff: (material as PBRMetallicRoughnessMaterial).alphaCutOff,\r\n emissiveMap: (material as PBRMetallicRoughnessMaterial).emissiveTexture,\r\n emissive: (material as PBRMetallicRoughnessMaterial).emissiveColor,\r\n normalMap: (material as PBRMetallicRoughnessMaterial).normalTexture,\r\n roughnessMap: (material as PBRMaterial).metallicTexture,\r\n roughnessChannel: (material as PBRMaterial).useRoughnessFromMetallicTextureAlpha ? \"a\" : \"g\",\r\n roughness: (material as PBRMetallicRoughnessMaterial).roughness || 1,\r\n metalnessMap: (material as PBRMaterial).metallicTexture,\r\n metalnessChannel: (material as PBRMaterial).useMetallnessFromMetallicTextureBlue ? \"b\" : \"r\",\r\n metalness: (material as PBRMetallicRoughnessMaterial).metallic || 0,\r\n aoMap: (material as PBRMaterial).ambientTexture,\r\n aoMapChannel: (material as PBRMaterial).useAmbientInGrayScale ? \"r\" : \"rgb\",\r\n aoMapIntensity: (material as PBRMaterial).ambientTextureStrength,\r\n alphaMap: (material as PBRMaterial).opacityTexture,\r\n ior: (material as PBRMaterial).indexOfRefraction,\r\n };\r\n default:\r\n return {\r\n diffuseMap: null,\r\n diffuse: null,\r\n emissiveMap: null,\r\n emissemissiveiveColor: null,\r\n normalMap: null,\r\n roughnessMap: null,\r\n metalnessMap: null,\r\n alphaCutOff: 0,\r\n roughness: 0,\r\n metalness: 0,\r\n aoMap: null,\r\n aoMapIntensity: 0,\r\n alphaMap: null,\r\n ior: 1,\r\n };\r\n }\r\n}\r\n\r\nfunction BuildMaterial(material: Material, textureToExports: { [key: string]: BaseTexture }, options: IUSDZExportOptions) {\r\n // https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html\r\n\r\n const pad = \"\t\t\t\";\r\n const inputs = [];\r\n const samplers = [];\r\n\r\n const {\r\n diffuseMap,\r\n diffuse,\r\n alphaCutOff,\r\n emissiveMap,\r\n emissive,\r\n normalMap,\r\n roughnessMap,\r\n roughnessChannel,\r\n roughness,\r\n metalnessMap,\r\n metalnessChannel,\r\n metalness,\r\n aoMap,\r\n aoMapChannel,\r\n aoMapIntensity,\r\n alphaMap,\r\n ior,\r\n } = ExtractTextureInformations(material);\r\n\r\n if (diffuseMap !== null) {\r\n inputs.push(`${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:rgb>`);\r\n\r\n if (material.needAlphaBlending()) {\r\n inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:a>`);\r\n } else if (material.needAlphaTesting()) {\r\n inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${diffuseMap.uniqueId}_diffuse.outputs:a>`);\r\n inputs.push(`${pad}float inputs:opacityThreshold = ${alphaCutOff}`);\r\n }\r\n\r\n samplers.push(BuildTexture(diffuseMap as Texture, material, \"diffuse\", diffuse, textureToExports, options));\r\n } else {\r\n inputs.push(`${pad}color3f inputs:diffuseColor = ${BuildColor(diffuse || Color3.White())}`);\r\n }\r\n\r\n if (emissiveMap !== null) {\r\n inputs.push(`${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.uniqueId}/Texture_${emissiveMap.uniqueId}_emissive.outputs:rgb>`);\r\n\r\n samplers.push(BuildTexture(emissiveMap as Texture, material, \"emissive\", emissive, textureToExports, options));\r\n } else if (emissive && emissive.toLuminance() > 0) {\r\n inputs.push(`${pad}color3f inputs:emissiveColor = ${BuildColor(emissive)}`);\r\n }\r\n\r\n if (normalMap !== null) {\r\n inputs.push(`${pad}normal3f inputs:normal.connect = </Materials/Material_${material.uniqueId}/Texture_${normalMap.uniqueId}_normal.outputs:rgb>`);\r\n\r\n samplers.push(BuildTexture(normalMap as Texture, material, \"normal\", null, textureToExports, options));\r\n }\r\n\r\n if (aoMap !== null) {\r\n inputs.push(`${pad}float inputs:occlusion.connect = </Materials/Material_${material.uniqueId}/Texture_${aoMap.uniqueId}_occlusion.outputs:${aoMapChannel}>`);\r\n\r\n samplers.push(BuildTexture(aoMap as Texture, material, \"occlusion\", new Color3(aoMapIntensity, aoMapIntensity, aoMapIntensity), textureToExports, options));\r\n }\r\n\r\n if (roughnessMap !== null) {\r\n inputs.push(`${pad}float inputs:roughness.connect = </Materials/Material_${material.uniqueId}/Texture_${roughnessMap.uniqueId}_roughness.outputs:${roughnessChannel}>`);\r\n\r\n samplers.push(BuildTexture(roughnessMap as Texture, material, \"roughness\", new Color3(roughness, roughness, roughness), textureToExports, options));\r\n } else {\r\n inputs.push(`${pad}float inputs:roughness = ${roughness}`);\r\n }\r\n\r\n if (metalnessMap !== null) {\r\n inputs.push(`${pad}float inputs:metallic.connect = </Materials/Material_${material.uniqueId}/Texture_${metalnessMap.uniqueId}_metallic.outputs:${metalnessChannel}>`);\r\n\r\n samplers.push(BuildTexture(metalnessMap as Texture, material, \"metallic\", new Color3(metalness, metalness, metalness), textureToExports, options));\r\n } else {\r\n inputs.push(`${pad}float inputs:metallic = ${metalness}`);\r\n }\r\n\r\n if (alphaMap !== null) {\r\n inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.uniqueId}/Texture_${alphaMap.uniqueId}_opacity.outputs:r>`);\r\n inputs.push(`${pad}float inputs:opacityThreshold = 0.0001`);\r\n\r\n samplers.push(BuildTexture(alphaMap as Texture, material, \"opacity\", null, textureToExports, options));\r\n } else {\r\n inputs.push(`${pad}float inputs:opacity = ${material.alpha}`);\r\n }\r\n\r\n inputs.push(`${pad}float inputs:ior = ${ior}`);\r\n\r\n return `\r\n\tdef Material \"Material_${material.uniqueId}\"\r\n\t{\r\n\t\tdef Shader \"PreviewSurface\"\r\n\t\t{\r\n\t\t\tuniform token info:id = \"UsdPreviewSurface\"\r\n${inputs.join(\"\\n\")}\r\n\t\t\tint inputs:useSpecularWorkflow = 0\r\n\t\t\ttoken outputs:surface\r\n\t\t}\r\n\r\n\t\ttoken outputs:surface.connect = </Materials/Material_${material.uniqueId}/PreviewSurface.outputs:surface>\r\n\r\n${samplers.join(\"\\n\")}\r\n\r\n\t}\r\n`;\r\n}\r\n\r\nfunction BuildCamera(camera: Camera, options: IUSDZExportOptions) {\r\n const name = \"Camera_\" + camera.uniqueId;\r\n const matrix = Matrix.RotationY(Math.PI).multiply(camera.getWorldMatrix()); // work towards positive z\r\n\r\n const transform = BuildMatrix(matrix);\r\n\r\n if (camera.mode === Constants.ORTHOGRAPHIC_CAMERA) {\r\n return `def Camera \"${name}\"\r\n\t\t{\r\n\t\t\tmatrix4d xformOp:transform = ${transform}\r\n\t\t\tuniform token[] xformOpOrder = [\"xformOp:transform\"]\r\n\r\n\t\t\tfloat2 clippingRange = (${camera.minZ.toPrecision(options.precision)}, ${camera.maxZ.toPrecision(options.precision)})\r\n\t\t\tfloat horizontalAperture = ${((Math.abs(camera.orthoLeft || 1) + Math.abs(camera.orthoRight || 1)) * 10).toPrecision(options.precision)}\r\n\t\t\tfloat verticalAperture = ${((Math.abs(camera.orthoTop || 1) + Math.abs(camera.orthoBottom || 1)) * 10).toPrecision(options.precision)}\r\n\t\t\ttoken projection = \"orthographic\"\r\n\t\t}\r\n\t\r\n\t`;\r\n } else {\r\n const aspect = camera.getEngine().getAspectRatio(camera);\r\n const sensorwidth = options.cameraSensorWidth || 35;\r\n\r\n return `def Camera \"${name}\"\r\n\t\t{\r\n\t\t\tmatrix4d xformOp:transform = ${transform}\r\n\t\t\tuniform token[] xformOpOrder = [\"xformOp:transform\"]\r\n\r\n\t\t\tfloat2 clippingRange = (${camera.minZ.toPrecision(options.precision)}, ${camera.maxZ.toPrecision(options.precision)})\r\n\t\t\tfloat focalLength = ${(sensorwidth / (2 * Math.tan(camera.fov * 0.5))).toPrecision(options.precision)}\r\n token projection = \"perspective\"\r\n\t\t\tfloat horizontalAperture = ${(sensorwidth * aspect).toPrecision(options.precision)}\r\n\t\t\tfloat verticalAperture = ${(sensorwidth / aspect).toPrecision(options.precision)} \r\n\t\t}\r\n\t\r\n\t`;\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param scene scene to export\r\n * @param options options to configure the export\r\n * @param meshPredicate predicate to filter the meshes to export\r\n * @returns a uint8 array containing the USDZ file\r\n * #H2G5XW#3 - Simple sphere\r\n * #H2G5XW#4 - Red sphere\r\n * #5N3RWK#4 - Boombox\r\n */\r\nexport async function USDZExportAsync(scene: Scene, options: Partial<IUSDZExportOptions>, meshPredicate?: (m: Mesh) => boolean): Promise<Uint8Array> {\r\n const localOptions = {\r\n fflateUrl: \"https://unpkg.com/fflate@0.8.2\",\r\n includeAnchoringProperties: true,\r\n anchoringType: \"plane\",\r\n planeAnchoringAlignment: \"horizontal\",\r\n modelFileName: \"model.usda\",\r\n precision: 5,\r\n exportCamera: false,\r\n cameraSensorWidth: 35,\r\n ...options,\r\n };\r\n\r\n // Get the fflate library\r\n if (typeof fflate === \"undefined\") {\r\n await Tools.LoadScriptAsync(localOptions.fflateUrl);\r\n }\r\n\r\n // Start the export\r\n const files: { [key: string]: any } = {};\r\n\r\n // model file should be first in USDZ archive so we init it here\r\n files[localOptions.modelFileName] = null;\r\n\r\n let output = BuildHeader();\r\n output += BuildSceneStart(localOptions);\r\n\r\n const materialToExports: { [key: string]: Material } = {};\r\n\r\n // Meshes\r\n for (const abstractMesh of scene.meshes) {\r\n if (abstractMesh.getTotalVertices() === 0) {\r\n continue;\r\n }\r\n const mesh = abstractMesh as Mesh;\r\n const geometry = mesh.geometry;\r\n const material = mesh.material;\r\n\r\n if (!material || !geometry || (meshPredicate && !meshPredicate(mesh))) {\r\n continue;\r\n }\r\n\r\n const supportedMaterials = [\"StandardMaterial\", \"PBRMaterial\", \"PBRMetallicRoughnessMaterial\"];\r\n\r\n if (supportedMaterials.indexOf(material.getClassName()) !== -1) {\r\n const geometryFileName = \"geometries/Geometry_\" + geometry.uniqueId + \".usda\";\r\n\r\n if (!(geometryFileName in files)) {\r\n const meshObject = BuildMeshObject(geometry, localOptions);\r\n files[geometryFileName] = BuildUSDFileAsString(meshObject);\r\n }\r\n\r\n if (!(material.uniqueId in materialToExports)) {\r\n materialToExports[material.uniqueId] = material;\r\n }\r\n\r\n output += BuildXform(mesh);\r\n } else {\r\n Tools.Warn(\"USDZExportAsync does not support this material type: \" + material.getClassName());\r\n }\r\n }\r\n\r\n // Camera\r\n if (scene.activeCamera && localOptions.exportCamera) {\r\n output += BuildCamera(scene.activeCamera, localOptions);\r\n }\r\n\r\n // Close scene\r\n output += BuildSceneEnd();\r\n\r\n // Materials\r\n const textureToExports: { [key: string]: BaseTexture } = {};\r\n output += BuildMaterials(materialToExports, textureToExports, localOptions);\r\n\r\n // Compress\r\n files[localOptions.modelFileName] = fflate.strToU8(output);\r\n\r\n // Textures\r\n for (const id in textureToExports) {\r\n const texture = textureToExports[id];\r\n\r\n const size = texture.getSize();\r\n const textureData = await texture.readPixels();\r\n\r\n if (!textureData) {\r\n throw new Error(\"Texture data is not available\");\r\n }\r\n\r\n const fileContent = await DumpTools.DumpDataAsync(size.width, size.height, textureData, \"image/png\", undefined, false, true);\r\n\r\n files[`textures/Texture_${id}.png`] = new Uint8Array(fileContent as ArrayBuffer).slice(); // This is to avoid getting a link and not a copy\r\n }\r\n\r\n // 64 byte alignment\r\n // https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109\r\n\r\n let offset = 0;\r\n\r\n for (const filename in files) {\r\n const file = files[filename];\r\n if (!file) {\r\n continue;\r\n }\r\n const headerSize = 34 + filename.length;\r\n\r\n offset += headerSize;\r\n\r\n const offsetMod64 = offset & 63;\r\n\r\n if (offsetMod64 !== 4) {\r\n const padLength = 64 - offsetMod64;\r\n const padding = new Uint8Array(padLength);\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n files[filename] = [file, { extra: { 12345: padding } }];\r\n }\r\n\r\n offset = file.length;\r\n }\r\n\r\n return fflate.zipSync(files, { level: 0 });\r\n}\r\n"]}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dev/serializers/src/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC","sourcesContent":["/* eslint-disable import/no-internal-modules */\r\nexport * from \"./OBJ/index\";\r\nexport * from \"./glTF/index\";\r\nexport * from \"./stl/index\";\r\n"]}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dev/serializers/src/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC","sourcesContent":["/* eslint-disable import/no-internal-modules */\r\nexport * from \"./OBJ/index\";\r\nexport * from \"./glTF/index\";\r\nexport * from \"./stl/index\";\r\nexport * from \"./USDZ/index\";\r\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "../USDZ/index.js";
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/* eslint-disable import/no-internal-modules */
|
2
|
+
import * as Serializers from "../USDZ/index.js";
|
3
|
+
/**
|
4
|
+
* This is the entry point for the UMD module.
|
5
|
+
* The entry point for a future ESM package should be index.ts
|
6
|
+
*/
|
7
|
+
const globalObject = typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : undefined;
|
8
|
+
if (typeof globalObject !== "undefined") {
|
9
|
+
for (const serializer in Serializers) {
|
10
|
+
globalObject.BABYLON[serializer] = Serializers[serializer];
|
11
|
+
}
|
12
|
+
}
|
13
|
+
export * from "../USDZ/index.js";
|
14
|
+
//# sourceMappingURL=legacy-usdzSerializer.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"legacy-usdzSerializer.js","sourceRoot":"","sources":["../../../../lts/serializers/src/legacy/legacy-usdzSerializer.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,KAAK,WAAW,yBAA+B;AAEtD;;;GAGG;AACH,MAAM,YAAY,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACjH,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;IACrC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QAC5B,YAAa,CAAC,OAAO,CAAC,UAAU,CAAC,GAAS,WAAY,CAAC,UAAU,CAAC,CAAC;KAC5E;CACJ;AAED,iCAAuC","sourcesContent":["/* eslint-disable import/no-internal-modules */\r\nimport * as Serializers from \"serializers/USDZ/index\";\r\n\r\n/**\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nif (typeof globalObject !== \"undefined\") {\r\n for (const serializer in Serializers) {\r\n (<any>globalObject).BABYLON[serializer] = (<any>Serializers)[serializer];\r\n }\r\n}\r\n\r\nexport * from \"serializers/USDZ/index\";\r\n"]}
|
package/legacy/legacy.d.ts
CHANGED
package/legacy/legacy.js
CHANGED
package/legacy/legacy.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../../../lts/serializers/src/legacy/legacy.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,+CAA+C;AAC/C,qBAA2B;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC","sourcesContent":["/* eslint-disable import/export */\r\n/* eslint-disable import/no-internal-modules */\r\nimport \"serializers/index\";\r\nexport * from \"./legacy-glTF2Serializer\";\r\nexport * from \"./legacy-objSerializer\";\r\nexport * from \"./legacy-stlSerializer\";\r\n"]}
|
1
|
+
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../../../lts/serializers/src/legacy/legacy.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,+CAA+C;AAC/C,qBAA2B;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC","sourcesContent":["/* eslint-disable import/export */\r\n/* eslint-disable import/no-internal-modules */\r\nimport \"serializers/index\";\r\nexport * from \"./legacy-glTF2Serializer\";\r\nexport * from \"./legacy-objSerializer\";\r\nexport * from \"./legacy-stlSerializer\";\r\nexport * from \"./legacy-usdzSerializer\";\r\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@babylonjs/serializers",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.30.0",
|
4
4
|
"main": "index.js",
|
5
5
|
"module": "index.js",
|
6
6
|
"types": "index.d.ts",
|
@@ -18,10 +18,10 @@
|
|
18
18
|
"postcompile": "build-tools -c add-js-to-es6"
|
19
19
|
},
|
20
20
|
"devDependencies": {
|
21
|
-
"@babylonjs/core": "^7.
|
21
|
+
"@babylonjs/core": "^7.30.0",
|
22
22
|
"@dev/build-tools": "^1.0.0",
|
23
23
|
"@lts/serializers": "^1.0.0",
|
24
|
-
"babylonjs-gltf2interface": "^7.
|
24
|
+
"babylonjs-gltf2interface": "^7.30.0"
|
25
25
|
},
|
26
26
|
"peerDependencies": {
|
27
27
|
"@babylonjs/core": "^7.0.0",
|