babylonjs-editor-cli 5.0.0 → 5.0.2
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/.env +5 -0
- package/build/index.node.js +85 -18
- package/build/package.json +4 -2
- package/build/src/export.mjs +2 -0
- package/build/src/export.mjs.map +1 -1
- package/build/src/index.mjs +10 -0
- package/build/src/index.mjs.map +1 -1
- package/build/src/pack/assets/assets.mjs.map +1 -1
- package/build/src/pack/assets/process.mjs +3 -0
- package/build/src/pack/assets/process.mjs.map +1 -1
- package/build/src/pack/assets/texture.mjs +3 -0
- package/build/src/pack/assets/texture.mjs.map +1 -1
- package/build/src/pack/geometry.mjs +1 -1
- package/build/src/pack/geometry.mjs.map +1 -1
- package/build/src/pack/pack.mjs +21 -9
- package/build/src/pack/pack.mjs.map +1 -1
- package/build/src/s3/s3.mjs +132 -0
- package/build/src/s3/s3.mjs.map +1 -0
- package/build/src/tools/fs.mjs +9 -0
- package/build/src/tools/fs.mjs.map +1 -1
- package/build/src/tools/ktx.mjs +3 -1
- package/build/src/tools/ktx.mjs.map +1 -1
- package/build/src/tools/worker.mjs +7 -3
- package/build/src/tools/worker.mjs.map +1 -1
- package/declaration/src/export.d.mts +3 -1
- package/declaration/src/pack/assets/assets.d.mts +2 -0
- package/declaration/src/pack/assets/texture.d.mts +2 -1
- package/declaration/src/pack/pack.d.mts +6 -0
- package/declaration/src/s3/s3.d.mts +11 -0
- package/declaration/src/tools/fs.d.mts +1 -0
- package/declaration/src/tools/worker.d.mts +3 -2
- package/package.json +4 -2
- package/esbuild.mjs +0 -57
- package/src/export.mts +0 -1
- package/src/index.mts +0 -28
- package/src/pack/assets/assets.mts +0 -46
- package/src/pack/assets/ktx.mts +0 -158
- package/src/pack/assets/material.mts +0 -86
- package/src/pack/assets/particle-system.mts +0 -109
- package/src/pack/assets/process.mts +0 -102
- package/src/pack/assets/texture.mts +0 -91
- package/src/pack/geometry.mts +0 -38
- package/src/pack/pack.mts +0 -159
- package/src/pack/scene.mts +0 -346
- package/src/tools/extract.mts +0 -74
- package/src/tools/fs.mts +0 -11
- package/src/tools/ktx.mts +0 -44
- package/src/tools/process.mts +0 -21
- package/src/tools/scalar.mts +0 -28
- package/src/tools/scene.mts +0 -90
- package/src/tools/worker.mts +0 -39
- package/src/tools/workers/md5.mts +0 -13
- package/tsconfig.json +0 -21
package/src/pack/geometry.mts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path/posix";
|
|
2
|
-
|
|
3
|
-
import fs from "fs-extra";
|
|
4
|
-
|
|
5
|
-
import { readSceneDirectories } from "../tools/scene.mjs";
|
|
6
|
-
|
|
7
|
-
export interface ICreateGeometryFilesOptions {
|
|
8
|
-
sceneFile: string;
|
|
9
|
-
sceneName: string;
|
|
10
|
-
publicDir: string;
|
|
11
|
-
exportedAssets: string[];
|
|
12
|
-
babylonjsEditorToolsVersion: string;
|
|
13
|
-
|
|
14
|
-
directories: Awaited<ReturnType<typeof readSceneDirectories>>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function createGeometryFiles(options: ICreateGeometryFilesOptions) {
|
|
18
|
-
await fs.ensureDir(join(options.publicDir, options.sceneName));
|
|
19
|
-
await fs.ensureDir(join(options.publicDir, options.sceneName, "morphTargets"));
|
|
20
|
-
|
|
21
|
-
await Promise.all(
|
|
22
|
-
options.directories.geometryFiles.map(async (file) => {
|
|
23
|
-
const destination = join(options.publicDir, options.sceneName, file);
|
|
24
|
-
await fs.copyFile(join(options.sceneFile, "geometries", file), destination);
|
|
25
|
-
options.exportedAssets.push(destination);
|
|
26
|
-
})
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
if (options.babylonjsEditorToolsVersion >= "5.2.6") {
|
|
30
|
-
await Promise.all(
|
|
31
|
-
options.directories.morphTargetFiles.map(async (file) => {
|
|
32
|
-
const destination = join(options.publicDir, options.sceneName, "morphTargets", file);
|
|
33
|
-
await fs.copyFile(join(options.sceneFile, "morphTargets", file), destination);
|
|
34
|
-
options.exportedAssets.push(destination);
|
|
35
|
-
})
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
}
|
package/src/pack/pack.mts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import fs from "fs-extra";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
import { basename, extname, join } from "node:path/posix";
|
|
4
|
-
|
|
5
|
-
import ora from "ora";
|
|
6
|
-
import cliSpinners from "cli-spinners";
|
|
7
|
-
|
|
8
|
-
import { normalizedGlob } from "../tools/fs.mjs";
|
|
9
|
-
import { locatePVRTexTool, setPVRTexToolAbsolutePath } from "../tools/ktx.mjs";
|
|
10
|
-
import { ensureSceneDirectories, readSceneDirectories } from "../tools/scene.mjs";
|
|
11
|
-
|
|
12
|
-
import { createAssets } from "./assets/assets.mjs";
|
|
13
|
-
import { createBabylonScene } from "./scene.mjs";
|
|
14
|
-
import { createGeometryFiles } from "./geometry.mjs";
|
|
15
|
-
|
|
16
|
-
export interface IPackOptions {
|
|
17
|
-
optimize: boolean;
|
|
18
|
-
pvrTexToolAbsolutePath?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function pack(projectDir: string, options: IPackOptions) {
|
|
22
|
-
const cwd = process.cwd();
|
|
23
|
-
|
|
24
|
-
if (projectDir !== cwd) {
|
|
25
|
-
projectDir = resolve(cwd, projectDir);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
projectDir = projectDir.replace(/\\/g, "/");
|
|
29
|
-
|
|
30
|
-
// Load project configuration
|
|
31
|
-
const projectFiles = await fs.readdir(projectDir);
|
|
32
|
-
const projectConfigurationFile = projectFiles.find((file) => extname(file).toLowerCase() === ".bjseditor");
|
|
33
|
-
|
|
34
|
-
let projectConfiguration = {
|
|
35
|
-
compressedTexturesEnabled: false,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
if (projectConfigurationFile) {
|
|
39
|
-
projectConfiguration = await fs.readJSON(join(projectDir, projectConfigurationFile));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Locate PVRTexToolCLI
|
|
43
|
-
if (projectConfiguration.compressedTexturesEnabled) {
|
|
44
|
-
if (options.pvrTexToolAbsolutePath) {
|
|
45
|
-
setPVRTexToolAbsolutePath(options.pvrTexToolAbsolutePath);
|
|
46
|
-
} else {
|
|
47
|
-
await locatePVRTexTool();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const assetsDirectory = join(projectDir, "assets");
|
|
52
|
-
const publicDir = join(projectDir, "public/scene");
|
|
53
|
-
|
|
54
|
-
await fs.ensureDir(publicDir);
|
|
55
|
-
|
|
56
|
-
const baseAssetsDir = join(projectDir, "assets");
|
|
57
|
-
const outputAssetsDir = join(publicDir, "assets");
|
|
58
|
-
|
|
59
|
-
await fs.ensureDir(outputAssetsDir);
|
|
60
|
-
|
|
61
|
-
const exportedAssets: string[] = [];
|
|
62
|
-
|
|
63
|
-
let cache: Record<string, string> = {};
|
|
64
|
-
try {
|
|
65
|
-
cache = await fs.readJSON(join(projectDir, "assets/.export-cache.json"));
|
|
66
|
-
} catch (e) {
|
|
67
|
-
// Catch silently.
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Pack assets
|
|
71
|
-
const assetsLog = ora(`Packing assets...`);
|
|
72
|
-
assetsLog.spinner = cliSpinners.dots14;
|
|
73
|
-
assetsLog.start();
|
|
74
|
-
|
|
75
|
-
await createAssets({
|
|
76
|
-
...options,
|
|
77
|
-
...projectConfiguration,
|
|
78
|
-
cache,
|
|
79
|
-
projectDir,
|
|
80
|
-
publicDir,
|
|
81
|
-
baseAssetsDir,
|
|
82
|
-
outputAssetsDir,
|
|
83
|
-
exportedAssets,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
assetsLog.succeed(`Packed assets`);
|
|
87
|
-
|
|
88
|
-
// Get babylonjs-editor-tools version
|
|
89
|
-
let babylonjsEditorToolsVersion = "5.0.0";
|
|
90
|
-
try {
|
|
91
|
-
const pkg = await fs.readJSON(join(projectDir, "node_modules/babylonjs-editor-tools/package.json"));
|
|
92
|
-
babylonjsEditorToolsVersion = pkg.version;
|
|
93
|
-
} catch (e) {
|
|
94
|
-
// Catch silently.
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Pack scenes
|
|
98
|
-
const sceneFiles = await normalizedGlob(`${assetsDirectory}/**/*`, {
|
|
99
|
-
nodir: false,
|
|
100
|
-
ignore: {
|
|
101
|
-
ignored: (p) => !p.isDirectory() || extname(p.name).toLocaleLowerCase() !== ".scene",
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
for (const sceneFile of sceneFiles) {
|
|
106
|
-
const sceneFilename = basename(sceneFile);
|
|
107
|
-
const sceneName = basename(sceneFile, extname(sceneFile));
|
|
108
|
-
|
|
109
|
-
const sceneLog = ora(`Packing ${sceneFilename}...`);
|
|
110
|
-
sceneLog.spinner = cliSpinners.dots14;
|
|
111
|
-
sceneLog.start();
|
|
112
|
-
|
|
113
|
-
await ensureSceneDirectories(sceneFile);
|
|
114
|
-
|
|
115
|
-
const directories = await readSceneDirectories(sceneFile);
|
|
116
|
-
const config = await fs.readJSON(join(sceneFile, "config.json"));
|
|
117
|
-
|
|
118
|
-
await createBabylonScene({
|
|
119
|
-
...options,
|
|
120
|
-
...projectConfiguration,
|
|
121
|
-
config,
|
|
122
|
-
directories,
|
|
123
|
-
publicDir,
|
|
124
|
-
sceneFile,
|
|
125
|
-
sceneName,
|
|
126
|
-
exportedAssets,
|
|
127
|
-
babylonjsEditorToolsVersion,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Copy geometry files
|
|
131
|
-
await createGeometryFiles({
|
|
132
|
-
directories,
|
|
133
|
-
publicDir,
|
|
134
|
-
sceneFile,
|
|
135
|
-
sceneName,
|
|
136
|
-
exportedAssets,
|
|
137
|
-
babylonjsEditorToolsVersion,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
sceneLog.succeed(`Packed ${sceneFilename}`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Save cache
|
|
144
|
-
await fs.writeJSON(join(projectDir, "assets/.export-cache.json"), cache, {
|
|
145
|
-
encoding: "utf-8",
|
|
146
|
-
spaces: "\t",
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
// Clean
|
|
150
|
-
const publicFiles = await normalizedGlob(join(publicDir, "**/*"), {
|
|
151
|
-
nodir: true,
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
publicFiles.forEach((file) => {
|
|
155
|
-
if (!exportedAssets.includes(file.toString())) {
|
|
156
|
-
fs.remove(file);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
package/src/pack/scene.mts
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import { join, basename } from "node:path/posix";
|
|
2
|
-
|
|
3
|
-
import fs from "fs-extra";
|
|
4
|
-
|
|
5
|
-
import { readSceneDirectories } from "../tools/scene.mjs";
|
|
6
|
-
|
|
7
|
-
import { compressFileToKtx } from "./assets/ktx.mjs";
|
|
8
|
-
import { extractNodeMaterialTextures } from "./assets/material.mjs";
|
|
9
|
-
import { getExtractedTextureOutputPath } from "./assets/texture.mjs";
|
|
10
|
-
import { extractNodeParticleSystemSetTextures, extractParticleSystemTextures } from "./assets/particle-system.mjs";
|
|
11
|
-
|
|
12
|
-
export interface ICreateBabylonSceneOptions {
|
|
13
|
-
sceneFile: string;
|
|
14
|
-
sceneName: string;
|
|
15
|
-
publicDir: string;
|
|
16
|
-
babylonjsEditorToolsVersion: string;
|
|
17
|
-
exportedAssets: string[];
|
|
18
|
-
optimize: boolean;
|
|
19
|
-
compressedTexturesEnabled: boolean;
|
|
20
|
-
|
|
21
|
-
config: any;
|
|
22
|
-
directories: Awaited<ReturnType<typeof readSceneDirectories>>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function createBabylonScene(options: ICreateBabylonSceneOptions) {
|
|
26
|
-
const meshes: any[] = [];
|
|
27
|
-
const materials: any[] = [];
|
|
28
|
-
const transformNodes: any[] = [];
|
|
29
|
-
const morphTargetManagers: any[] = [];
|
|
30
|
-
|
|
31
|
-
// Meshes
|
|
32
|
-
await Promise.all(
|
|
33
|
-
options.directories.meshesFiles.map(async (file) => {
|
|
34
|
-
const data = await fs.readJSON(join(options.sceneFile, "meshes", file));
|
|
35
|
-
const mesh = data.meshes[0];
|
|
36
|
-
|
|
37
|
-
if (mesh.delayLoadingFile) {
|
|
38
|
-
mesh.delayLoadingFile = join(options.sceneName, basename(mesh.delayLoadingFile));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (mesh.metadata?.parentId) {
|
|
42
|
-
mesh.parentId = mesh.metadata.parentId;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
mesh.instances?.forEach((instance) => {
|
|
46
|
-
if (instance.metadata?.parentId) {
|
|
47
|
-
instance.parentId = instance.metadata.parentId;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
if (data.basePoseMatrix) {
|
|
52
|
-
mesh.basePoseMatrix = data.basePoseMatrix;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
meshes.push(mesh);
|
|
56
|
-
|
|
57
|
-
data.materials?.forEach((material) => {
|
|
58
|
-
const existingMaterial = materials.find((m) => m.id === material.id);
|
|
59
|
-
if (!existingMaterial) {
|
|
60
|
-
materials.push(material);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
})
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
// Morph targets
|
|
67
|
-
await Promise.all(
|
|
68
|
-
options.directories.morphTargetManagerFiles.map(async (file) => {
|
|
69
|
-
const data = await fs.readJSON(join(options.sceneFile, "morphTargetManagers", file));
|
|
70
|
-
|
|
71
|
-
if (options.babylonjsEditorToolsVersion >= "5.2.6") {
|
|
72
|
-
data.targets.forEach((target) => {
|
|
73
|
-
if (target.delayLoadingFile) {
|
|
74
|
-
target.delayLoadingFile = join(options.sceneName, "morphTargets", basename(target.delayLoadingFile));
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
} else {
|
|
78
|
-
await Promise.all(
|
|
79
|
-
data.targets.map(async (target) => {
|
|
80
|
-
const binaryFileData = join(options.sceneFile, "morphTargets", basename(target.delayLoadingFile));
|
|
81
|
-
const buffer = (await fs.readFile(binaryFileData)).buffer;
|
|
82
|
-
|
|
83
|
-
if (target.positionsCount) {
|
|
84
|
-
target.positions = Array.prototype.slice.call(new Float32Array(buffer, target.positionsOffset, target.positionsCount));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (target.normalsCount) {
|
|
88
|
-
target.normals = Array.prototype.slice.call(new Float32Array(buffer, target.normalsOffset, target.normalsCount));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (target.tangentsCount) {
|
|
92
|
-
target.tangents = Array.prototype.slice.call(new Float32Array(buffer, target.tangentsOffset, target.tangentsCount));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (target.uvsCount) {
|
|
96
|
-
target.uvs = Array.prototype.slice.call(new Float32Array(buffer, target.uvsOffset, target.uvsCount));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (target.uv2sCount) {
|
|
100
|
-
target.uv2s = Array.prototype.slice.call(new Float32Array(buffer, target.uv2sOffset, target.uv2sCount));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
delete target.delayLoadingFile;
|
|
104
|
-
|
|
105
|
-
delete target.positionsCount;
|
|
106
|
-
delete target.normalsCount;
|
|
107
|
-
delete target.tangentsCount;
|
|
108
|
-
delete target.uvsCount;
|
|
109
|
-
delete target.uv2sCount;
|
|
110
|
-
|
|
111
|
-
delete target.positionsOffset;
|
|
112
|
-
delete target.normalsOffset;
|
|
113
|
-
delete target.tangentsOffset;
|
|
114
|
-
delete target.uvsOffset;
|
|
115
|
-
delete target.uv2sOffset;
|
|
116
|
-
})
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
morphTargetManagers.push(data);
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
// Transform nodes
|
|
125
|
-
await Promise.all(
|
|
126
|
-
options.directories.nodesFiles.map(async (file) => {
|
|
127
|
-
const data = await fs.readJSON(join(options.sceneFile, "nodes", file));
|
|
128
|
-
if (data.metadata?.parentId) {
|
|
129
|
-
data.parentId = data.metadata.parentId;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
transformNodes.push(data);
|
|
133
|
-
})
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
await Promise.all(
|
|
137
|
-
options.directories.spriteManagerFiles.map(async (file) => {
|
|
138
|
-
const data = await fs.readJSON(join(options.sceneFile, "sprite-managers", file));
|
|
139
|
-
if (data.metadata?.parentId) {
|
|
140
|
-
data.parentId = data.metadata.parentId;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
transformNodes.push(data);
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
await Promise.all(
|
|
148
|
-
options.directories.spriteMapFiles.map(async (file) => {
|
|
149
|
-
const data = await fs.readJSON(join(options.sceneFile, "sprite-maps", file));
|
|
150
|
-
if (data.metadata?.parentId) {
|
|
151
|
-
data.parentId = data.metadata.parentId;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
transformNodes.push(data);
|
|
155
|
-
})
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
// Extract materials
|
|
159
|
-
const extractedTexturesOutputPath = getExtractedTextureOutputPath(options.publicDir);
|
|
160
|
-
await fs.ensureDir(extractedTexturesOutputPath);
|
|
161
|
-
|
|
162
|
-
await Promise.all(
|
|
163
|
-
materials.map(async (material) => {
|
|
164
|
-
if (material.customType === "BABYLON.NodeMaterial") {
|
|
165
|
-
const result = await extractNodeMaterialTextures(material, {
|
|
166
|
-
extractedTexturesOutputPath,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
await Promise.all(
|
|
170
|
-
result.map(async (relativePath) => {
|
|
171
|
-
const finalPath = join(options.publicDir, relativePath);
|
|
172
|
-
options.exportedAssets.push(finalPath);
|
|
173
|
-
|
|
174
|
-
if (options.optimize && options.compressedTexturesEnabled) {
|
|
175
|
-
await compressFileToKtx(finalPath, {
|
|
176
|
-
...options,
|
|
177
|
-
force: false,
|
|
178
|
-
exportedAssets: options.exportedAssets,
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
})
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
// Particle systems
|
|
188
|
-
const particleSystems = await Promise.all(
|
|
189
|
-
options.directories.particleSystemFiles.map(async (file) => {
|
|
190
|
-
const data = await fs.readJSON(join(options.sceneFile, "particleSystems", file));
|
|
191
|
-
|
|
192
|
-
const result = await extractParticleSystemTextures(data, {
|
|
193
|
-
extractedTexturesOutputPath,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
if (result) {
|
|
197
|
-
const finalPath = join(options.publicDir, result);
|
|
198
|
-
options.exportedAssets.push(finalPath);
|
|
199
|
-
|
|
200
|
-
if (options.optimize && options.compressedTexturesEnabled) {
|
|
201
|
-
await compressFileToKtx(finalPath, {
|
|
202
|
-
...options,
|
|
203
|
-
force: false,
|
|
204
|
-
exportedAssets: options.exportedAssets,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return data;
|
|
210
|
-
})
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
// Node particle system sets
|
|
214
|
-
await Promise.all(
|
|
215
|
-
options.directories.nodeParticleSystemSetFiles.map(async (file) => {
|
|
216
|
-
const data = await fs.readJSON(join(options.sceneFile, "nodeParticleSystemSets", file));
|
|
217
|
-
|
|
218
|
-
if (data.metadata?.parentId) {
|
|
219
|
-
data.parentId = data.metadata.parentId;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (data.nodeParticleSystemSet) {
|
|
223
|
-
const result = await extractNodeParticleSystemSetTextures(data.nodeParticleSystemSet, {
|
|
224
|
-
extractedTexturesOutputPath,
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
await Promise.all(
|
|
228
|
-
result.map(async (relativePath) => {
|
|
229
|
-
const finalPath = join(options.publicDir, relativePath);
|
|
230
|
-
options.exportedAssets.push(finalPath);
|
|
231
|
-
|
|
232
|
-
if (options.optimize && options.compressedTexturesEnabled) {
|
|
233
|
-
await compressFileToKtx(finalPath, {
|
|
234
|
-
...options,
|
|
235
|
-
force: false,
|
|
236
|
-
exportedAssets: options.exportedAssets,
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
meshes.push(data);
|
|
244
|
-
})
|
|
245
|
-
);
|
|
246
|
-
|
|
247
|
-
const scene = {
|
|
248
|
-
autoClear: true,
|
|
249
|
-
physicsEnabled: true,
|
|
250
|
-
collisionsEnabled: true,
|
|
251
|
-
useRightHandedSystem: false,
|
|
252
|
-
physicsEngine: "HavokPlugin",
|
|
253
|
-
iblIntensity: 1,
|
|
254
|
-
|
|
255
|
-
clearColor: options.config.clearColor,
|
|
256
|
-
ambientColor: options.config.ambientColor,
|
|
257
|
-
|
|
258
|
-
geometries: {
|
|
259
|
-
boxes: [],
|
|
260
|
-
spheres: [],
|
|
261
|
-
cylinders: [],
|
|
262
|
-
toruses: [],
|
|
263
|
-
grounds: [],
|
|
264
|
-
planes: [],
|
|
265
|
-
torusKnots: [],
|
|
266
|
-
vertexData: [],
|
|
267
|
-
},
|
|
268
|
-
|
|
269
|
-
gravity: options.config.gravity ?? [0, -9.81, 0],
|
|
270
|
-
|
|
271
|
-
fogColor: options.config.fog.fogColor,
|
|
272
|
-
fogStart: options.config.fog.fogStart,
|
|
273
|
-
fogEnd: options.config.fog.fogEnd,
|
|
274
|
-
fogDensity: options.config.fog.fogDensity,
|
|
275
|
-
fogMode: options.config.fog.fogMode,
|
|
276
|
-
|
|
277
|
-
physicsGravity: options.config.physics.gravity,
|
|
278
|
-
|
|
279
|
-
environmentIntensity: options.config.environment.environmentIntensity,
|
|
280
|
-
environmentTexture: options.config.environment.environmentTexture,
|
|
281
|
-
|
|
282
|
-
metadata: options.config.metadata,
|
|
283
|
-
|
|
284
|
-
animations: options.config.animations,
|
|
285
|
-
|
|
286
|
-
postProcesses: [],
|
|
287
|
-
multiMaterials: [],
|
|
288
|
-
spriteManagers: [],
|
|
289
|
-
reflectionProbes: [],
|
|
290
|
-
|
|
291
|
-
meshes,
|
|
292
|
-
materials,
|
|
293
|
-
morphTargetManagers,
|
|
294
|
-
transformNodes,
|
|
295
|
-
particleSystems,
|
|
296
|
-
|
|
297
|
-
animationGroups: await Promise.all(
|
|
298
|
-
options.directories.animationGroupFiles.map(async (file) => {
|
|
299
|
-
return fs.readJSON(join(options.sceneFile, "animationGroups", file));
|
|
300
|
-
})
|
|
301
|
-
),
|
|
302
|
-
skeletons: await Promise.all(
|
|
303
|
-
options.directories.skeletonFiles.map(async (file) => {
|
|
304
|
-
return fs.readJSON(join(options.sceneFile, "skeletons", file));
|
|
305
|
-
})
|
|
306
|
-
),
|
|
307
|
-
cameras: await Promise.all(
|
|
308
|
-
options.directories.cameraFiles.map(async (file) => {
|
|
309
|
-
const data = await fs.readJSON(join(options.sceneFile, "cameras", file));
|
|
310
|
-
if (data.metadata?.parentId) {
|
|
311
|
-
data.parentId = data.metadata.parentId;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
return data;
|
|
315
|
-
})
|
|
316
|
-
),
|
|
317
|
-
lights: await Promise.all(
|
|
318
|
-
options.directories.lightsFiles.map(async (file) => {
|
|
319
|
-
const data = await fs.readJSON(join(options.sceneFile, "lights", file));
|
|
320
|
-
if (data.metadata?.parentId) {
|
|
321
|
-
data.parentId = data.metadata.parentId;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return data;
|
|
325
|
-
})
|
|
326
|
-
),
|
|
327
|
-
shadowGenerators: await Promise.all(
|
|
328
|
-
options.directories.shadowGeneratorFiles.map(async (file) => {
|
|
329
|
-
return fs.readJSON(join(options.sceneFile, "shadowGenerators", file));
|
|
330
|
-
})
|
|
331
|
-
),
|
|
332
|
-
sounds: await Promise.all(
|
|
333
|
-
options.directories.soundFiles.map(async (file) => {
|
|
334
|
-
return fs.readJSON(join(options.sceneFile, "sounds", file));
|
|
335
|
-
})
|
|
336
|
-
),
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
const destination = join(options.publicDir, `${options.sceneName}.babylon`);
|
|
340
|
-
await fs.writeJSON(destination, scene, {
|
|
341
|
-
encoding: "utf-8",
|
|
342
|
-
// spaces: "\t", // Useful for debug
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
options.exportedAssets.push(destination);
|
|
346
|
-
}
|
package/src/tools/extract.mts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path/posix";
|
|
2
|
-
|
|
3
|
-
import fs from "fs-extra";
|
|
4
|
-
import sharp from "sharp";
|
|
5
|
-
|
|
6
|
-
import { executeSimpleWorker } from "./worker.mjs";
|
|
7
|
-
|
|
8
|
-
export interface IExtractTextureAssetFromDataStringOptions {
|
|
9
|
-
extractedTexturesOutputPath: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export async function extractTextureAssetFromDataString(dataString: string, options: IExtractTextureAssetFromDataStringOptions) {
|
|
13
|
-
const split = dataString.split(",");
|
|
14
|
-
const header = split[0];
|
|
15
|
-
|
|
16
|
-
const headerSplit = header.split(";");
|
|
17
|
-
const dataType = headerSplit[1];
|
|
18
|
-
|
|
19
|
-
const byteString = split[1];
|
|
20
|
-
|
|
21
|
-
if (dataType === "base64") {
|
|
22
|
-
const buffer = Buffer.from(byteString, "base64");
|
|
23
|
-
const image = sharp(buffer);
|
|
24
|
-
|
|
25
|
-
const [metadata, hash] = await Promise.all([image.metadata(), executeSimpleWorker("workers/md5.mjs", buffer)]);
|
|
26
|
-
|
|
27
|
-
let filename: string;
|
|
28
|
-
switch (metadata.format) {
|
|
29
|
-
case "png":
|
|
30
|
-
filename = `${hash}.png`;
|
|
31
|
-
break;
|
|
32
|
-
|
|
33
|
-
case "jpg":
|
|
34
|
-
case "jpeg":
|
|
35
|
-
filename = `${hash}.jpg`;
|
|
36
|
-
break;
|
|
37
|
-
|
|
38
|
-
default:
|
|
39
|
-
console.error(`Unsupported embedded texture format while extracting texture: ${metadata.format}`);
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const outputFilename = join(options.extractedTexturesOutputPath, filename);
|
|
44
|
-
if (!(await fs.pathExists(outputFilename))) {
|
|
45
|
-
await fs.writeFile(outputFilename, buffer);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return join("assets", "editor-generated_extracted-textures", filename).replace(/\\/g, "/");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface IExtractTextureAssetFromUrlOptions {
|
|
55
|
-
extractedTexturesOutputPath: string;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function extractTextureAssetFromUrl(url: string, options: IExtractTextureAssetFromUrlOptions) {
|
|
59
|
-
try {
|
|
60
|
-
const response = await fetch(url);
|
|
61
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
62
|
-
|
|
63
|
-
const base64 = Buffer.from(arrayBuffer).toString("base64");
|
|
64
|
-
const dataString = `data:${response.headers.get("content-type") ?? "image/unknown"};base64,${base64}`;
|
|
65
|
-
|
|
66
|
-
return extractTextureAssetFromDataString(dataString, {
|
|
67
|
-
...options,
|
|
68
|
-
});
|
|
69
|
-
} catch (e) {
|
|
70
|
-
console.error(`Failed to extract texture from url "${url}": ${e.message}`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return null;
|
|
74
|
-
}
|
package/src/tools/fs.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { glob } from "glob";
|
|
2
|
-
|
|
3
|
-
export async function normalizedGlob(...args: Parameters<typeof glob>) {
|
|
4
|
-
const result = await glob(...args);
|
|
5
|
-
|
|
6
|
-
result.forEach((_: unknown, index: number) => {
|
|
7
|
-
result[index] = result[index].toString().replace(/\\/g, "/");
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
return result as string[];
|
|
11
|
-
}
|
package/src/tools/ktx.mts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import os from "node:os";
|
|
2
|
-
import { normalizedGlob } from "./fs.mjs";
|
|
3
|
-
import { join } from "node:path/posix";
|
|
4
|
-
|
|
5
|
-
export let pvrTexToolAbsolutePath: string | undefined;
|
|
6
|
-
|
|
7
|
-
export function setPVRTexToolAbsolutePath(absolutePath: string) {
|
|
8
|
-
pvrTexToolAbsolutePath = absolutePath;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function locatePVRTexTool() {
|
|
12
|
-
if (process.env.PVRTexToolCLI) {
|
|
13
|
-
return (pvrTexToolAbsolutePath = process.env.PVRTexToolCLI);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const platform = os.platform();
|
|
17
|
-
|
|
18
|
-
let absolutePathToCheck: string | null = null;
|
|
19
|
-
switch (platform) {
|
|
20
|
-
case "darwin":
|
|
21
|
-
absolutePathToCheck = "/Applications/Imagination/";
|
|
22
|
-
case "win32":
|
|
23
|
-
absolutePathToCheck = "C:/Imagination Technologies/";
|
|
24
|
-
default:
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!absolutePathToCheck) {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const files = await normalizedGlob(join(absolutePathToCheck, "**"), {
|
|
33
|
-
nodir: true,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
switch (platform) {
|
|
37
|
-
case "darwin":
|
|
38
|
-
return (pvrTexToolAbsolutePath = files.find((file) => file.endsWith("macOS/PVRTexToolCLI")));
|
|
39
|
-
case "win32":
|
|
40
|
-
return (pvrTexToolAbsolutePath = files.find((file) => file.endsWith("Windows_x86_64/PVRTexToolCLI.exe")));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
package/src/tools/process.mts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { exec } from "node:child_process";
|
|
2
|
-
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Executes the given command asynchronously using `child_process`
|
|
7
|
-
* @param command defines the command to execute.
|
|
8
|
-
*/
|
|
9
|
-
export function executeAsync(command: string): Promise<void> {
|
|
10
|
-
return new Promise<void>((resolve, reject) => {
|
|
11
|
-
exec(command, (error, stdout, stderr) => {
|
|
12
|
-
if (error) {
|
|
13
|
-
console.error(chalk.red(command), chalk.red(stderr));
|
|
14
|
-
reject(error);
|
|
15
|
-
} else {
|
|
16
|
-
console.log(chalk.gray(command), chalk.gray(stdout));
|
|
17
|
-
resolve();
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
}
|