@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.
- package/CHANGELOG.md +140 -0
- package/clear-caches.mjs +4 -0
- package/defaults.mjs +12 -0
- package/dist/cache/cache.d.ts +5 -0
- package/dist/cache/cache.js +82 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +1 -0
- package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.d.ts +24 -0
- package/dist/extensions/NEEDLE_compression_texture/NEEDLE_compression_texture.js +54 -0
- package/dist/extensions/NEEDLE_compression_texture/index.d.ts +1 -0
- package/dist/extensions/NEEDLE_compression_texture/index.js +1 -0
- package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.d.ts +23 -0
- package/dist/extensions/NEEDLE_mesh_compression/NEEDLE_mesh_compression.js +43 -0
- package/dist/extensions/NEEDLE_mesh_compression/index.d.ts +1 -0
- package/dist/extensions/NEEDLE_mesh_compression/index.js +1 -0
- package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.d.ts +20 -0
- package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.js +699 -0
- package/dist/extensions/NEEDLE_opaque/index.d.ts +3 -0
- package/dist/extensions/NEEDLE_opaque/index.js +18 -0
- package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.d.ts +23 -0
- package/dist/extensions/NEEDLE_progressive/NEEDLE_progressive.js +53 -0
- package/dist/extensions/NEEDLE_progressive/index.d.ts +1 -0
- package/dist/extensions/NEEDLE_progressive/index.js +1 -0
- package/dist/extensions/NEEDLE_progressive_texture_settings/index.d.ts +21 -0
- package/dist/extensions/NEEDLE_progressive_texture_settings/index.js +39 -0
- package/dist/extensions/index.d.ts +6 -0
- package/dist/extensions/index.js +16 -0
- package/dist/extensions/utils.d.ts +6 -0
- package/dist/extensions/utils.js +72 -0
- package/dist/functions/list-texture-slots.d.ts +1 -0
- package/dist/functions/list-texture-slots.js +35 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/transforms/index.d.ts +9 -0
- package/dist/transforms/index.js +9 -0
- package/dist/transforms/needle_animation_transform.d.ts +2 -0
- package/dist/transforms/needle_animation_transform.js +5 -0
- package/dist/transforms/needle_asset.d.ts +2 -0
- package/dist/transforms/needle_asset.js +28 -0
- package/dist/transforms/needle_common.d.ts +11 -0
- package/dist/transforms/needle_common.js +1 -0
- package/dist/transforms/needle_mesh_transform.d.ts +3 -0
- package/dist/transforms/needle_mesh_transform.js +83 -0
- package/dist/transforms/needle_progressive.d.ts +34 -0
- package/dist/transforms/needle_progressive.js +264 -0
- package/dist/transforms/needle_simplify.d.ts +3 -0
- package/dist/transforms/needle_simplify.js +76 -0
- package/dist/transforms/needle_texture_transform.d.ts +5 -0
- package/dist/transforms/needle_texture_transform.js +123 -0
- package/dist/transforms/needle_toktx.d.ts +24 -0
- package/dist/transforms/needle_toktx.js +144 -0
- package/dist/transforms/needle_webp.d.ts +13 -0
- package/dist/transforms/needle_webp.js +53 -0
- package/dist/transforms/toktx.d.ts +77 -0
- package/dist/transforms/toktx.js +230 -0
- package/dist/transforms/types/squoosh.d.ts +31 -0
- package/dist/transforms/types/squoosh.js +33 -0
- package/dist/transforms/util.d.ts +21 -0
- package/dist/transforms/util.js +90 -0
- package/dist/utils/fileutils.d.ts +2 -0
- package/dist/utils/fileutils.js +95 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/fileutils.mjs +6 -0
- package/index.mjs +33 -0
- package/make-progressive.mjs +11 -0
- package/pack-gltf.mjs +119 -0
- package/package.json +60 -0
- package/tsconfig.json +15 -0
|
@@ -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
|
+
// }
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -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,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,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 {};
|