@needle-tools/gltf-build-pipeline 2.13.0 → 2.13.1

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +520 -517
  2. package/README.md +38 -38
  3. package/dist/cache/cache.d.ts +55 -55
  4. package/dist/cache/cache.js +326 -326
  5. package/dist/cache/index.d.ts +1 -1
  6. package/dist/cache/index.js +1 -1
  7. package/dist/cli/index.d.ts +2 -2
  8. package/dist/cli/index.js +198 -198
  9. package/dist/config/index.d.ts +53 -53
  10. package/dist/config/index.js +152 -152
  11. package/dist/constants.d.ts +7 -7
  12. package/dist/constants.js +7 -7
  13. package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.d.ts +24 -24
  14. package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.js +54 -54
  15. package/dist/extensions/NEEDLE_compression_texture/index.d.ts +1 -1
  16. package/dist/extensions/NEEDLE_compression_texture/index.js +1 -1
  17. package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.d.ts +27 -27
  18. package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.js +88 -88
  19. package/dist/extensions/NEEDLE_mesh_compression/index.d.ts +1 -1
  20. package/dist/extensions/NEEDLE_mesh_compression/index.js +1 -1
  21. package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.d.ts +27 -27
  22. package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.js +980 -980
  23. package/dist/extensions/NEEDLE_opaque/index.d.ts +3 -3
  24. package/dist/extensions/NEEDLE_opaque/index.js +30 -30
  25. package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.d.ts +48 -48
  26. package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.js +69 -69
  27. package/dist/extensions/NEEDLE_progressive/index.d.ts +1 -1
  28. package/dist/extensions/NEEDLE_progressive/index.js +1 -1
  29. package/dist/extensions/NEEDLE_progressive_mesh_settings/index.d.ts +23 -23
  30. package/dist/extensions/NEEDLE_progressive_mesh_settings/index.js +41 -41
  31. package/dist/extensions/NEEDLE_progressive_texture_settings/index.d.ts +25 -25
  32. package/dist/extensions/NEEDLE_progressive_texture_settings/index.js +38 -38
  33. package/dist/extensions/index.d.ts +7 -7
  34. package/dist/extensions/index.js +17 -17
  35. package/dist/extensions/utils.d.ts +6 -6
  36. package/dist/extensions/utils.js +72 -72
  37. package/dist/functions/weld.3.d.ts +76 -76
  38. package/dist/functions/weld.3.js +414 -414
  39. package/dist/index.d.ts +8 -8
  40. package/dist/index.js +8 -8
  41. package/dist/scripts/index.d.ts +2 -2
  42. package/dist/scripts/index.js +2 -2
  43. package/dist/scripts/pack-gltf.d.ts +15 -15
  44. package/dist/scripts/pack-gltf.js +135 -133
  45. package/dist/scripts/stats.d.ts +2 -2
  46. package/dist/scripts/stats.js +19 -19
  47. package/dist/transforms/index.d.ts +9 -9
  48. package/dist/transforms/index.js +9 -9
  49. package/dist/transforms/needle_animation_transform.d.ts +2 -2
  50. package/dist/transforms/needle_animation_transform.js +5 -5
  51. package/dist/transforms/needle_asset.d.ts +3 -3
  52. package/dist/transforms/needle_asset.js +50 -50
  53. package/dist/transforms/needle_common.d.ts +17 -17
  54. package/dist/transforms/needle_common.js +1 -1
  55. package/dist/transforms/needle_mesh_transform.d.ts +15 -15
  56. package/dist/transforms/needle_mesh_transform.js +223 -223
  57. package/dist/transforms/needle_progressive.d.ts +45 -45
  58. package/dist/transforms/needle_progressive.js +1043 -1043
  59. package/dist/transforms/needle_texture_transform.d.ts +13 -13
  60. package/dist/transforms/needle_texture_transform.js +257 -257
  61. package/dist/transforms/needle_toktx.d.ts +26 -26
  62. package/dist/transforms/needle_toktx.js +243 -243
  63. package/dist/transforms/needle_webp.d.ts +15 -15
  64. package/dist/transforms/needle_webp.js +53 -53
  65. package/dist/transforms/toktx.d.ts +52 -52
  66. package/dist/transforms/toktx.js +221 -221
  67. package/dist/transforms/toktx_types.d.ts +78 -78
  68. package/dist/transforms/toktx_types.js +62 -62
  69. package/dist/transforms/util.d.ts +21 -21
  70. package/dist/transforms/util.js +90 -90
  71. package/dist/utils/compression_utils.d.ts +2 -2
  72. package/dist/utils/compression_utils.js +6 -6
  73. package/dist/utils/fileutils.d.ts +19 -19
  74. package/dist/utils/fileutils.js +177 -177
  75. package/dist/utils/guid.d.ts +1 -1
  76. package/dist/utils/guid.js +5 -5
  77. package/dist/utils/index.d.ts +10 -10
  78. package/dist/utils/index.js +10 -10
  79. package/dist/utils/merge.d.ts +12 -12
  80. package/dist/utils/merge.js +31 -31
  81. package/dist/utils/mesh.d.ts +13 -13
  82. package/dist/utils/mesh.js +124 -124
  83. package/dist/utils/nodeio.d.ts +6 -6
  84. package/dist/utils/nodeio.js +86 -86
  85. package/dist/utils/stats.d.ts +70 -70
  86. package/dist/utils/stats.js +258 -258
  87. package/dist/utils/texture.d.ts +5 -5
  88. package/dist/utils/texture.js +14 -14
  89. package/dist/utils/validate.d.ts +5 -5
  90. package/dist/utils/validate.js +17 -17
  91. package/dist/utils/version.d.ts +1 -1
  92. package/dist/utils/version.gen.d.ts +1 -1
  93. package/dist/utils/version.gen.js +1 -1
  94. package/dist/utils/version.js +4 -4
  95. package/package.json +79 -79
  96. package/scripts/clear-caches.mjs +3 -3
  97. package/scripts/defaults.mjs +11 -11
  98. package/scripts/fileutils.mjs +5 -5
  99. package/scripts/index.mjs +41 -41
  100. package/scripts/limit-caches.mjs +3 -3
  101. package/scripts/make-progressive.mjs +16 -16
  102. package/scripts/pack-gltf.mjs +106 -106
  103. package/tsconfig.json +19 -19
