babylonjs-editor-cli 5.0.0
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/bin/babylonjs-editor-cli.js +3 -0
- package/build/index.node.js +21 -0
- package/build/package.json +34 -0
- package/build/src/export.mjs +2 -0
- package/build/src/export.mjs.map +1 -0
- package/build/src/index.mjs +22 -0
- package/build/src/index.mjs.map +1 -0
- package/build/src/pack/assets/assets.mjs +26 -0
- package/build/src/pack/assets/assets.mjs.map +1 -0
- package/build/src/pack/assets/ktx.mjs +121 -0
- package/build/src/pack/assets/ktx.mjs.map +1 -0
- package/build/src/pack/assets/material.mjs +53 -0
- package/build/src/pack/assets/material.mjs.map +1 -0
- package/build/src/pack/assets/particle-system.mjs +75 -0
- package/build/src/pack/assets/particle-system.mjs.map +1 -0
- package/build/src/pack/assets/process.mjs +78 -0
- package/build/src/pack/assets/process.mjs.map +1 -0
- package/build/src/pack/assets/texture.mjs +61 -0
- package/build/src/pack/assets/texture.mjs.map +1 -0
- package/build/src/pack/geometry.mjs +19 -0
- package/build/src/pack/geometry.mjs.map +1 -0
- package/build/src/pack/pack.mjs +127 -0
- package/build/src/pack/pack.mjs.map +1 -0
- package/build/src/pack/scene.mjs +241 -0
- package/build/src/pack/scene.mjs.map +1 -0
- package/build/src/tools/extract.mjs +51 -0
- package/build/src/tools/extract.mjs.map +1 -0
- package/build/src/tools/fs.mjs +9 -0
- package/build/src/tools/fs.mjs.map +1 -0
- package/build/src/tools/ktx.mjs +36 -0
- package/build/src/tools/ktx.mjs.map +1 -0
- package/build/src/tools/process.mjs +21 -0
- package/build/src/tools/process.mjs.map +1 -0
- package/build/src/tools/scalar.mjs +23 -0
- package/build/src/tools/scalar.mjs.map +1 -0
- package/build/src/tools/scene.mjs +68 -0
- package/build/src/tools/scene.mjs.map +1 -0
- package/build/src/tools/worker.mjs +35 -0
- package/build/src/tools/worker.mjs.map +1 -0
- package/build/src/tools/workers/md5.mjs +10 -0
- package/build/src/tools/workers/md5.mjs.map +1 -0
- package/declaration/src/export.d.mts +1 -0
- package/declaration/src/index.d.mts +1 -0
- package/declaration/src/pack/assets/assets.d.mts +11 -0
- package/declaration/src/pack/assets/ktx.d.mts +28 -0
- package/declaration/src/pack/assets/material.d.mts +11 -0
- package/declaration/src/pack/assets/particle-system.d.mts +12 -0
- package/declaration/src/pack/assets/process.d.mts +9 -0
- package/declaration/src/pack/assets/texture.d.mts +7 -0
- package/declaration/src/pack/geometry.d.mts +10 -0
- package/declaration/src/pack/pack.d.mts +5 -0
- package/declaration/src/pack/scene.d.mts +13 -0
- package/declaration/src/tools/extract.d.mts +8 -0
- package/declaration/src/tools/fs.d.mts +2 -0
- package/declaration/src/tools/ktx.d.mts +3 -0
- package/declaration/src/tools/process.d.mts +5 -0
- package/declaration/src/tools/scalar.d.mts +8 -0
- package/declaration/src/tools/scene.d.mts +21 -0
- package/declaration/src/tools/worker.d.mts +18 -0
- package/declaration/src/tools/workers/md5.d.mts +1 -0
- package/esbuild.mjs +57 -0
- package/package.json +34 -0
- package/src/export.mts +1 -0
- package/src/index.mts +28 -0
- package/src/pack/assets/assets.mts +46 -0
- package/src/pack/assets/ktx.mts +158 -0
- package/src/pack/assets/material.mts +86 -0
- package/src/pack/assets/particle-system.mts +109 -0
- package/src/pack/assets/process.mts +102 -0
- package/src/pack/assets/texture.mts +91 -0
- package/src/pack/geometry.mts +38 -0
- package/src/pack/pack.mts +159 -0
- package/src/pack/scene.mts +346 -0
- package/src/tools/extract.mts +74 -0
- package/src/tools/fs.mts +11 -0
- package/src/tools/ktx.mts +44 -0
- package/src/tools/process.mts +21 -0
- package/src/tools/scalar.mts +28 -0
- package/src/tools/scene.mts +90 -0
- package/src/tools/worker.mts +39 -0
- package/src/tools/workers/md5.mts +13 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { join } from "node:path/posix";
|
|
2
|
+
import { Worker } from "node:worker_threads";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new worker and returns its reference.
|
|
5
|
+
* @param path defines the relative path to the worker entry point relative to THIS file.
|
|
6
|
+
*/
|
|
7
|
+
export function loadWorker(path, workerData) {
|
|
8
|
+
path = join(import.meta.dirname.replace(/\\/g, "/"), path);
|
|
9
|
+
return new Worker(path, {
|
|
10
|
+
workerData,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new worker and returns the result computed by the worker.
|
|
15
|
+
* Posts the given message data to the worker and waits until the worker posts a message back.
|
|
16
|
+
* @param path defines the relative path to the worker according to THIS file. Typically "workers/myWorker.js".
|
|
17
|
+
* @param data defines the data object posted to the worker once it has been initialized.
|
|
18
|
+
* @param transfer defines the optional transferable objects to pass to the worker.
|
|
19
|
+
* @returns a promise that resolves with the data posted by the worker.
|
|
20
|
+
*/
|
|
21
|
+
export async function executeSimpleWorker(pathOrWorker, data) {
|
|
22
|
+
const worker = loadWorker(pathOrWorker, data);
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
worker.on("message", (result) => {
|
|
25
|
+
if (data.id && result.id !== data.id) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
else if (!data.id) {
|
|
29
|
+
worker.terminate();
|
|
30
|
+
}
|
|
31
|
+
resolve(result);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=worker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.mjs","sourceRoot":"","sources":["../../../src/tools/worker.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,UAA6B;IACrE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE;QACvB,UAAU;KACV,CAAC,CAAC;AACJ,CAAC;AAID;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAI,YAAoB,EAAE,IAAuB;IACzF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAE9C,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;QACjC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,IAAI,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACtC,OAAO;YACR,CAAC;iBAAM,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACrB,MAAM,CAAC,SAAS,EAAE,CAAC;YACpB,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { workerData, parentPort } from "node:worker_threads";
|
|
2
|
+
import md5 from "md5";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
let content = workerData;
|
|
5
|
+
if (typeof workerData === "string") {
|
|
6
|
+
content = await fs.readFile(workerData);
|
|
7
|
+
}
|
|
8
|
+
const hash = md5(content);
|
|
9
|
+
parentPort?.postMessage(hash);
|
|
10
|
+
//# sourceMappingURL=md5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md5.mjs","sourceRoot":"","sources":["../../../../src/tools/workers/md5.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,UAAU,CAAC;AAE1B,IAAI,OAAO,GAAG,UAAU,CAAC;AAEzB,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;IACpC,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;AAC1B,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { pack, IPackOptions } from "./pack/pack.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ICreateAssetsOptions {
|
|
2
|
+
projectDir: string;
|
|
3
|
+
publicDir: string;
|
|
4
|
+
baseAssetsDir: string;
|
|
5
|
+
outputAssetsDir: string;
|
|
6
|
+
optimize: boolean;
|
|
7
|
+
exportedAssets: string[];
|
|
8
|
+
cache: Record<string, string>;
|
|
9
|
+
compressedTexturesEnabled: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function createAssets(options: ICreateAssetsOptions): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type KTXToolsType = "-astc.ktx" | "-dxt.ktx" | "-pvrtc.ktx" | "-etc1.ktx" | "-etc2.ktx";
|
|
2
|
+
export declare const allKtxFormats: KTXToolsType[];
|
|
3
|
+
export declare const ktxSupportedextensions: string[];
|
|
4
|
+
/**
|
|
5
|
+
* Returns the absolute path to the compressed textures CLI path (PVRTexTool).
|
|
6
|
+
* The value is retrieved from the local storage so it's per computer and not per project.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCompressedTexturesCliPath(): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Sets the absolute path to the compressed textures CLI path (PVRTexTool).
|
|
11
|
+
* The value is stored in the local storage so it's per computer and not per project.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setCompressedTexturesCliPath(absolutePath: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the filename of the compressed texture according to the given path and the destination format.
|
|
16
|
+
* @param path defines the path of the texture to get its final name.
|
|
17
|
+
* @param format defines the destination format of the texture.
|
|
18
|
+
* @example image.png -> image-asct.ktx
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCompressedTextureFilename(path: string, format: KTXToolsType): string;
|
|
21
|
+
export type CompressFileToKtxOptions = {
|
|
22
|
+
format: KTXToolsType;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
exportedAssets?: string[];
|
|
25
|
+
destinationFolder?: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function compressFileToKtx(absolutePath: string, options: Partial<CompressFileToKtxOptions>): Promise<void>;
|
|
28
|
+
export declare function compressFileToKtxFormat(absolutePath: string, options: CompressFileToKtxOptions): Promise<string | null>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface IProcessExportedMaterialOptions {
|
|
2
|
+
force: boolean;
|
|
3
|
+
publicDir: string;
|
|
4
|
+
exportedAssets: string[];
|
|
5
|
+
optimize: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function processExportedMaterial(absolutePath: string, options: IProcessExportedMaterialOptions): Promise<void>;
|
|
8
|
+
export interface IExtractNodeMaterialTexturesOptions {
|
|
9
|
+
extractedTexturesOutputPath: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function extractNodeMaterialTextures(materialData: any, options: IExtractNodeMaterialTexturesOptions): Promise<string[]>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface IProcessExportedMaterialOptions {
|
|
2
|
+
force: boolean;
|
|
3
|
+
publicDir: string;
|
|
4
|
+
exportedAssets: string[];
|
|
5
|
+
optimize: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function processExportedNodeParticleSystemSet(absolutePath: string, options: IProcessExportedMaterialOptions): Promise<void>;
|
|
8
|
+
export interface IExtractParticleSystemTexturesOptions {
|
|
9
|
+
extractedTexturesOutputPath: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function extractParticleSystemTextures(particleSystemData: any, options: IExtractParticleSystemTexturesOptions): Promise<string | null>;
|
|
12
|
+
export declare function extractNodeParticleSystemSetTextures(particleSystemData: any, options: IExtractParticleSystemTexturesOptions): Promise<string[]>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ICreateAssetsOptions } from "./assets.mjs";
|
|
2
|
+
export interface IProcessAssetFileOptions extends ICreateAssetsOptions {
|
|
3
|
+
outputAssetsDir: string;
|
|
4
|
+
exportedAssets: string[];
|
|
5
|
+
optimize: boolean;
|
|
6
|
+
cache: Record<string, string>;
|
|
7
|
+
compressedTexturesEnabled: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function processAssetFile(file: string, options: IProcessAssetFileOptions): Promise<void>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function getExtractedTextureOutputPath(publicDir: string): string;
|
|
2
|
+
export interface IComputeExportedTextureOptions {
|
|
3
|
+
force: boolean;
|
|
4
|
+
exportedAssets: string[];
|
|
5
|
+
compressedTexturesEnabled: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function processExportedTexture(absolutePath: string, options: IComputeExportedTextureOptions): Promise<void>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { readSceneDirectories } from "../tools/scene.mjs";
|
|
2
|
+
export interface ICreateGeometryFilesOptions {
|
|
3
|
+
sceneFile: string;
|
|
4
|
+
sceneName: string;
|
|
5
|
+
publicDir: string;
|
|
6
|
+
exportedAssets: string[];
|
|
7
|
+
babylonjsEditorToolsVersion: string;
|
|
8
|
+
directories: Awaited<ReturnType<typeof readSceneDirectories>>;
|
|
9
|
+
}
|
|
10
|
+
export declare function createGeometryFiles(options: ICreateGeometryFilesOptions): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readSceneDirectories } from "../tools/scene.mjs";
|
|
2
|
+
export interface ICreateBabylonSceneOptions {
|
|
3
|
+
sceneFile: string;
|
|
4
|
+
sceneName: string;
|
|
5
|
+
publicDir: string;
|
|
6
|
+
babylonjsEditorToolsVersion: string;
|
|
7
|
+
exportedAssets: string[];
|
|
8
|
+
optimize: boolean;
|
|
9
|
+
compressedTexturesEnabled: boolean;
|
|
10
|
+
config: any;
|
|
11
|
+
directories: Awaited<ReturnType<typeof readSceneDirectories>>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createBabylonScene(options: ICreateBabylonSceneOptions): Promise<void>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface IExtractTextureAssetFromDataStringOptions {
|
|
2
|
+
extractedTexturesOutputPath: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function extractTextureAssetFromDataString(dataString: string, options: IExtractTextureAssetFromDataStringOptions): Promise<string | null>;
|
|
5
|
+
export interface IExtractTextureAssetFromUrlOptions {
|
|
6
|
+
extractedTexturesOutputPath: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function extractTextureAssetFromUrl(url: string, options: IExtractTextureAssetFromUrlOptions): Promise<string | null>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the power of two sizes until the given limit.
|
|
3
|
+
* @param limit The limit size.
|
|
4
|
+
* @param from The starting size. Default is 1.
|
|
5
|
+
* @returns An array of power of two sizes.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getPowerOfTwoSizesUntil(limit?: number, from?: number): number[];
|
|
8
|
+
export declare function getPowerOfTwoUntil(limit: number): number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare function ensureSceneDirectories(scenePath: string): Promise<void>;
|
|
2
|
+
export declare function readSceneDirectories(scenePath: string): Promise<{
|
|
3
|
+
nodesFiles: string[];
|
|
4
|
+
meshesFiles: string[];
|
|
5
|
+
lodsFiles: string[];
|
|
6
|
+
lightsFiles: string[];
|
|
7
|
+
cameraFiles: string[];
|
|
8
|
+
skeletonFiles: string[];
|
|
9
|
+
shadowGeneratorFiles: string[];
|
|
10
|
+
sceneLinkFiles: string[];
|
|
11
|
+
guiFiles: string[];
|
|
12
|
+
soundFiles: string[];
|
|
13
|
+
particleSystemFiles: string[];
|
|
14
|
+
morphTargetManagerFiles: string[];
|
|
15
|
+
morphTargetFiles: string[];
|
|
16
|
+
animationGroupFiles: string[];
|
|
17
|
+
spriteMapFiles: string[];
|
|
18
|
+
spriteManagerFiles: string[];
|
|
19
|
+
geometryFiles: string[];
|
|
20
|
+
nodeParticleSystemSetFiles: string[];
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Worker } from "node:worker_threads";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new worker and returns its reference.
|
|
4
|
+
* @param path defines the relative path to the worker entry point relative to THIS file.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadWorker(path: string, workerData: WorkerMessageData): Worker;
|
|
7
|
+
export type WorkerMessageData = {
|
|
8
|
+
id?: string;
|
|
9
|
+
} & Record<string, any>;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new worker and returns the result computed by the worker.
|
|
12
|
+
* Posts the given message data to the worker and waits until the worker posts a message back.
|
|
13
|
+
* @param path defines the relative path to the worker according to THIS file. Typically "workers/myWorker.js".
|
|
14
|
+
* @param data defines the data object posted to the worker once it has been initialized.
|
|
15
|
+
* @param transfer defines the optional transferable objects to pass to the worker.
|
|
16
|
+
* @returns a promise that resolves with the data posted by the worker.
|
|
17
|
+
*/
|
|
18
|
+
export declare function executeSimpleWorker<T>(pathOrWorker: string, data: WorkerMessageData): Promise<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/esbuild.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import esbuild from "esbuild";
|
|
2
|
+
|
|
3
|
+
import { argv, exit } from "node:process";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
|
|
6
|
+
const args = argv.slice(2);
|
|
7
|
+
const isWatch = args.includes("--watch");
|
|
8
|
+
|
|
9
|
+
const replaceImportMetaDirname = {
|
|
10
|
+
name: "replaceImportMetaDirname",
|
|
11
|
+
setup(build) {
|
|
12
|
+
build.onLoad({ filter: /.*/ }, async (args) => {
|
|
13
|
+
const source = await readFile(args.path, "utf8");
|
|
14
|
+
|
|
15
|
+
const transformedSource = source.replace(/import.meta.dirname/g, '"__dirname"');
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
loader: "default",
|
|
19
|
+
contents: transformedSource,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const mainBuildOptions = {
|
|
26
|
+
entryPoints: ["./src/export.mts"],
|
|
27
|
+
bundle: true,
|
|
28
|
+
platform: "node",
|
|
29
|
+
target: "node20", // target version of Node.js
|
|
30
|
+
format: "cjs", // output format as CommonJS
|
|
31
|
+
outfile: "./build/index.node.js",
|
|
32
|
+
treeShaking: false,
|
|
33
|
+
loader: {
|
|
34
|
+
".mts": "ts",
|
|
35
|
+
},
|
|
36
|
+
keepNames: true,
|
|
37
|
+
minify: !isWatch,
|
|
38
|
+
plugins: [replaceImportMetaDirname],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
if (args.includes("--watch")) {
|
|
42
|
+
esbuild
|
|
43
|
+
.context(mainBuildOptions)
|
|
44
|
+
.then(async (buildcontext) => {
|
|
45
|
+
await buildcontext.watch();
|
|
46
|
+
console.log("Watching...");
|
|
47
|
+
})
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
console.error(error);
|
|
50
|
+
exit(1);
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
esbuild.build(mainBuildOptions).catch((error) => {
|
|
54
|
+
console.error(error);
|
|
55
|
+
exit(1);
|
|
56
|
+
});
|
|
57
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "babylonjs-editor-cli",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Babylon.js Editor CLI is a command line interface to help you package your scenes made using the Babylon.js Editor",
|
|
5
|
+
"productName": "Babylon.js Editor CLI",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc -p . && node esbuild.mjs",
|
|
8
|
+
"watch": "concurrently \"tsc -p . --watch\" \"node esbuild.mjs --watch\" -c bgYellow.bold,bgBlue.bold --names cli-ts,editor-dependencies"
|
|
9
|
+
},
|
|
10
|
+
"typings": "declaration/src/export.d.mts",
|
|
11
|
+
"license": "(Apache-2.0)",
|
|
12
|
+
"bin": {
|
|
13
|
+
"babylonjs-editor-cli": "./bin/babylonjs-editor-cli.js"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./declaration/src/export.d.ts",
|
|
18
|
+
"import": "./build/src/export.mjs",
|
|
19
|
+
"require": "./build/index.node.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"chalk": "5.6.2",
|
|
25
|
+
"cli-spinners": "3.4.0",
|
|
26
|
+
"commander": "14.0.2",
|
|
27
|
+
"dotenv": "17.2.3",
|
|
28
|
+
"fs-extra": "11.2.0",
|
|
29
|
+
"glob": "11.1.0",
|
|
30
|
+
"pngjs": "7.0.0",
|
|
31
|
+
"ora": "9.1.0",
|
|
32
|
+
"sharp": "0.34.3"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/export.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { pack, IPackOptions } from "./pack/pack.mjs";
|
package/src/index.mts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import dotEnv from "dotenv";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
|
|
4
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
5
|
+
|
|
6
|
+
import { pack } from "./pack/pack.mjs";
|
|
7
|
+
|
|
8
|
+
dotEnv.config();
|
|
9
|
+
|
|
10
|
+
const program = new Command();
|
|
11
|
+
|
|
12
|
+
program
|
|
13
|
+
.version(packageJson.version)
|
|
14
|
+
.name("Babylon.js Editor CLI")
|
|
15
|
+
.description("Babylon.js Editor CLI is a command line interface to help you package your scenes made using the Babylon.js Editor")
|
|
16
|
+
.option("-h, --help", "display help for command");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("pack")
|
|
20
|
+
.description("Packs the project located in the specified directory. Current directory is used by default.")
|
|
21
|
+
.argument("[projectDir]", "The root directory of the project to package", process.cwd())
|
|
22
|
+
.action((projectDir: string) => {
|
|
23
|
+
pack(projectDir, {
|
|
24
|
+
optimize: true,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
program.parse();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { cpus } from "node:os";
|
|
2
|
+
import { extname, join } from "node:path/posix";
|
|
3
|
+
|
|
4
|
+
import { normalizedGlob } from "../../tools/fs.mjs";
|
|
5
|
+
|
|
6
|
+
import { processAssetFile } from "./process.mjs";
|
|
7
|
+
|
|
8
|
+
export interface ICreateAssetsOptions {
|
|
9
|
+
projectDir: string;
|
|
10
|
+
publicDir: string;
|
|
11
|
+
baseAssetsDir: string;
|
|
12
|
+
outputAssetsDir: string;
|
|
13
|
+
optimize: boolean;
|
|
14
|
+
exportedAssets: string[];
|
|
15
|
+
cache: Record<string, string>;
|
|
16
|
+
compressedTexturesEnabled: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function createAssets(options: ICreateAssetsOptions) {
|
|
20
|
+
const files = await normalizedGlob(join(options.baseAssetsDir, "**/*"), {
|
|
21
|
+
nodir: true,
|
|
22
|
+
ignore: {
|
|
23
|
+
childrenIgnored: (p) => extname(p.name) === ".scene",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const promises: Promise<void>[] = [];
|
|
28
|
+
|
|
29
|
+
const cpusCount = cpus().length;
|
|
30
|
+
console.log(`Using ${cpusCount} cpus to process assets...`);
|
|
31
|
+
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
if (promises.length >= cpusCount) {
|
|
34
|
+
await Promise.all(promises);
|
|
35
|
+
promises.length = 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
promises.push(
|
|
39
|
+
processAssetFile(file, {
|
|
40
|
+
...options,
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
await Promise.all(promises);
|
|
46
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { basename, extname, join, dirname } from "node:path/posix";
|
|
2
|
+
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import { PNG } from "pngjs";
|
|
5
|
+
import { createReadStream } from "node:fs";
|
|
6
|
+
|
|
7
|
+
import { executeAsync } from "../../tools/process.mjs";
|
|
8
|
+
import { pvrTexToolAbsolutePath } from "../../tools/ktx.mjs";
|
|
9
|
+
|
|
10
|
+
export type KTXToolsType = "-astc.ktx" | "-dxt.ktx" | "-pvrtc.ktx" | "-etc1.ktx" | "-etc2.ktx";
|
|
11
|
+
|
|
12
|
+
export const allKtxFormats: KTXToolsType[] = ["-astc.ktx", "-dxt.ktx", "-pvrtc.ktx", "-etc1.ktx", "-etc2.ktx"];
|
|
13
|
+
|
|
14
|
+
export const ktxSupportedextensions: string[] = [".png", ".jpg", ".jpeg", ".bmp"];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns the absolute path to the compressed textures CLI path (PVRTexTool).
|
|
18
|
+
* The value is retrieved from the local storage so it's per computer and not per project.
|
|
19
|
+
*/
|
|
20
|
+
export function getCompressedTexturesCliPath() {
|
|
21
|
+
let value = "";
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
value = localStorage.getItem("editor-compressed-textures-cli-path") ?? "";
|
|
25
|
+
} catch (e) {
|
|
26
|
+
// Catch silently.
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return value || null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Sets the absolute path to the compressed textures CLI path (PVRTexTool).
|
|
34
|
+
* The value is stored in the local storage so it's per computer and not per project.
|
|
35
|
+
*/
|
|
36
|
+
export function setCompressedTexturesCliPath(absolutePath: string) {
|
|
37
|
+
try {
|
|
38
|
+
localStorage.setItem("editor-compressed-textures-cli-path", absolutePath);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
// Catch silently.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns the filename of the compressed texture according to the given path and the destination format.
|
|
46
|
+
* @param path defines the path of the texture to get its final name.
|
|
47
|
+
* @param format defines the destination format of the texture.
|
|
48
|
+
* @example image.png -> image-asct.ktx
|
|
49
|
+
*/
|
|
50
|
+
export function getCompressedTextureFilename(path: string, format: KTXToolsType) {
|
|
51
|
+
return `${path.substring(0, path.lastIndexOf("."))}${format}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type CompressFileToKtxOptions = {
|
|
55
|
+
format: KTXToolsType;
|
|
56
|
+
force?: boolean;
|
|
57
|
+
exportedAssets?: string[];
|
|
58
|
+
destinationFolder?: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export async function compressFileToKtx(absolutePath: string, options: Partial<CompressFileToKtxOptions>): Promise<void> {
|
|
62
|
+
if (options.format) {
|
|
63
|
+
await compressFileToKtxFormat(absolutePath, options as CompressFileToKtxOptions);
|
|
64
|
+
} else {
|
|
65
|
+
await Promise.all(
|
|
66
|
+
allKtxFormats.map((f) =>
|
|
67
|
+
compressFileToKtxFormat(absolutePath, {
|
|
68
|
+
...options,
|
|
69
|
+
format: f,
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function compressFileToKtxFormat(absolutePath: string, options: CompressFileToKtxOptions): Promise<string | null> {
|
|
77
|
+
const name = basename(absolutePath);
|
|
78
|
+
const extension = extname(name).toLocaleLowerCase();
|
|
79
|
+
|
|
80
|
+
if (!ktxSupportedextensions.includes(extension)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const filename = getCompressedTextureFilename(name, options.format);
|
|
85
|
+
|
|
86
|
+
options.destinationFolder ??= dirname(absolutePath);
|
|
87
|
+
options.destinationFolder = join(options.destinationFolder, filename);
|
|
88
|
+
|
|
89
|
+
// if (!editor.state.compressedTexturesEnabled) {
|
|
90
|
+
// options.exportedAssets?.push(options.destinationFolder);
|
|
91
|
+
// return null;
|
|
92
|
+
// }
|
|
93
|
+
|
|
94
|
+
if ((await fs.pathExists(options.destinationFolder)) && !options.force) {
|
|
95
|
+
options.exportedAssets?.push(options.destinationFolder);
|
|
96
|
+
return options.destinationFolder;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const hasAlpha = await new Promise<boolean>((resolve) => {
|
|
100
|
+
const stream = createReadStream(absolutePath);
|
|
101
|
+
|
|
102
|
+
stream
|
|
103
|
+
.pipe(new PNG())
|
|
104
|
+
.on("metadata", (p) => {
|
|
105
|
+
resolve(p.alpha);
|
|
106
|
+
stream.close();
|
|
107
|
+
})
|
|
108
|
+
.on("error", () => {
|
|
109
|
+
resolve(false);
|
|
110
|
+
stream.close();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!pvrTexToolAbsolutePath) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let command: string | null = null;
|
|
119
|
+
switch (options.format) {
|
|
120
|
+
case "-astc.ktx":
|
|
121
|
+
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -dither -ics lRGB -f ASTC_8x8,UBN,lRGB -q astcveryfast -o "${options.destinationFolder}"`;
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case "-dxt.ktx":
|
|
125
|
+
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -ics lRGB ${hasAlpha ? "-l" : ""} -f ${hasAlpha ? "BC2" : "BC1"},UBN,lRGB -o "${options.destinationFolder}"`;
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case "-pvrtc.ktx":
|
|
129
|
+
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -square + -m -dither -ics lRGB ${hasAlpha ? "-l" : ""} -f ${hasAlpha ? "PVRTCI_2BPP_RGBA" : "PVRTCI_2BPP_RGB"},UBN,lRGB -q pvrtcfastest -o "${options.destinationFolder}"`;
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case "-etc1.ktx":
|
|
133
|
+
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -dither -ics lRGB -f ETC1,UBN,lRGB -q etcfast -o "${options.destinationFolder}"`;
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
case "-etc2.ktx":
|
|
137
|
+
command = `"${pvrTexToolAbsolutePath}" -i "${absolutePath}" -flip y -pot + -m -dither -ics lRGB -f ${hasAlpha ? "ETC2_RGBA" : "ETC2_RGB"},UBN,lRGB -q etcfast -o "${options.destinationFolder}"`;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!command) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(`Compressing image "${filename}"`);
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
await executeAsync(command);
|
|
149
|
+
console.log(`Compressed image "${filename}"`);
|
|
150
|
+
options.exportedAssets?.push(options.destinationFolder);
|
|
151
|
+
|
|
152
|
+
return options.destinationFolder;
|
|
153
|
+
} catch (e) {
|
|
154
|
+
console.error(`Failed to compress image "${filename}"`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
}
|