@needle-tools/gltf-build-pipeline 1.5.0-alpha.6 → 1.5.0-alpha.8

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 CHANGED
@@ -4,8 +4,16 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.5.0-alpha.8] - 2023-05-16
8
+ - fix: issue where updating ktx compressed texture extension also flattened the path
9
+
10
+ ## [1.5.0-alpha.7] - 2023-05-16
11
+ - fix: external resources that are KTX2 compressed are now saved with a `.ktx2` extension
12
+ - change: toktx now uses compression "auto" mode to select uastc or etc1s
13
+ - change: toktx now checks the slots and increases quality for `metallicRoughnessTexture` and `normalTexture` but keeps using ETC1S for smaller file size
14
+
7
15
  ## [1.5.0-alpha.6] - 2023-05-15
8
- - fix: If not further specified then automatically use UASTC for textures that are in either `normalTexture` or `metallicOcclusionTexture` slots
16
+ - fix: If not further specified then automatically use UASTC for textures that are in either `normalTexture` or `metallicRoughnessTexture` slots
9
17
 
10
18
  ## [1.5.0-alpha.5] - 2023-05-04
11
19
  - fix: NEEDLE_opaque should handle if VRM texture index is negative
@@ -1,6 +1,7 @@
1
1
  import { Document, Texture } from '@gltf-transform/core';
2
2
  import { NEEDLE_compression_texture_schema } from '../extensions/index.js';
3
3
  export interface NeedleTransformContext {
4
+ /** full path to the file being processed */
4
5
  file: string;
5
6
  debug?: boolean;
6
7
  useCache: boolean;
@@ -5,6 +5,8 @@ import { addToCache, getKey, tryGetFromCache } from "../cache/index.js";
5
5
  import { NeedleWebPContext } from "./needle_webp.js";
6
6
  import { NeedleToktxContext } from "./needle_toktx.js";
7
7
  import { createTransform } from "@gltf-transform/functions";
8
+ import { dirname } from "path";
9
+ import { existsSync, rmSync } from "fs";
8
10
  export async function resizeTextureIfNecessary(texture) {
9
11
  const ext = texture.getExtension(NEEDLE_compression_texture.EXTENSION_NAME);
10
12
  if (ext?.model) {
@@ -96,6 +98,7 @@ async function processTexture(texture, index, document, logger, context) {
96
98
  }
97
99
  let successFullyProcessed = false;
98
100
  const canRunToktx = context.noToktx !== true;
101
+ const originalUri = texture.getURI();
99
102
  if (compressionSettings && compressionSettings.mode !== "auto") {
100
103
  switch (compressionSettings.mode) {
101
104
  case "webp":
@@ -167,4 +170,15 @@ async function processTexture(texture, index, document, logger, context) {
167
170
  if (data)
168
171
  addToCache(key, data);
169
172
  }
173
+ if (successFullyProcessed) {
174
+ const newUri = texture.getURI();
175
+ if (originalUri && originalUri != newUri) {
176
+ const fileDirectory = dirname(context.file);
177
+ const originalPath = fileDirectory + "/" + originalUri;
178
+ if (existsSync(originalPath)) {
179
+ console.log(`INFO: Texture moved \"${originalUri}\" → \"${newUri}\"`);
180
+ rmSync(originalPath);
181
+ }
182
+ }
183
+ }
170
184
  }
@@ -8,6 +8,7 @@ import fs from 'fs/promises';
8
8
  import os from 'os';
9
9
  import tmp from 'tmp';
10
10
  import pLimit from 'p-limit';
11
+ import { replaceExtension } from "../utils/fileutils.js";
11
12
  const NUM_CPUS = os.cpus().length || 1; // microsoft/vscode#112122
12
13
  let didLogEnvironmentInfo = false;
13
14
  export class NeedleToktxContext {
@@ -114,16 +115,29 @@ export class NeedleToktxContext {
114
115
  // const inBytes = image.byteLength;
115
116
  await fs.writeFile(inPath, Buffer.from(image));
116
117
  let mode = Mode.ETC1S;
118
+ let quality = 128;
119
+ let compression = 1;
117
120
  if (settings) {
118
- mode = settings.mode === "ETC1S" ? Mode.ETC1S : Mode.UASTC;
121
+ if (settings.mode === "auto") {
122
+ const useUASTC = slots.includes("normalTexture") || slots.includes("metallicRoughnessTexture");
123
+ mode = useUASTC ? Mode.UASTC : Mode.ETC1S;
124
+ }
125
+ else {
126
+ mode = settings.mode === "ETC1S" ? Mode.ETC1S : Mode.UASTC;
127
+ }
119
128
  }
120
129
  else if (slots) {
121
- const useUASTC = slots.includes("normalTexture") || slots.includes("metallicRoughnessTexture");
122
- mode = useUASTC ? Mode.UASTC : Mode.ETC1S;
130
+ const betterQuality = slots.includes("normalTexture") || slots.includes("metallicRoughnessTexture");
131
+ // mode = useUASTC ? Mode.UASTC : Mode.ETC1S;
132
+ mode = Mode.ETC1S;
133
+ // https://github.khronos.org/KTX-Software/ktxtools/toktx.html
134
+ quality = betterQuality ? 255 : 128;
135
+ // ETC1S / BasisLZ compression level, an encoding speed vs. quality tradeoff. Range is [0,5], default is 1. Higher values are slower but give higher quality.
136
+ compression = betterQuality ? 4 : 1;
123
137
  }
124
138
  const defaults = mode === Mode.ETC1S ? ETC1S_DEFAULTS : UASTC_DEFAULTS;
125
139
  //@ts-ignore
126
- const toktxParams = createParams(slots, channels, size, logger, this.numTextures, { ...defaults, mode }, this.version);
140
+ const toktxParams = createParams(slots, channels, size, logger, this.numTextures, { ...defaults, mode, quality, compression }, this.version);
127
141
  const params = [
128
142
  ...toktxParams,
129
143
  outPath,
@@ -141,6 +155,13 @@ export class NeedleToktxContext {
141
155
  else {
142
156
  const result = await fs.readFile(outPath);
143
157
  texture.setImage(result).setMimeType('image/ktx2');
158
+ // TODO: we also need to remove the old file when the extension has changed - this should probably be done outside of this method to also support webp
159
+ // If this is a texture that was loaded from a file, we need to update the URI
160
+ if (texture.getURI()) {
161
+ const oldUri = texture.getURI();
162
+ const newUri = replaceExtension(oldUri, 'ktx2');
163
+ texture.setURI(newUri);
164
+ }
144
165
  return true;
145
166
  }
146
167
  }
@@ -1,2 +1,3 @@
1
1
  export declare type GLTFFileCallback = (file: string) => void | Promise<void>;
2
2
  export declare function foreachGLTF(args: string | string[], callback: GLTFFileCallback): Promise<void>;
3
+ export declare function replaceExtension(filepath: string, newExtension: string): string;
@@ -113,3 +113,8 @@ async function testEntry(entry, callback, context) {
113
113
  }
114
114
  }
115
115
  }
116
+ export function replaceExtension(filepath, newExtension) {
117
+ const parts = filepath.split(".");
118
+ parts.pop();
119
+ return parts.join(".") + "." + newExtension;
120
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-build-pipeline",
3
- "version": "1.5.0-alpha.6",
3
+ "version": "1.5.0-alpha.8",
4
4
  "description": "Pipeline and tools for optimizing gltf files using gltf-transform and compression settings within glTF extensions",
5
5
  "main": "index.mjs",
6
6
  "type": "module",