@@ -1,177 +1,177 @@
1
- import { existsSync, statSync, readdirSync, readFileSync, mkdirSync } from 'fs';
2
- import { dirname, isAbsolute, join } from 'path';
3
- /**
4
- * Get the output path for a file based on the output directory or file.
5
- * If outDirOrFile is a filepath, it will be returned as is.
6
- * If outDirOrFile is a directory, the file will be placed in that directory.
7
- */
8
- export function getOutputPath(filepath, outDirOrFile, opts) {
9
- if (!outDirOrFile) {
10
- return filepath;
11
- }
12
- if (!isDirectory(outDirOrFile)) {
13
- return outDirOrFile;
14
- }
15
- const filename = getFileName(filepath);
16
- // create the directory if it doesn't exist (default behavior)
17
- if (opts?.create != false && !existsSync(outDirOrFile)) {
18
- mkdirSync(outDirOrFile, { recursive: true });
19
- }
20
- const outpath = join(outDirOrFile, filename);
21
- return outpath;
22
- }
23
- export function getFileName(filepath) {
24
- const parts = filepath.replaceAll("\\", "/").split("/");
25
- return parts[parts.length - 1];
26
- }
27
- export function getDirName(filepath) {
28
- // should work for paths that end with "/" or not
29
- const parts = filepath.replaceAll("\\", "/").split("/");
30
- let res = parts.pop();
31
- if (res === "") {
32
- res = parts.pop();
33
- }
34
- return res;
35
- }
36
- export async function foreachGLTF(args, callback) {
37
- // get original directory this run was invoked from
38
- const initDir = process.env.INIT_CWD;
39
- const context = {
40
- baseDirectory: initDir,
41
- files: [],
42
- };
43
- // traverse recursively through all files and directories
44
- if (Array.isArray(args)) {
45
- for (const arg of args) {
46
- await testEntry(arg, context);
47
- }
48
- }
49
- else if (typeof args === "string") {
50
- await testEntry(args, context);
51
- }
52
- // try to run with needle config
53
- if (context.files?.length <= 0 && context.baseDirectory) {
54
- const needleConfigPath = context.baseDirectory + "/needle.config.json";
55
- if (existsSync(needleConfigPath)) {
56
- const config = JSON.parse(readFileSync(needleConfigPath, "utf8"));
57
- const buildDirectory = config.buildDirectory;
58
- if (buildDirectory?.length) {
59
- // If it's an absolute path
60
- if (existsSync(buildDirectory)) {
61
- console.log("INFO: Using build directory from needle.config.json: " + buildDirectory);
62
- await testEntry(buildDirectory, context);
63
- }
64
- else { // if its a relative path
65
- const newPath = context.baseDirectory + "/" + buildDirectory;
66
- if (existsSync(newPath)) {
67
- console.log("INFO: Using build directory from needle.config.json: " + newPath);
68
- await testEntry(newPath, context);
69
- }
70
- }
71
- }
72
- }
73
- else {
74
- // if no file was found, we don't have a needle.config in the directory
75
- // and we don't have any arguments, try to find it in the default dist directory
76
- // await testEntry(context.baseDirectory + "/dist", callback, context);
77
- }
78
- }
79
- if (context.files.length <= 0) {
80
- console.log(`WARN: No glTF files found. Make sure to invoke with a valid path to a glTF file or directory.\nBase Directory: ${context.baseDirectory}\nPaths can be relative to \"${initDir}\"`);
81
- }
82
- else {
83
- for (const file of context.files) {
84
- await callback(file);
85
- }
86
- }
87
- }
88
- async function testEntry(entry, context) {
89
- // ignore argument names (e.g. --debug)
90
- if (entry.startsWith("--")) {
91
- return false;
92
- }
93
- if (entry === "." || entry === "./") {
94
- if (context.baseDirectory) {
95
- entry = context.baseDirectory;
96
- }
97
- }
98
- if (existsSync(entry) === false) {
99
- // If no base directory is defined we cannot try to resolve the path
100
- if (context.baseDirectory === undefined) {
101
- console.log("WARN: Path does not exist: " + entry);
102
- return false;
103
- }
104
- // Try resolve potential relative path
105
- const newPath = context.baseDirectory + "/" + entry;
106
- if (existsSync(newPath) === false) {
107
- console.log(`INFO: Resolved path failed: \"${entry}\" -> ${newPath} (doesnt exist or is locked by another process)`);
108
- return false;
109
- }
110
- else {
111
- console.log(`INFO: Resolved path: ${entry} -> ${newPath}`);
112
- entry = newPath;
113
- }
114
- }
115
- else {
116
- // When passing in a relative path (e.g. `dist`) we dont want to accidentally traverse this package's directory
117
- // So in that case make sure we resolve to an absolute path relative to the calling directory
118
- const isAbs = isAbsolute(entry);
119
- if (!isAbs) {
120
- if (context.baseDirectory) {
121
- const newPath = context.baseDirectory + "/" + entry;
122
- console.log(`INFO: Resolved path: ${entry} -> ${newPath}`);
123
- entry = newPath;
124
- if (!existsSync(entry)) {
125
- return false;
126
- }
127
- }
128
- }
129
- }
130
- if (entry.endsWith(".glb") || entry.endsWith(".gltf") || entry.endsWith(".vrm")) {
131
- context.files.push(entry);
132
- }
133
- else {
134
- const stat = statSync(entry);
135
- if (stat.isDirectory()) {
136
- // Don't traverse node_modules
137
- if (entry.endsWith("node_modules")) {
138
- return false;
139
- }
140
- const files = readdirSync(entry);
141
- for (const file of files) {
142
- await testEntry(entry + "/" + file, context);
143
- }
144
- }
145
- else {
146
- // console.log("WARN: Ignoring file: " + entry);
147
- }
148
- }
149
- }
150
- export function replaceExtension(filepath, newExtension) {
151
- const parts = filepath.split(".");
152
- parts.pop();
153
- return parts.join(".") + "." + newExtension;
154
- }
155
- export function isDirectory(path) {
156
- if (!path) {
157
- return false;
158
- }
159
- if (existsSync(path)) {
160
- return statSync(path).isDirectory();
161
- }
162
- const hasExt = path.replaceAll("\\", "/").split("/").pop()?.includes(".");
163
- return !hasExt;
164
- }
165
- /**
166
- * Ensure that a path is a directory.
167
- * If the directory does not exist, it will be created.
168
- */
169
- export function ensureIsDirectory(path) {
170
- if (!isDirectory(path)) {
171
- path = dirname(path);
172
- }
173
- if (!existsSync(path)) {
174
- mkdirSync(path, { recursive: true });
175
- }
176
- return path;
177
- }
1
+ import { existsSync, statSync, readdirSync, readFileSync, mkdirSync } from 'fs';
2
+ import { dirname, isAbsolute, join } from 'path';
3
+ /**
4
+ * Get the output path for a file based on the output directory or file.
5
+ * If outDirOrFile is a filepath, it will be returned as is.
6
+ * If outDirOrFile is a directory, the file will be placed in that directory.
7
+ */
8
+ export function getOutputPath(filepath, outDirOrFile, opts) {
9
+ if (!outDirOrFile) {
10
+ return filepath;
11
+ }
12
+ if (!isDirectory(outDirOrFile)) {
13
+ return outDirOrFile;
14
+ }
15
+ const filename = getFileName(filepath);
16
+ // create the directory if it doesn't exist (default behavior)
17
+ if (opts?.create != false && !existsSync(outDirOrFile)) {
18
+ mkdirSync(outDirOrFile, { recursive: true });
19
+ }
20
+ const outpath = join(outDirOrFile, filename);
21
+ return outpath;
22
+ }
23
+ export function getFileName(filepath) {
24
+ const parts = filepath.replaceAll("\\", "/").split("/");
25
+ return parts[parts.length - 1];
26
+ }
27
+ export function getDirName(filepath) {
28
+ // should work for paths that end with "/" or not
29
+ const parts = filepath.replaceAll("\\", "/").split("/");
30
+ let res = parts.pop();
31
+ if (res === "") {
32
+ res = parts.pop();
33
+ }
34
+ return res;
35
+ }
36
+ export async function foreachGLTF(args, callback) {
37
+ // get original directory this run was invoked from
38
+ const initDir = process.env.INIT_CWD;
39
+ const context = {
40
+ baseDirectory: initDir,
41
+ files: [],
42
+ };
43
+ // traverse recursively through all files and directories
44
+ if (Array.isArray(args)) {
45
+ for (const arg of args) {
46
+ await testEntry(arg, context);
47
+ }
48
+ }
49
+ else if (typeof args === "string") {
50
+ await testEntry(args, context);
51
+ }
52
+ // try to run with needle config
53
+ if (context.files?.length <= 0 && context.baseDirectory) {
54
+ const needleConfigPath = context.baseDirectory + "/needle.config.json";
55
+ if (existsSync(needleConfigPath)) {
56
+ const config = JSON.parse(readFileSync(needleConfigPath, "utf8"));
57
+ const buildDirectory = config.buildDirectory;
58
+ if (buildDirectory?.length) {
59
+ // If it's an absolute path
60
+ if (existsSync(buildDirectory)) {
61
+ console.log("INFO: Using build directory from needle.config.json: " + buildDirectory);
62
+ await testEntry(buildDirectory, context);
63
+ }
64
+ else { // if its a relative path
65
+ const newPath = context.baseDirectory + "/" + buildDirectory;
66
+ if (existsSync(newPath)) {
67
+ console.log("INFO: Using build directory from needle.config.json: " + newPath);
68
+ await testEntry(newPath, context);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ else {
74
+ // if no file was found, we don't have a needle.config in the directory
75
+ // and we don't have any arguments, try to find it in the default dist directory
76
+ // await testEntry(context.baseDirectory + "/dist", callback, context);
77
+ }
78
+ }
79
+ if (context.files.length <= 0) {
80
+ console.log(`WARN: No glTF files found. Make sure to invoke with a valid path to a glTF file or directory.\nBase Directory: ${context.baseDirectory}\nPaths can be relative to \"${initDir}\"`);
81
+ }
82
+ else {
83
+ for (const file of context.files) {
84
+ await callback(file);
85
+ }
86
+ }
87
+ }
88
+ async function testEntry(entry, context) {
89
+ // ignore argument names (e.g. --debug)
90
+ if (entry.startsWith("--")) {
91
+ return false;
92
+ }
93
+ if (entry === "." || entry === "./") {
94
+ if (context.baseDirectory) {
95
+ entry = context.baseDirectory;
96
+ }
97
+ }
98
+ if (existsSync(entry) === false) {
99
+ // If no base directory is defined we cannot try to resolve the path
100
+ if (context.baseDirectory === undefined) {
101
+ console.log("WARN: Path does not exist: " + entry);
102
+ return false;
103
+ }
104
+ // Try resolve potential relative path
105
+ const newPath = context.baseDirectory + "/" + entry;
106
+ if (existsSync(newPath) === false) {
107
+ console.log(`INFO: Resolved path failed: \"${entry}\" -> ${newPath} (doesnt exist or is locked by another process)`);
108
+ return false;
109
+ }
110
+ else {
111
+ console.log(`INFO: Resolved path: ${entry} -> ${newPath}`);
112
+ entry = newPath;
113
+ }
114
+ }
115
+ else {
116
+ // When passing in a relative path (e.g. `dist`) we dont want to accidentally traverse this package's directory
117
+ // So in that case make sure we resolve to an absolute path relative to the calling directory
118
+ const isAbs = isAbsolute(entry);
119
+ if (!isAbs) {
120
+ if (context.baseDirectory) {
121
+ const newPath = context.baseDirectory + "/" + entry;
122
+ console.log(`INFO: Resolved path: ${entry} -> ${newPath}`);
123
+ entry = newPath;
124
+ if (!existsSync(entry)) {
125
+ return false;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ if (entry.endsWith(".glb") || entry.endsWith(".gltf") || entry.endsWith(".vrm")) {
131
+ context.files.push(entry);
132
+ }
133
+ else {
134
+ const stat = statSync(entry);
135
+ if (stat.isDirectory()) {
136
+ // Don't traverse node_modules
137
+ if (entry.endsWith("node_modules")) {
138
+ return false;
139
+ }
140
+ const files = readdirSync(entry);
141
+ for (const file of files) {
142
+ await testEntry(entry + "/" + file, context);
143
+ }
144
+ }
145
+ else {
146
+ // console.log("WARN: Ignoring file: " + entry);
147
+ }
148
+ }
149
+ }
150
+ export function replaceExtension(filepath, newExtension) {
151
+ const parts = filepath.split(".");
152
+ parts.pop();
153
+ return parts.join(".") + "." + newExtension;
154
+ }
155
+ export function isDirectory(path) {
156
+ if (!path) {
157
+ return false;
158
+ }
159
+ if (existsSync(path)) {
160
+ return statSync(path).isDirectory();
161
+ }
162
+ const hasExt = path.replaceAll("\\", "/").split("/").pop()?.includes(".");
163
+ return !hasExt;
164
+ }
165
+ /**
166
+ * Ensure that a path is a directory.
167
+ * If the directory does not exist, it will be created.
168
+ */
169
+ export function ensureIsDirectory(path) {
170
+ if (!isDirectory(path)) {
171
+ path = dirname(path);
172
+ }
173
+ if (!existsSync(path)) {
174
+ mkdirSync(path, { recursive: true });
175
+ }
176
+ return path;
177
+ }
@@ -1 +1 @@
1
- export declare function generateGuid(key: string): any;
1
+ export declare function generateGuid(key: string): any;
@@ -1,5 +1,5 @@
1
- import { v5 as uuidv5 } from 'uuid';
2
- const NEEDLE_BUILD_PIPELINE_NAMESPACE = '208dcaa6-1398-4d42-a625-8f5fc1cc1ccf';
3
- export function generateGuid(key) {
4
- return uuidv5(key, NEEDLE_BUILD_PIPELINE_NAMESPACE);
5
- }
1
+ import { v5 as uuidv5 } from 'uuid';
2
+ const NEEDLE_BUILD_PIPELINE_NAMESPACE = '208dcaa6-1398-4d42-a625-8f5fc1cc1ccf';
3
+ export function generateGuid(key) {
4
+ return uuidv5(key, NEEDLE_BUILD_PIPELINE_NAMESPACE);
5
+ }
@@ -1,10 +1,10 @@
1
- export * from "./compression_utils.js";
2
- export * from "./fileutils.js";
3
- export * from "./version.js";
4
- export * from "./mesh.js";
5
- export * from "./texture.js";
6
- export * from "./guid.js";
7
- export * from "./nodeio.js";
8
- export * from "./stats.js";
9
- export * from "./merge.js";
10
- export * from "./validate.js";
1
+ export * from "./compression_utils.js";
2
+ export * from "./fileutils.js";
3
+ export * from "./version.js";
4
+ export * from "./mesh.js";
5
+ export * from "./texture.js";
6
+ export * from "./guid.js";
7
+ export * from "./nodeio.js";
8
+ export * from "./stats.js";
9
+ export * from "./merge.js";
10
+ export * from "./validate.js";
@@ -1,10 +1,10 @@
1
- export * from "./compression_utils.js";
2
- export * from "./fileutils.js";
3
- export * from "./version.js";
4
- export * from "./mesh.js";
5
- export * from "./texture.js";
6
- export * from "./guid.js";
7
- export * from "./nodeio.js";
8
- export * from "./stats.js";
9
- export * from "./merge.js";
10
- export * from "./validate.js";
1
+ export * from "./compression_utils.js";
2
+ export * from "./fileutils.js";
3
+ export * from "./version.js";
4
+ export * from "./mesh.js";
5
+ export * from "./texture.js";
6
+ export * from "./guid.js";
7
+ export * from "./nodeio.js";
8
+ export * from "./stats.js";
9
+ export * from "./merge.js";
10
+ export * from "./validate.js";
@@ -1,12 +1,12 @@
1
- /**
2
- * Simple object check.
3
- * @param item
4
- * @returns {boolean}
5
- */
6
- export declare function isObject(item: object): boolean;
7
- /**
8
- * Deep merge two objects.
9
- * @param target
10
- * @param ...sources
11
- */
12
- export declare function mergeDeep(target: any, ...sources: any[]): any;
1
+ /**
2
+ * Simple object check.
3
+ * @param item
4
+ * @returns {boolean}
5
+ */
6
+ export declare function isObject(item: object): boolean;
7
+ /**
8
+ * Deep merge two objects.
9
+ * @param target
10
+ * @param ...sources
11
+ */
12
+ export declare function mergeDeep(target: any, ...sources: any[]): any;
@@ -1,31 +1,31 @@
1
- /**
2
- * Simple object check.
3
- * @param item
4
- * @returns {boolean}
5
- */
6
- export function isObject(item) {
7
- return (item && typeof item === 'object' && !Array.isArray(item));
8
- }
9
- /**
10
- * Deep merge two objects.
11
- * @param target
12
- * @param ...sources
13
- */
14
- export function mergeDeep(target, ...sources) {
15
- if (!sources.length)
16
- return target;
17
- const source = sources.shift();
18
- if (isObject(target) && isObject(source)) {
19
- for (const key in source) {
20
- if (isObject(source[key])) {
21
- if (!target[key])
22
- Object.assign(target, { [key]: {} });
23
- mergeDeep(target[key], source[key]);
24
- }
25
- else {
26
- Object.assign(target, { [key]: source[key] });
27
- }
28
- }
29
- }
30
- return mergeDeep(target, ...sources);
31
- }
1
+ /**
2
+ * Simple object check.
3
+ * @param item
4
+ * @returns {boolean}
5
+ */
6
+ export function isObject(item) {
7
+ return (item && typeof item === 'object' && !Array.isArray(item));
8
+ }
9
+ /**
10
+ * Deep merge two objects.
11
+ * @param target
12
+ * @param ...sources
13
+ */
14
+ export function mergeDeep(target, ...sources) {
15
+ if (!sources.length)
16
+ return target;
17
+ const source = sources.shift();
18
+ if (isObject(target) && isObject(source)) {
19
+ for (const key in source) {
20
+ if (isObject(source[key])) {
21
+ if (!target[key])
22
+ Object.assign(target, { [key]: {} });
23
+ mergeDeep(target[key], source[key]);
24
+ }
25
+ else {
26
+ Object.assign(target, { [key]: source[key] });
27
+ }
28
+ }
29
+ }
30
+ return mergeDeep(target, ...sources);
31
+ }
@@ -1,13 +1,13 @@
1
- import { Document, Mesh, Primitive } from "@gltf-transform/core";
2
- export declare type MeshInformation = {
3
- readonly maxVertexCount: number;
4
- readonly totalVertexCount: number;
5
- readonly totalIndexCount: number;
6
- };
7
- export declare function getMeshInformation(mesh: Mesh | Document): MeshInformation;
8
- /**
9
- * Calculate the density of a mesh.
10
- * @param prim - The primitive to calculate the density for.
11
- * @returns The density of the mesh or -1 if the mesh is not indexed.
12
- */
13
- export declare function calculateMeshDensity(prim: Primitive): number | -1;
1
+ import { Document, Mesh, Primitive } from "@gltf-transform/core";
2
+ export declare type MeshInformation = {
3
+ readonly maxVertexCount: number;
4
+ readonly totalVertexCount: number;
5
+ readonly totalIndexCount: number;
6
+ };
7
+ export declare function getMeshInformation(mesh: Mesh | Document): MeshInformation;
8
+ /**
9
+ * Calculate the density of a mesh.
10
+ * @param prim - The primitive to calculate the density for.
11
+ * @returns The density of the mesh or -1 if the mesh is not indexed.
12
+ */
13
+ export declare function calculateMeshDensity(prim: Primitive): number | -1;