@needle-tools/gltf-build-pipeline 0.1.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/clear-caches.mjs +4 -0
  3. package/defaults.mjs +12 -0
  4. package/dist/cache/cache.d.ts +5 -0
  5. package/dist/cache/cache.js +82 -0
  6. package/dist/cache/index.d.ts +1 -0
  7. package/dist/cache/index.js +1 -0
  8. package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.d.ts +24 -0
  9. package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.js +54 -0
  10. package/dist/extensions/NEEDLE_compression_texture/index.d.ts +1 -0
  11. package/dist/extensions/NEEDLE_compression_texture/index.js +1 -0
  12. package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.d.ts +23 -0
  13. package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.js +43 -0
  14. package/dist/extensions/NEEDLE_mesh_compression/index.d.ts +1 -0
  15. package/dist/extensions/NEEDLE_mesh_compression/index.js +1 -0
  16. package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.d.ts +20 -0
  17. package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.js +699 -0
  18. package/dist/extensions/NEEDLE_opaque/index.d.ts +3 -0
  19. package/dist/extensions/NEEDLE_opaque/index.js +18 -0
  20. package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.d.ts +23 -0
  21. package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.js +53 -0
  22. package/dist/extensions/NEEDLE_progressive/index.d.ts +1 -0
  23. package/dist/extensions/NEEDLE_progressive/index.js +1 -0
  24. package/dist/extensions/NEEDLE_progressive_texture_settings/index.d.ts +21 -0
  25. package/dist/extensions/NEEDLE_progressive_texture_settings/index.js +39 -0
  26. package/dist/extensions/index.d.ts +6 -0
  27. package/dist/extensions/index.js +16 -0
  28. package/dist/extensions/utils.d.ts +6 -0
  29. package/dist/extensions/utils.js +72 -0
  30. package/dist/functions/list-texture-slots.d.ts +1 -0
  31. package/dist/functions/list-texture-slots.js +35 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +3 -0
  34. package/dist/transforms/index.d.ts +9 -0
  35. package/dist/transforms/index.js +9 -0
  36. package/dist/transforms/needle_animation_transform.d.ts +2 -0
  37. package/dist/transforms/needle_animation_transform.js +5 -0
  38. package/dist/transforms/needle_asset.d.ts +2 -0
  39. package/dist/transforms/needle_asset.js +28 -0
  40. package/dist/transforms/needle_common.d.ts +11 -0
  41. package/dist/transforms/needle_common.js +1 -0
  42. package/dist/transforms/needle_mesh_transform.d.ts +3 -0
  43. package/dist/transforms/needle_mesh_transform.js +83 -0
  44. package/dist/transforms/needle_progressive.d.ts +34 -0
  45. package/dist/transforms/needle_progressive.js +264 -0
  46. package/dist/transforms/needle_simplify.d.ts +3 -0
  47. package/dist/transforms/needle_simplify.js +76 -0
  48. package/dist/transforms/needle_texture_transform.d.ts +5 -0
  49. package/dist/transforms/needle_texture_transform.js +123 -0
  50. package/dist/transforms/needle_toktx.d.ts +24 -0
  51. package/dist/transforms/needle_toktx.js +144 -0
  52. package/dist/transforms/needle_webp.d.ts +13 -0
  53. package/dist/transforms/needle_webp.js +53 -0
  54. package/dist/transforms/toktx.d.ts +77 -0
  55. package/dist/transforms/toktx.js +230 -0
  56. package/dist/transforms/types/squoosh.d.ts +31 -0
  57. package/dist/transforms/types/squoosh.js +33 -0
  58. package/dist/transforms/util.d.ts +21 -0
  59. package/dist/transforms/util.js +90 -0
  60. package/dist/utils/fileutils.d.ts +2 -0
  61. package/dist/utils/fileutils.js +95 -0
  62. package/dist/utils/index.d.ts +1 -0
  63. package/dist/utils/index.js +1 -0
  64. package/fileutils.mjs +6 -0
  65. package/index.mjs +33 -0
  66. package/make-progressive.mjs +11 -0
  67. package/pack-gltf.mjs +119 -0
  68. package/package.json +60 -0
  69. package/tsconfig.json +15 -0
@@ -0,0 +1,3 @@
1
+ import { IOpaqueExtension } from "./NEEDLE_opaque.js";
2
+ export * from "./NEEDLE_opaque.js";
3
+ export declare const ALL_EXTENSIONS: IOpaqueExtension[];
@@ -0,0 +1,18 @@
1
+ import { PropertyType } from "@gltf-transform/core";
2
+ import { createOpaqueExtension } from "./NEEDLE_opaque.js";
3
+ export * from "./NEEDLE_opaque.js";
4
+ const opaqueOptions = {
5
+ debug: false,
6
+ };
7
+ export const ALL_EXTENSIONS = [
8
+ createOpaqueExtension("KHR_animation_pointer", [PropertyType.ANIMATION, PropertyType.ANIMATION_CHANNEL], { ...opaqueOptions }),
9
+ createOpaqueExtension("NEEDLE_techniques_webgl", [PropertyType.NODE, PropertyType.MATERIAL, PropertyType.ROOT], { ...opaqueOptions }),
10
+ createOpaqueExtension("NEEDLE_gameobject_data", PropertyType.NODE, { ...opaqueOptions }),
11
+ createOpaqueExtension("NEEDLE_components", PropertyType.NODE, { ...opaqueOptions }),
12
+ createOpaqueExtension("NEEDLE_persistent_assets", PropertyType.ROOT, { ...opaqueOptions }),
13
+ createOpaqueExtension("NEEDLE_lightmaps", PropertyType.ROOT, { ...opaqueOptions }),
14
+ createOpaqueExtension("NEEDLE_lighting_settings", PropertyType.ROOT, { ...opaqueOptions }),
15
+ createOpaqueExtension("NEEDLE_render_objects", PropertyType.ROOT, { ...opaqueOptions }),
16
+ createOpaqueExtension("NEEDLE_progressive", [PropertyType.TEXTURE, PropertyType.MATERIAL], { ...opaqueOptions }),
17
+ createOpaqueExtension("EXT_texture_exr", [PropertyType.TEXTURE], { ...opaqueOptions }),
18
+ ];
@@ -0,0 +1,23 @@
1
+ import { Extension, ExtensionProperty, PropertyType, ReaderContext, WriterContext } from "@gltf-transform/core";
2
+ export declare const NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME = "NEEDLE_progressive";
3
+ export declare interface IProgressiveTextureInfo {
4
+ uri?: string;
5
+ guid: string;
6
+ level?: number;
7
+ }
8
+ export declare function generateGuid(): string;
9
+ export declare class NEEDLE_progressive extends Extension {
10
+ static EXTENSION_NAME: string;
11
+ extensionName: string;
12
+ create(data: IProgressiveTextureInfo): NEEDLE_progressive_texture_property;
13
+ read(_context: ReaderContext): this;
14
+ write(context: WriterContext): this;
15
+ }
16
+ export declare class NEEDLE_progressive_texture_property extends ExtensionProperty {
17
+ static EXTENSION_NAME: string;
18
+ readonly extensionName: string;
19
+ parentTypes: PropertyType[];
20
+ propertyType: string;
21
+ init(): void;
22
+ model: IProgressiveTextureInfo;
23
+ }
@@ -0,0 +1,53 @@
1
+ import { Extension, ExtensionProperty, PropertyType, uuid } from "@gltf-transform/core";
2
+ // TODO: rename to NEEDLE_progressive_texture
3
+ export const NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME = "NEEDLE_progressive";
4
+ export function generateGuid() {
5
+ // TODO: replace with same uuid package as in needle engine
6
+ return uuid();
7
+ }
8
+ export class NEEDLE_progressive extends Extension {
9
+ static EXTENSION_NAME = NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME;
10
+ extensionName = NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME;
11
+ create(data) {
12
+ const ext = new NEEDLE_progressive_texture_property(this.document.getGraph());
13
+ ext.model = data;
14
+ return ext;
15
+ }
16
+ read(_context) {
17
+ // console.log("READ " + NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME);
18
+ return this;
19
+ }
20
+ write(context) {
21
+ // console.log("WRITE " + NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME);
22
+ const textureDefinitions = context.jsonDoc.json.textures;
23
+ if (!textureDefinitions)
24
+ return;
25
+ const root = this.document.getRoot();
26
+ const textures = root.listTextures();
27
+ // we use the texture image map to find the texture definition to write the extension to
28
+ const textureImageIndexMap = context.imageIndexMap;
29
+ for (const tex of textures) {
30
+ const prop = tex.getExtension(NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME);
31
+ if (prop && prop.model) {
32
+ // get the image this texture is using
33
+ const imageIndex = textureImageIndexMap.get(tex);
34
+ // find the texture definition that uses this image and add the extension
35
+ for (const def of textureDefinitions) {
36
+ if (def.source === imageIndex) {
37
+ def.extensions = def.extensions || {};
38
+ def.extensions[NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME] = prop.model;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return this;
44
+ }
45
+ }
46
+ export class NEEDLE_progressive_texture_property extends ExtensionProperty {
47
+ static EXTENSION_NAME = NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME;
48
+ extensionName = NEEDLE_PROGRESSIVE_TEXTURE_EXTENSION_NAME;
49
+ parentTypes = [PropertyType.TEXTURE];
50
+ propertyType = "progressive_texture";
51
+ init() { }
52
+ model;
53
+ }
@@ -0,0 +1 @@
1
+ export * from "./NEEDLE_progressive.js";
@@ -0,0 +1 @@
1
+ export * from "./NEEDLE_progressive.js";
@@ -0,0 +1,21 @@
1
+ import { Extension, ExtensionProperty, PropertyType, ReaderContext, WriterContext } from "@gltf-transform/core";
2
+ export declare interface IProgressiveTextureSettings {
3
+ maxSize: number;
4
+ guid: string;
5
+ }
6
+ export declare class NEEDLE_progressive_texture_settings extends Extension {
7
+ static EXTENSION_NAME: string;
8
+ extensionName: string;
9
+ read(context: ReaderContext): this;
10
+ write(context: WriterContext): this;
11
+ }
12
+ export declare class NEEDLE_progressive_texture_settings_property extends ExtensionProperty implements IProgressiveTextureSettings {
13
+ static EXTENSION_NAME: string;
14
+ readonly extensionName: string;
15
+ parentTypes: PropertyType[];
16
+ propertyType: string;
17
+ init(): void;
18
+ get isValid(): boolean;
19
+ maxSize: number;
20
+ guid: string;
21
+ }
@@ -0,0 +1,39 @@
1
+ import { Extension, ExtensionProperty, PropertyType } from "@gltf-transform/core";
2
+ // TODO: rename to NEEDLE_progressive_texture
3
+ const EXTENSION_NAME = "NEEDLE_progressive_texture_settings";
4
+ export class NEEDLE_progressive_texture_settings extends Extension {
5
+ static EXTENSION_NAME = EXTENSION_NAME;
6
+ extensionName = EXTENSION_NAME;
7
+ read(context) {
8
+ const textureDefinitions = context.jsonDoc.json.textures;
9
+ if (!textureDefinitions)
10
+ return this;
11
+ const root = this.document.getRoot();
12
+ const textures = root.listTextures();
13
+ for (let i = 0; i < textureDefinitions.length; i++) {
14
+ const texDef = textureDefinitions[i];
15
+ if (texDef.extensions && texDef.extensions[EXTENSION_NAME]) {
16
+ const ext = texDef.extensions[EXTENSION_NAME];
17
+ const prop = new NEEDLE_progressive_texture_settings_property(this.document.getGraph(), "");
18
+ Object.assign(prop, ext);
19
+ textures[i].setExtension(EXTENSION_NAME, prop);
20
+ }
21
+ }
22
+ return this;
23
+ }
24
+ write(context) {
25
+ return this;
26
+ }
27
+ }
28
+ export class NEEDLE_progressive_texture_settings_property extends ExtensionProperty {
29
+ static EXTENSION_NAME = EXTENSION_NAME;
30
+ extensionName = EXTENSION_NAME;
31
+ parentTypes = [PropertyType.TEXTURE];
32
+ propertyType = EXTENSION_NAME;
33
+ init() { }
34
+ get isValid() {
35
+ return this.maxSize !== undefined && this.maxSize > 0;
36
+ }
37
+ maxSize;
38
+ guid;
39
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./NEEDLE_opaque/index.js";
2
+ export * from "./NEEDLE_mesh_compression/index.js";
3
+ export * from "./NEEDLE_compression_texture/index.js";
4
+ export * from "./NEEDLE_progressive/index.js";
5
+ export * from "./NEEDLE_progressive_texture_settings/index.js";
6
+ export declare function registerExtensions(node: any): void;
@@ -0,0 +1,16 @@
1
+ // export * from "./extension.js";
2
+ export * from "./NEEDLE_opaque/index.js";
3
+ export * from "./NEEDLE_mesh_compression/index.js";
4
+ export * from "./NEEDLE_compression_texture/index.js";
5
+ export * from "./NEEDLE_progressive/index.js";
6
+ export * from "./NEEDLE_progressive_texture_settings/index.js";
7
+ import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
8
+ import { ALL_EXTENSIONS as NEEDLE_EXTENSIONS } from "./NEEDLE_opaque/index.js";
9
+ import { NEEDLE_progressive } from './NEEDLE_progressive/index.js';
10
+ export function registerExtensions(node) {
11
+ node.registerExtensions(ALL_EXTENSIONS);
12
+ node.registerExtensions(NEEDLE_EXTENSIONS);
13
+ node.registerExtensions([
14
+ NEEDLE_progressive
15
+ ]);
16
+ }
@@ -0,0 +1,6 @@
1
+ import { ReaderContext, Texture, WriterContext } from '@gltf-transform/core';
2
+ import { GLTF } from '@gltf-transform/core';
3
+ export declare function tryGetInArray<T>(arr: Array<T> | undefined | null, index: number | undefined): T | null;
4
+ export declare function writeExtension(prop: GLTF.IProperty | null, name: string, ext: any): void;
5
+ export declare function getTexture(context: ReaderContext, tex: GLTF.ITexture): Texture;
6
+ export declare function getTextureDefinition(context: WriterContext | ReaderContext, tex: Texture): GLTF.ITexture | null;
@@ -0,0 +1,72 @@
1
+ import { WriterContext } from '@gltf-transform/core';
2
+ export function tryGetInArray(arr, index) {
3
+ if (index === undefined)
4
+ return null;
5
+ if (Array.isArray(arr) && arr.length > index) {
6
+ return arr[index];
7
+ }
8
+ return null;
9
+ }
10
+ export function writeExtension(prop, name, ext) {
11
+ if (prop === null)
12
+ return;
13
+ if (ext) {
14
+ if (!prop.extensions) {
15
+ prop.extensions = {};
16
+ }
17
+ prop.extensions[name] = ext;
18
+ }
19
+ }
20
+ // Texture index in context.textures
21
+ export function getTexture(context, tex) {
22
+ if (!context.jsonDoc.json.images)
23
+ return null;
24
+ if (tex.source !== undefined) {
25
+ return context.textures[tex.source];
26
+ }
27
+ else {
28
+ for (const key of Object.keys(tex.extensions)) {
29
+ const ext = tex.extensions[key];
30
+ if (ext && typeof ext["source"] === "number") {
31
+ return context.textures[ext["source"]];
32
+ }
33
+ }
34
+ }
35
+ console.log("Could not fnd texture", tex);
36
+ return null;
37
+ }
38
+ export function getTextureDefinition(context, tex) {
39
+ const textureDefinitions = context.jsonDoc.json.textures;
40
+ if (!textureDefinitions)
41
+ return null;
42
+ if (context instanceof WriterContext) {
43
+ // we use the texture image map to find the texture definition to write the extension to
44
+ const textureImageIndexMap = context.imageIndexMap;
45
+ // get the image this texture is using
46
+ const imageIndex = textureImageIndexMap.get(tex);
47
+ // find the texture definition that uses this image and add the extension
48
+ for (const def of textureDefinitions) {
49
+ if (def.source === imageIndex) {
50
+ return def;
51
+ }
52
+ }
53
+ }
54
+ else {
55
+ const textureIndex = context.textures.indexOf(tex);
56
+ for (let i = 0; i < textureDefinitions.length; i++) {
57
+ const textureDef = textureDefinitions[i];
58
+ if (textureDef.source === textureIndex) {
59
+ return textureDef;
60
+ }
61
+ else if (textureDef.extensions) {
62
+ for (const key of Object.keys(textureDef.extensions)) {
63
+ const ext = textureDef.extensions[key];
64
+ if (ext && ext["source"] === textureIndex) {
65
+ return textureDef;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ return null;
72
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ export {};
2
+ // TODO: remove once this is resolved: https://github.com/donmccurdy/glTF-Transform/issues/855
3
+ // modified to take a document as a parameter
4
+ // export function listTextureSlots(texture: Texture, document: Document): string[] {
5
+ // const root = document.getRoot();
6
+ // const slots = texture
7
+ // .getGraph()
8
+ // .listParentEdges(texture)
9
+ // .filter((edge) => edge.getParent() !== root)
10
+ // .map((edge) => edge.getName());
11
+ // return Array.from(new Set(slots));
12
+ // }
13
+ // export function getTextureChannelMask(texture: Texture, document: Document): number {
14
+ // let mask = 0x0000;
15
+ // for (const edge of document.getGraph().listParentEdges(texture)) {
16
+ // const parent = edge.getParent();
17
+ // let { channels } = edge.getAttributes() as { channels: number | undefined };
18
+ // if (
19
+ // channels &&
20
+ // edge.getName() === 'baseColorTexture' &&
21
+ // parent instanceof Material &&
22
+ // parent.getAlphaMode() === Material.AlphaMode.OPAQUE
23
+ // ) {
24
+ // channels &= ~TextureChannel.A;
25
+ // }
26
+ // if (channels) {
27
+ // mask |= channels;
28
+ // continue;
29
+ // }
30
+ // if (parent.propertyType !== PropertyType.ROOT) {
31
+ // document.getLogger().warn(`Missing attribute ".channels" on edge, "${edge.getName()}".`);
32
+ // }
33
+ // }
34
+ // return mask;
35
+ // }
@@ -0,0 +1,3 @@
1
+ export * from "./utils/index.js";
2
+ export * from "./transforms/index.js";
3
+ export * from "./extensions/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./utils/index.js";
2
+ export * from "./transforms/index.js";
3
+ export * from "./extensions/index.js";
@@ -0,0 +1,9 @@
1
+ export * from "./needle_asset.js";
2
+ export * from "./toktx.js";
3
+ export * from "./needle_toktx.js";
4
+ export * from "./needle_progressive.js";
5
+ export * from "./needle_webp.js";
6
+ export * from "./needle_mesh_transform.js";
7
+ export * from "./needle_common.js";
8
+ export * from "./needle_texture_transform.js";
9
+ export * from "./needle_animation_transform.js";
@@ -0,0 +1,9 @@
1
+ export * from "./needle_asset.js";
2
+ export * from "./toktx.js";
3
+ export * from "./needle_toktx.js";
4
+ export * from "./needle_progressive.js";
5
+ export * from "./needle_webp.js";
6
+ export * from "./needle_mesh_transform.js";
7
+ export * from "./needle_common.js";
8
+ export * from "./needle_texture_transform.js";
9
+ export * from "./needle_animation_transform.js";
@@ -0,0 +1,2 @@
1
+ import { Transform } from "@gltf-transform/core";
2
+ export declare const needle_animation_transform: (_options: any) => Transform;
@@ -0,0 +1,5 @@
1
+ export const needle_animation_transform = function (_options) {
2
+ // return resample();
3
+ return (document, _context) => {
4
+ };
5
+ };
@@ -0,0 +1,2 @@
1
+ import { Transform } from '@gltf-transform/core';
2
+ export declare function needle_asset(): Transform;
@@ -0,0 +1,28 @@
1
+ import { createTransform } from '@gltf-transform/functions';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ let version = undefined;
4
+ export function needle_asset() {
5
+ return createTransform("needle_asset_transform", (document) => {
6
+ const root = document.getRoot();
7
+ const asset = root.getAsset();
8
+ if (asset) {
9
+ if (version === undefined) {
10
+ version = null;
11
+ const path = process.cwd() + "/package.json";
12
+ if (existsSync(path)) {
13
+ const packageJson = readFileSync(path, "utf8");
14
+ const packageVersion = JSON.parse(packageJson).version;
15
+ version = packageVersion ?? null;
16
+ }
17
+ else
18
+ console.log("Could not find package.json at " + path);
19
+ }
20
+ if (!asset.generator.startsWith("Needle glTF Build Pipeline")) {
21
+ asset.generator = "Needle glTF Build Pipeline";
22
+ if (version?.length > 0) {
23
+ asset.generator += " " + version;
24
+ }
25
+ }
26
+ }
27
+ });
28
+ }
@@ -0,0 +1,11 @@
1
+ import { Document, Texture } from '@gltf-transform/core';
2
+ import { NEEDLE_compression_texture_schema } from '../extensions/index.js';
3
+ export interface NeedleTransformContext {
4
+ useCache: boolean;
5
+ noToktx: boolean;
6
+ }
7
+ export interface INeedleTextureTransformContext {
8
+ prepare(document: Document): Promise<void>;
9
+ process(index: number, texture: Texture, settings: NEEDLE_compression_texture_schema): Promise<boolean>;
10
+ finalize(document: Document): Promise<void>;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { Transform } from "@gltf-transform/core";
2
+ import { SimplifyOptions } from "@gltf-transform/functions";
3
+ export declare const needle_mesh_transform: (_options: SimplifyOptions) => Transform;
@@ -0,0 +1,83 @@
1
+ import { Primitive } from "@gltf-transform/core";
2
+ import { simplifyPrimitive, SIMPLIFY_DEFAULTS, weldPrimitive, WELD_DEFAULTS } from "@gltf-transform/functions";
3
+ import { MeshoptSimplifier } from "meshoptimizer";
4
+ import { NEEDLE_mesh_compression } from "../extensions/index.js";
5
+ const NAME = 'needle_simplify';
6
+ export const needle_mesh_transform = function (_options) {
7
+ const simplifier = MeshoptSimplifier;
8
+ if (!simplifier) {
9
+ throw new Error(`${NAME}: simplifier dependency required — install "meshoptimizer".`);
10
+ }
11
+ return (document, _context) => {
12
+ const logger = document.getLogger();
13
+ const options = { ...SIMPLIFY_DEFAULTS, ..._options };
14
+ const weldOptions = {
15
+ ...WELD_DEFAULTS,
16
+ tolerance: 0.00000000001,
17
+ overwrite: true,
18
+ };
19
+ for (const mesh of document.getRoot().listMeshes()) {
20
+ for (const prim of mesh.listPrimitives()) {
21
+ // TODO: mesh compression caching
22
+ // const key = getKey(prim);
23
+ // const cached = tryGetFromCache(key);
24
+ // if (cached) {
25
+ // logger.debug(`${NAME}: Skipping primitive of mesh "${mesh.getName()}": Already cached.`);
26
+ // continue;
27
+ // }
28
+ // updatePrimitive(prim, simplifier, null, prim.getIndices());
29
+ // continue;
30
+ const ext = prim.getExtension(NEEDLE_mesh_compression.EXTENSION_NAME);
31
+ const mesh_compression = ext?.model;
32
+ const simplifyOpts = { ...options };
33
+ if (!ext) {
34
+ // If no extension exists on the primitive dont apply any simplification
35
+ continue;
36
+ }
37
+ if (mesh_compression) {
38
+ // Dont run if useSimplifier is turned off explictly
39
+ if (mesh_compression.useSimplifier === false) {
40
+ logger.debug(`${NAME}: Skipping primitive of mesh "${mesh.getName()}": useSimplifier is false.`);
41
+ continue;
42
+ }
43
+ if (mesh_compression.error >= 0)
44
+ simplifyOpts.error = mesh_compression.error;
45
+ if (mesh_compression.ratio >= 0)
46
+ simplifyOpts.ratio = mesh_compression.ratio;
47
+ simplifyOpts.lockBorder = mesh_compression.lockBorder;
48
+ }
49
+ if (prim.getMode() !== Primitive.Mode.TRIANGLES) {
50
+ logger.warn(`${NAME}: Skipping primitive of mesh "${mesh.getName()}": Requires TRIANGLES draw mode.`);
51
+ continue;
52
+ }
53
+ compressPrimitive(document, mesh, prim, weldOptions, simplifyOpts);
54
+ }
55
+ }
56
+ };
57
+ };
58
+ function compressPrimitive(document, mesh, prim, weldOptions, meshOptions) {
59
+ const logger = document.getLogger();
60
+ logger.debug(`${NAME}: Welding primitive of mesh "${mesh.getName()}" → tolerance: ${weldOptions.tolerance}`);
61
+ weldPrimitive(document, prim, weldOptions);
62
+ logger.debug(`${NAME}: Simplifying primitive of mesh "${mesh.getName()}" → ratio: ${meshOptions.ratio}, error: ${meshOptions.error}, lockBorder: ${meshOptions.lockBorder}`);
63
+ simplifyPrimitive(document, prim, meshOptions);
64
+ }
65
+ // function updatePrimitive(prim: Primitive, simplifier: any, positionArray, dstIndicesArray) {
66
+ // const position = prim.getAttribute('POSITION')!;
67
+ // const srcIndices = prim.getIndices()!;
68
+ // const srcVertexCount = position.getCount();
69
+ // const [remap, unique] = simplifier.compactMesh(dstIndicesArray);
70
+ // // logger.debug(`${NAME}: ${formatDeltaOp(position.getCount(), unique)} vertices, error: ${error.toFixed(4)}.`);
71
+ // // (3) Write vertex attributes.
72
+ // for (const srcAttribute of deepListAttributes(prim)) {
73
+ // const dstAttribute = srcAttribute.clone();
74
+ // remapAttribute(dstAttribute, remap, unique);
75
+ // deepSwapAttribute(prim, srcAttribute, dstAttribute);
76
+ // if (srcAttribute.listParents().length === 1) srcAttribute.dispose();
77
+ // }
78
+ // // (4) Write indices.
79
+ // const dstIndices = srcIndices.clone();
80
+ // dstIndices.setArray(srcVertexCount <= 65534 ? new Uint16Array(dstIndicesArray) : dstIndicesArray);
81
+ // prim.setIndices(dstIndices);
82
+ // if (srcIndices.listParents().length === 1) srcIndices.dispose();
83
+ // }
@@ -0,0 +1,34 @@
1
+ import { ILogger, Texture, Transform, vec2 } from '@gltf-transform/core';
2
+ declare interface ProgressiveOptions {
3
+ path: string | Array<string>;
4
+ debug?: boolean;
5
+ useCache?: boolean;
6
+ }
7
+ export declare function make_progressive(opts: ProgressiveOptions): Promise<void>;
8
+ export declare function createTransform(name: string, fn: Transform): Transform;
9
+ export declare function make_progressive_textures(filePath: string, _options?: TextureResizeOptions, opts?: ProgressiveOptions): Transform;
10
+ /** Options for the {@link textureResize} function. */
11
+ export interface TextureResizeOptions {
12
+ /**
13
+ * Maximum width/height to enforce, preserving aspect ratio. For example,
14
+ * a 4096x8192 texture, resized with limit [2048, 2048] will be reduced
15
+ * to 1024x2048.
16
+ */
17
+ size: vec2;
18
+ /** Resampling filter method. LANCZOS3 is sharper, LANCZOS2 is smoother. */
19
+ filter?: TextureResizeFilter;
20
+ /** Pattern identifying textures to resize, matched to name or URI. */
21
+ pattern?: RegExp | null;
22
+ /** Pattern to match slots usage for resizing. */
23
+ slots?: RegExp | null;
24
+ }
25
+ /** Resampling filter methods. LANCZOS3 is sharper, LANCZOS2 is smoother. */
26
+ export declare enum TextureResizeFilter {
27
+ /** Lanczos3 (sharp) */
28
+ LANCZOS3 = "lanczos3",
29
+ /** Lanczos2 (smooth) */
30
+ LANCZOS2 = "lanczos2"
31
+ }
32
+ export declare const TEXTURE_RESIZE_DEFAULTS: TextureResizeOptions;
33
+ export declare function resizeTextureToMax(texture: Texture, maxSize: number, logger: ILogger): Promise<void>;
34
+ export {};