From fbbc5ca65e5b4d69b75e6ac2c5785e13db26aafe Mon Sep 17 00:00:00 2001 From: Don McCurdy Date: Tue, 19 Dec 2023 20:45:24 -0500 Subject: [PATCH] v4: Remove deprecated APIs (#1211) --- packages/cli/src/cli.ts | 3 +- packages/core/src/index.ts | 1 - packages/core/src/properties/material.ts | 35 ------ packages/core/src/properties/node.ts | 16 +-- packages/core/src/utils/get-bounds.ts | 6 - packages/core/src/utils/math-utils.ts | 10 -- .../core/test/properties/material.test.ts | 9 -- .../src/khr-lights-punctual/light.ts | 19 --- .../pbr-specular-glossiness.ts | 18 --- .../src/khr-materials-sheen/sheen.ts | 18 --- .../src/khr-materials-specular/specular.ts | 18 --- .../khr-materials-volume/materials-volume.ts | 2 +- .../src/khr-materials-volume/volume.ts | 20 ---- .../extensions/test/lights-punctual.test.ts | 7 -- .../materials-pbr-specular-glossiness.test.ts | 11 +- .../extensions/test/materials-sheen.test.ts | 9 +- .../test/materials-specular.test.ts | 9 +- .../extensions/test/materials-volume.test.ts | 5 +- packages/functions/src/get-node-scene.ts | 7 -- packages/functions/src/index.ts | 2 - packages/functions/src/texture-compress.ts | 9 +- packages/functions/src/texture-resize.ts | 110 ------------------ packages/functions/src/vertex-color-space.ts | 11 +- packages/functions/src/weld.ts | 34 ++---- packages/functions/test/dedup.test.ts | 16 ++- .../functions/test/get-node-scene.test.ts | 22 ---- packages/functions/test/palette.test.ts | 44 +++++-- .../functions/test/texture-resize.test.ts | 52 --------- 28 files changed, 76 insertions(+), 447 deletions(-) delete mode 100644 packages/functions/src/get-node-scene.ts delete mode 100644 packages/functions/src/texture-resize.ts delete mode 100644 packages/functions/test/get-node-scene.test.ts delete mode 100644 packages/functions/test/texture-resize.test.ts diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index b120014d9..3e1a2ba50 100755 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -15,7 +15,6 @@ import { QUANTIZE_DEFAULTS, ResampleOptions, SequenceOptions, - TEXTURE_RESIZE_DEFAULTS, TextureResizeFilter, UnweldOptions, WeldOptions, @@ -1157,7 +1156,7 @@ preserving original aspect ratio. Texture dimensions are never increased. }) .option('--filter', 'Resampling filter', { validator: [TextureResizeFilter.LANCZOS3, TextureResizeFilter.LANCZOS2], - default: TEXTURE_RESIZE_DEFAULTS.filter, + default: TextureResizeFilter.LANCZOS3, }) .option('--width ', 'Maximum width (px) of output textures.', { validator: Validator.NUMBER, diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 7b98ed8ef..1329750d8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -38,7 +38,6 @@ export { MathUtils, Verbosity, getBounds, - bounds, uuid, } from './utils/index.js'; export { diff --git a/packages/core/src/properties/material.ts b/packages/core/src/properties/material.ts index 3a3a86ab2..68f1f3c7b 100644 --- a/packages/core/src/properties/material.ts +++ b/packages/core/src/properties/material.ts @@ -1,6 +1,5 @@ import { Nullable, PropertyType, TextureChannel, vec3, vec4 } from '../constants.js'; import type { GLTF } from '../types/gltf.js'; -import { ColorUtils } from '../utils/index.js'; import { ExtensibleProperty, IExtensibleProperty } from './extensible-property.js'; import type { Texture } from './texture.js'; import { TextureInfo } from './texture-info.js'; @@ -206,23 +205,6 @@ export class Material extends ExtensibleProperty { return this.set('baseColorFactor', baseColorFactor); } - /** - * Base color / albedo; sRGB hexadecimal color. See {@link Material.getBaseColorTexture getBaseColorTexture}. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getBaseColorHex(): number { - return ColorUtils.factorToHex(this.get('baseColorFactor')); - } - - /** - * Base color / albedo; sRGB hexadecimal color. See {@link Material.getBaseColorTexture getBaseColorTexture}. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setBaseColorHex(hex: number): this { - const factor = this.get('baseColorFactor').slice() as vec4; - return this.set('baseColorFactor', ColorUtils.hexToFactor(hex, factor)); - } - /** * Base color / albedo. The visible color of a non-metallic surface under constant ambient * light would be a linear combination (multiplication) of its vertex colors, base color @@ -264,23 +246,6 @@ export class Material extends ExtensibleProperty { return this.set('emissiveFactor', emissiveFactor); } - /** - * Emissive; sRGB hexadecimal color. See {@link Material.getBaseColorTexture getBaseColorTexture}. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getEmissiveHex(): number { - return ColorUtils.factorToHex(this.get('emissiveFactor')); - } - - /** - * Emissive; sRGB hexadecimal color. See {@link Material.getEmissiveTexture getEmissiveTexture}. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setEmissiveHex(hex: number): this { - const factor = this.get('emissiveFactor').slice() as vec3; - return this.set('emissiveFactor', ColorUtils.hexToFactor(hex, factor)); - } - /** * Emissive texture. Emissive color is added to any base color of the material, after any * lighting/shadowing are applied. An emissive color does not inherently "glow", or affect diff --git a/packages/core/src/properties/node.ts b/packages/core/src/properties/node.ts index 4cce56b6a..f57b2dea5 100644 --- a/packages/core/src/properties/node.ts +++ b/packages/core/src/properties/node.ts @@ -126,7 +126,7 @@ export class Node extends ExtensibleProperty { this.get('translation'), this.get('rotation'), this.get('scale'), - [] as unknown as mat4 + [] as unknown as mat4, ); } @@ -233,13 +233,6 @@ export class Node extends ExtensibleProperty { return this.listRefs('children'); } - /** @deprecated Use {@link Node.getParentNode} and {@link listNodeScenes} instead. */ - public getParent(): SceneNode | null { - if (this._parentNode) return this._parentNode; - const scene = this.listParents().find((parent) => parent.propertyType === PropertyType.SCENE); - return (scene as unknown as SceneNode) || null; - } - /** * Returns the Node's unique parent Node within the scene graph. If the * Node has no parents, or is a direct child of the {@link Scene} @@ -316,10 +309,3 @@ export class Node extends ExtensibleProperty { return this; } } - -interface SceneNode { - propertyType: PropertyType; - _parent?: SceneNode | null; - addChild(node: Node): this; - removeChild(node: Node): this; -} diff --git a/packages/core/src/utils/get-bounds.ts b/packages/core/src/utils/get-bounds.ts index 75550571c..4132a544d 100644 --- a/packages/core/src/utils/get-bounds.ts +++ b/packages/core/src/utils/get-bounds.ts @@ -30,12 +30,6 @@ export function getBounds(node: Node | Scene): bbox { return resultBounds; } -/** - * @deprecated Renamed to {@link getBounds}. - * @hidden - */ -export const bounds = getBounds; - /** Computes mesh bounds in local space. */ function getMeshBounds(mesh: Mesh, worldMatrix: mat4): bbox { const meshBounds = createBounds(); diff --git a/packages/core/src/utils/math-utils.ts b/packages/core/src/utils/math-utils.ts index 3670fdf70..a5d69abee 100644 --- a/packages/core/src/utils/math-utils.ts +++ b/packages/core/src/utils/math-utils.ts @@ -38,11 +38,6 @@ export class MathUtils { } } - /** @deprecated Renamed to {@link MathUtils.decodeNormalizedInt}. */ - public static denormalize(i: number, componentType: GLTF.AccessorComponentType): number { - return MathUtils.decodeNormalizedInt(i, componentType); - } - // TODO(v4): Compare performance if we replace the switch with individual functions. // TODO(v4): Consider clamping to [0, 1] or [-1, 1] here. public static encodeNormalizedInt(f: number, componentType: GLTF.AccessorComponentType): number { @@ -63,11 +58,6 @@ export class MathUtils { } } - /** @deprecated Renamed to {@link MathUtils.encodeNormalizedInt}. */ - public static normalize(f: number, componentType: GLTF.AccessorComponentType): number { - return MathUtils.encodeNormalizedInt(f, componentType); - } - /** * Decompose a mat4 to TRS properties. * diff --git a/packages/core/test/properties/material.test.ts b/packages/core/test/properties/material.test.ts index d6569f6ec..7f97caa69 100644 --- a/packages/core/test/properties/material.test.ts +++ b/packages/core/test/properties/material.test.ts @@ -30,15 +30,6 @@ test('factors', (t) => { t.is(mat.getRoughnessFactor(), 0.9, 'roughnessFactor'); }); -test('hex', (t) => { - const document = new Document(); - - const mat = document.createMaterial('mat').setAlpha(0.9).setBaseColorHex(0x00ff00); - - t.is(mat.getAlpha(), 0.9, 'alpha'); - t.is(mat.getBaseColorHex(), 65024, 'baseColorHex'); -}); - test('textures', (t) => { const document = new Document(); diff --git a/packages/extensions/src/khr-lights-punctual/light.ts b/packages/extensions/src/khr-lights-punctual/light.ts index 5ea68a66b..eb4edd7c5 100644 --- a/packages/extensions/src/khr-lights-punctual/light.ts +++ b/packages/extensions/src/khr-lights-punctual/light.ts @@ -1,5 +1,4 @@ import { ExtensionProperty, IProperty, Nullable, PropertyType, vec3 } from '@gltf-transform/core'; -import { ColorUtils } from '@gltf-transform/core'; import { KHR_LIGHTS_PUNCTUAL } from '../constants.js'; interface ILight extends IProperty { @@ -67,24 +66,6 @@ export class Light extends ExtensionProperty { return this.set('color', color); } - /** - * Light color; sRGB hexadecimal color. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getColorHex(): number { - return ColorUtils.factorToHex(this.getColor()); - } - - /** - * Light color; sRGB hexadecimal color. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setColorHex(hex: number): this { - const color = this.getColor().slice() as vec3; - ColorUtils.hexToFactor(hex, color); - return this.setColor(color); - } - /********************************************************************************************** * INTENSITY. */ diff --git a/packages/extensions/src/khr-materials-pbr-specular-glossiness/pbr-specular-glossiness.ts b/packages/extensions/src/khr-materials-pbr-specular-glossiness/pbr-specular-glossiness.ts index b2c953cae..c397dd0a2 100644 --- a/packages/extensions/src/khr-materials-pbr-specular-glossiness/pbr-specular-glossiness.ts +++ b/packages/extensions/src/khr-materials-pbr-specular-glossiness/pbr-specular-glossiness.ts @@ -1,5 +1,4 @@ import { - ColorUtils, ExtensionProperty, IProperty, Nullable, @@ -65,23 +64,6 @@ export class PBRSpecularGlossiness extends ExtensionProperty { return this.get('sheenColorFactor'); } - /** - * Sheen; hex color in sRGB colorspace. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getSheenColorHex(): number { - return ColorUtils.factorToHex(this.getSheenColorFactor()); - } - /** Sheen; linear multiplier. */ public setSheenColorFactor(factor: vec3): this { return this.set('sheenColorFactor', factor); } - /** - * Sheen; hex color in sRGB colorspace. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setSheenColorHex(hex: number): this { - const factor = this.getSheenColorFactor().slice() as vec3; - return this.set('sheenColorFactor', ColorUtils.hexToFactor(hex, factor)); - } - /** * Sheen color texture, in sRGB colorspace. */ diff --git a/packages/extensions/src/khr-materials-specular/specular.ts b/packages/extensions/src/khr-materials-specular/specular.ts index 2e3e13a3d..00ca9fc8e 100644 --- a/packages/extensions/src/khr-materials-specular/specular.ts +++ b/packages/extensions/src/khr-materials-specular/specular.ts @@ -1,5 +1,4 @@ import { - ColorUtils, ExtensionProperty, IProperty, Nullable, @@ -72,23 +71,6 @@ export class Specular extends ExtensionProperty { return this.set('specularColorFactor', factor); } - /** - * Specular color; sRGB hexadecimal color. See {@link Specular.getSpecularTexture getSpecularTexture} - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getSpecularColorHex(): number { - return ColorUtils.factorToHex(this.getSpecularColorFactor()); - } - - /** - * Specular color; sRGB hexadecimal color. See {@link Specular.getSpecularTexture getSpecularTexture} - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setSpecularColorHex(hex: number): this { - const factor = this.getSpecularColorFactor().slice() as vec3; - return this.set('specularColorFactor', ColorUtils.hexToFactor(hex, factor)); - } - /** * Specular texture; linear multiplier. Configures the strength of the specular reflection in * the dielectric BRDF. A value of zero disables the specular reflection, resulting in a pure diff --git a/packages/extensions/src/khr-materials-volume/materials-volume.ts b/packages/extensions/src/khr-materials-volume/materials-volume.ts index d7ea8687e..e452045f1 100644 --- a/packages/extensions/src/khr-materials-volume/materials-volume.ts +++ b/packages/extensions/src/khr-materials-volume/materials-volume.ts @@ -54,7 +54,7 @@ interface VolumeDef { * .setThicknessFactor(1.0) * .setThicknessTexture(texture) * .setAttenuationDistance(1.0) - * .setAttenuationColorHex(0xFFEEEE); + * .setAttenuationColorFactor([1, 0.5, 0.5]); * * // Attach the property to a Material. * material.setExtension('KHR_materials_volume', volume); diff --git a/packages/extensions/src/khr-materials-volume/volume.ts b/packages/extensions/src/khr-materials-volume/volume.ts index 6daff6188..2998db8e3 100644 --- a/packages/extensions/src/khr-materials-volume/volume.ts +++ b/packages/extensions/src/khr-materials-volume/volume.ts @@ -1,5 +1,4 @@ import { - ColorUtils, ExtensionProperty, IProperty, Nullable, @@ -127,23 +126,4 @@ export class Volume extends ExtensionProperty { public setAttenuationColor(color: vec3): this { return this.set('attenuationColor', color); } - - /** - * Color (sRGB) that white light turns into due to absorption when reaching the attenuation - * distance. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public getAttenuationColorHex(): number { - return ColorUtils.factorToHex(this.getAttenuationColor()); - } - - /** - * Color (sRGB) that white light turns into due to absorption when reaching the attenuation - * distance. - * @deprecated Will be removed in v4. Use {@link ColorUtils.hexToFactor} / {@link ColorUtils.factorToHex} instead. - */ - public setAttenuationColorHex(hex: number): this { - const factor = this.getAttenuationColor().slice() as vec3; - return this.set('attenuationColor', ColorUtils.hexToFactor(hex, factor)); - } } diff --git a/packages/extensions/test/lights-punctual.test.ts b/packages/extensions/test/lights-punctual.test.ts index 481700287..62cc13ff4 100644 --- a/packages/extensions/test/lights-punctual.test.ts +++ b/packages/extensions/test/lights-punctual.test.ts @@ -81,13 +81,6 @@ test('copy', (t) => { t.is(light2.getOuterConeAngle(), 0.75, 'copy outerConeAngle'); }); -test('hex', (t) => { - const document = new Document(); - const lightsExtension = document.createExtension(KHRLightsPunctual); - const light = lightsExtension.createLight().setColorHex(0x111111); - t.is(light.getColorHex(), 0x111111, 'colorHex'); -}); - test('i/o', async (t) => { const document = new Document(); const lightsExtension = document.createExtension(KHRLightsPunctual); diff --git a/packages/extensions/test/materials-pbr-specular-glossiness.test.ts b/packages/extensions/test/materials-pbr-specular-glossiness.test.ts index a19846690..8cb86dc60 100644 --- a/packages/extensions/test/materials-pbr-specular-glossiness.test.ts +++ b/packages/extensions/test/materials-pbr-specular-glossiness.test.ts @@ -34,12 +34,12 @@ test('basic', async (t) => { specularGlossinessTexture: { index: 0 }, }, }, - 'writes specGloss extension' + 'writes specGloss extension', ); t.deepEqual( jsonDoc.json.extensionsUsed, [KHRMaterialsPBRSpecularGlossiness.EXTENSION_NAME], - 'writes extensionsUsed' + 'writes extensionsUsed', ); specGlossExtension.dispose(); @@ -78,10 +78,3 @@ test('copy', (t) => { t.is(specGloss2.getGlossinessFactor(), 0.5, 'copy glossinessFactor'); t.is(specGloss2.getSpecularGlossinessTexture().getName(), 'specGloss', 'copy specularGlossinessTexture'); }); - -test('hex', (t) => { - const doc = new Document(); - const specGlossExtension = doc.createExtension(KHRMaterialsPBRSpecularGlossiness); - const specGloss = specGlossExtension.createPBRSpecularGlossiness().setDiffuseHex(0x0000ff); - t.is(specGloss.getDiffuseHex(), 254, 'diffuseHex'); -}); diff --git a/packages/extensions/test/materials-sheen.test.ts b/packages/extensions/test/materials-sheen.test.ts index 9db326501..21d17300a 100644 --- a/packages/extensions/test/materials-sheen.test.ts +++ b/packages/extensions/test/materials-sheen.test.ts @@ -33,7 +33,7 @@ test('basic', async (t) => { sheenColorTexture: { index: 0 }, }, }, - 'writes sheen extension' + 'writes sheen extension', ); t.deepEqual(jsonDoc.json.extensionsUsed, [KHRMaterialsSheen.EXTENSION_NAME], 'writes extensionsUsed'); @@ -64,10 +64,3 @@ test('copy', (t) => { t.deepEqual(sheen2.getSheenColorFactor(), [0.9, 0.5, 0.8], 'copy sheenColorFactor'); t.is(sheen2.getSheenColorTexture().getName(), 'sheen', 'copy sheenColorTexture'); }); - -test('hex', (t) => { - const doc = new Document(); - const sheenExtension = doc.createExtension(KHRMaterialsSheen); - const sheen = sheenExtension.createSheen().setSheenColorHex(0x252525); - t.is(sheen.getSheenColorHex(), 0x252525, 'sheenColorHex'); -}); diff --git a/packages/extensions/test/materials-specular.test.ts b/packages/extensions/test/materials-specular.test.ts index f4db738b6..d3847575a 100644 --- a/packages/extensions/test/materials-specular.test.ts +++ b/packages/extensions/test/materials-specular.test.ts @@ -36,7 +36,7 @@ test('basic', async (t) => { specularColorTexture: { index: 1 }, }, }, - 'writes specular extension' + 'writes specular extension', ); t.deepEqual(jsonDoc.json.extensionsUsed, [KHRMaterialsSpecular.EXTENSION_NAME], 'writes extensionsUsed'); @@ -72,10 +72,3 @@ test('copy', (t) => { t.is(specular2.getSpecularTexture().getName(), 'spec', 'copy specularTexture'); t.is(specular2.getSpecularColorTexture().getName(), 'specColor', 'copy specularColorTexture'); }); - -test('hex', (t) => { - const doc = new Document(); - const specularExtension = doc.createExtension(KHRMaterialsSpecular); - const specular = specularExtension.createSpecular().setSpecularColorHex(0x252525); - t.is(specular.getSpecularColorHex(), 0x252525, 'specularColorHex'); -}); diff --git a/packages/extensions/test/materials-volume.test.ts b/packages/extensions/test/materials-volume.test.ts index 734ff385c..348d1c93c 100644 --- a/packages/extensions/test/materials-volume.test.ts +++ b/packages/extensions/test/materials-volume.test.ts @@ -36,7 +36,7 @@ test('basic', async (t) => { attenuationColor: [0.1, 0.2, 0.3], }, }, - 'writes volume extension' + 'writes volume extension', ); t.deepEqual(jsonDoc.json.extensionsUsed, [KHRMaterialsVolume.EXTENSION_NAME], 'writes extensionsUsed'); @@ -51,9 +51,6 @@ test('basic', async (t) => { t.truthy(roundtripExt.getThicknessTexture(), 'reads thicknessTexture'); t.is(roundtripExt.getAttenuationDistance(), 2, 'reads attenuationDistance'); t.deepEqual(roundtripExt.getAttenuationColor(), [0.1, 0.2, 0.3], 'reads attenuationColor'); - - volume.setAttenuationColorHex(0x4285f4); - t.is(volume.getAttenuationColorHex(), 0x4285f4, 'reads/writes hexadecimal sRGB'); }); test('copy', (t) => { diff --git a/packages/functions/src/get-node-scene.ts b/packages/functions/src/get-node-scene.ts deleted file mode 100644 index 163420998..000000000 --- a/packages/functions/src/get-node-scene.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Node, Scene } from '@gltf-transform/core'; -import { listNodeScenes } from './list-node-scenes.js'; - -/** @deprecated Use {@link listNodeScenes} instead. */ -export function getNodeScene(node: Node): Scene | null { - return listNodeScenes(node)[0] || null; -} diff --git a/packages/functions/src/index.ts b/packages/functions/src/index.ts index 797b6a257..a8de9a6fb 100644 --- a/packages/functions/src/index.ts +++ b/packages/functions/src/index.ts @@ -5,7 +5,6 @@ export * from './dedup.js'; export { dequantize, dequantizePrimitive, DequantizeOptions } from './dequantize.js'; export * from './draco.js'; export * from './flatten.js'; -export * from './get-node-scene.js'; export * from './get-texture-color-space.js'; export * from './inspect.js'; export * from './instance.js'; @@ -30,7 +29,6 @@ export * from './sort-primitive-weights.js'; export * from './sparse.js'; export * from './texture-compress.js'; export * from './tangents.js'; -export * from './texture-resize.js'; export * from './transform-mesh.js'; export * from './transform-primitive.js'; export * from './unlit.js'; diff --git a/packages/functions/src/texture-compress.ts b/packages/functions/src/texture-compress.ts index 8aa1d17c5..ee59accbd 100644 --- a/packages/functions/src/texture-compress.ts +++ b/packages/functions/src/texture-compress.ts @@ -4,7 +4,6 @@ import { getTextureChannelMask } from './list-texture-channels.js'; import { listTextureSlots } from './list-texture-slots.js'; import type sharp from 'sharp'; import { createTransform, fitWithin, formatBytes } from './utils.js'; -import { TextureResizeFilter } from './texture-resize.js'; import { getPixels, savePixels } from 'ndarray-pixels'; import ndarray from 'ndarray'; import { lanczos2, lanczos3 } from 'ndarray-lanczos'; @@ -15,6 +14,14 @@ type Format = (typeof TEXTURE_COMPRESS_SUPPORTED_FORMATS)[number]; export const TEXTURE_COMPRESS_SUPPORTED_FORMATS = ['jpeg', 'png', 'webp', 'avif'] as const; const SUPPORTED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/avif']; +/** Resampling filter methods. LANCZOS3 is sharper, LANCZOS2 is smoother. */ +export enum TextureResizeFilter { + /** Lanczos3 (sharp) */ + LANCZOS3 = 'lanczos3', + /** Lanczos2 (smooth) */ + LANCZOS2 = 'lanczos2', +} + export interface TextureCompressOptions { /** Instance of the Sharp encoder, which must be installed from the * 'sharp' package and provided by the caller. When not provided, a diff --git a/packages/functions/src/texture-resize.ts b/packages/functions/src/texture-resize.ts deleted file mode 100644 index 29f2636fb..000000000 --- a/packages/functions/src/texture-resize.ts +++ /dev/null @@ -1,110 +0,0 @@ -import ndarray from 'ndarray'; -import { lanczos2, lanczos3 } from 'ndarray-lanczos'; -import { getPixels, savePixels } from 'ndarray-pixels'; -import { MathUtils, type Document, type Transform, type vec2 } from '@gltf-transform/core'; -import { listTextureSlots } from './list-texture-slots.js'; -import { createTransform, fitWithin } from './utils.js'; - -const NAME = 'textureResize'; - -/** Options for the {@link textureResize} function. */ -export interface TextureResizeOptions { - /** - * Maximum width/height to enforce, preserving aspect ratio. For example, - * a 4096x8192 texture, resized with limit [2048, 2048] will be reduced - * to 1024x2048. - */ - size: vec2; - /** Resampling filter method. LANCZOS3 is sharper, LANCZOS2 is smoother. */ - filter?: TextureResizeFilter; - /** Pattern identifying textures to resize, matched to name or URI. */ - pattern?: RegExp | null; - /** Pattern to match slots usage for resizing. */ - slots?: RegExp | null; -} - -/** Resampling filter methods. LANCZOS3 is sharper, LANCZOS2 is smoother. */ -export enum TextureResizeFilter { - /** Lanczos3 (sharp) */ - LANCZOS3 = 'lanczos3', - /** Lanczos2 (smooth) */ - LANCZOS2 = 'lanczos2', -} - -export const TEXTURE_RESIZE_DEFAULTS: TextureResizeOptions = { - size: [2048, 2048], - filter: TextureResizeFilter.LANCZOS3, - pattern: null, - slots: null, -}; - -/** - * Resize PNG or JPEG {@link Texture Textures}, with [Lanczos filtering](https://en.wikipedia.org/wiki/Lanczos_algorithm). - * - * Implementation provided by [ndarray-lanczos](https://github.com/donmccurdy/ndarray-lanczos) - * package, which works in Web and Node.js environments. For a faster and more robust implementation - * in Node.js, use {@link textureCompress}, providing a Sharp encoder and 'resize' options instead. - * - * @deprecated Prefer {@link textureCompress}, instead. - * @privateRemarks TODO(v4): Remove this function, using `textureCompress()` instead. - * @category Transforms - */ -export function textureResize(_options: TextureResizeOptions = TEXTURE_RESIZE_DEFAULTS): Transform { - const options = { ...TEXTURE_RESIZE_DEFAULTS, ..._options } as Required; - - return createTransform(NAME, async (doc: Document): Promise => { - const logger = doc.getLogger(); - - for (const texture of doc.getRoot().listTextures()) { - const name = texture.getName(); - const uri = texture.getURI(); - const match = !options.pattern || options.pattern.test(name) || options.pattern.test(uri); - if (!match) { - logger.debug(`${NAME}: Skipping, excluded by "pattern" parameter.`); - continue; - } - - if (texture.getMimeType() !== 'image/png' && texture.getMimeType() !== 'image/jpeg') { - logger.warn(`${NAME}: Skipping, unsupported texture type "${texture.getMimeType()}".`); - continue; - } - - const slots = listTextureSlots(texture); - if (options.slots && !slots.some((slot) => options.slots?.test(slot))) { - logger.debug(`${NAME}: Skipping, [${slots.join(', ')}] excluded by "slots" parameter.`); - continue; - } - - const srcSize = texture.getSize()!; - const dstSize = fitWithin(srcSize, options.size); - - if (MathUtils.eq(srcSize, dstSize)) { - logger.debug(`${NAME}: Skipping, not within size range.`); - continue; - } - - const srcImage = texture.getImage()!; - const srcPixels = (await getPixels(srcImage, texture.getMimeType())) as ndarray.NdArray; - const dstPixels = ndarray(new Uint8Array(dstSize[0] * dstSize[1] * 4), [...dstSize, 4]); - - logger.debug(`${NAME}: Resizing "${uri || name}", ${srcPixels.shape} → ${dstPixels.shape}...`); - logger.debug(`${NAME}: Slots → [${slots.join(', ')}]`); - - try { - options.filter === TextureResizeFilter.LANCZOS3 - ? lanczos3(srcPixels, dstPixels) - : lanczos2(srcPixels, dstPixels); - } catch (e) { - if (e instanceof Error) { - logger.warn(`${NAME}: Failed to resize "${uri || name}": "${e.message}".`); - continue; - } - throw e; - } - - texture.setImage(await savePixels(dstPixels, texture.getMimeType())); - } - - logger.debug(`${NAME}: Complete.`); - }); -} diff --git a/packages/functions/src/vertex-color-space.ts b/packages/functions/src/vertex-color-space.ts index 026d717e6..2830906c3 100644 --- a/packages/functions/src/vertex-color-space.ts +++ b/packages/functions/src/vertex-color-space.ts @@ -6,14 +6,9 @@ const NAME = 'vertexColorSpace'; /** Options for the {@link vertexColorSpace} function. */ export interface ColorSpaceOptions { /** Input color space of vertex colors, to be converted to "srgb-linear". Required. */ - inputColorSpace: 'srgb' | 'srgb-linear' | 'sRGB'; - /** @deprecated Renamed to 'colorSpace'. */ - inputEncoding?: 'srgb' | 'srgb-linear' | 'sRGB'; + inputColorSpace: 'srgb' | 'srgb-linear'; } -/** @deprecated Renamed to {@link vertexColorSpace}. */ -export const colorspace = vertexColorSpace; - /** * Vertex color color space correction. The glTF format requires vertex colors to be stored * in Linear Rec. 709 D65 color space, and this function provides a way to correct vertex @@ -35,7 +30,7 @@ export function vertexColorSpace(options: ColorSpaceOptions): Transform { return createTransform(NAME, (doc: Document): void => { const logger = doc.getLogger(); - const inputColorSpace = (options.inputColorSpace || options.inputEncoding || '').toLowerCase(); + const inputColorSpace = (options.inputColorSpace || '').toLowerCase(); if (inputColorSpace === 'srgb-linear') { logger.info(`${NAME}: Vertex colors already linear. Skipping conversion.`); @@ -45,7 +40,7 @@ export function vertexColorSpace(options: ColorSpaceOptions): Transform { if (inputColorSpace !== 'srgb') { logger.error( `${NAME}: Unknown input color space "${inputColorSpace}" – should be "srgb" or ` + - '"srgb-linear". Skipping conversion.' + '"srgb-linear". Skipping conversion.', ); return; } diff --git a/packages/functions/src/weld.ts b/packages/functions/src/weld.ts index 374126e75..ff31c3a82 100644 --- a/packages/functions/src/weld.ts +++ b/packages/functions/src/weld.ts @@ -108,7 +108,7 @@ export function weld(_options: WeldOptions = WELD_DEFAULTS): Transform { for (const mesh of doc.getRoot().listMeshes()) { for (const prim of mesh.listPrimitives()) { - weldPrimitive(doc, prim, options); + weldPrimitive(prim, options); if (isPrimEmpty(prim)) prim.dispose(); } @@ -158,35 +158,19 @@ export function weld(_options: WeldOptions = WELD_DEFAULTS): Transform { * weldPrimitive(prim, {tolerance: 0.0001}); * } * ``` - * - * @privateRemarks TODO(v4): Remove the "Document" parameter. */ -export function weldPrimitive( - a: Document | Primitive, - b: Primitive | WeldOptions = WELD_DEFAULTS, - c = WELD_DEFAULTS, -): void { - let _document: Document; - let _prim: Primitive; - let _options: Required; - if (a instanceof Primitive) { - const graph = a.getGraph(); - _document = Document.fromGraph(graph)!; - _prim = a; - _options = expandWeldOptions(b as WeldOptions); - } else { - _document = a; - _prim = b as Primitive; - _options = expandWeldOptions(c as WeldOptions); - } +export function weldPrimitive(prim: Primitive, _options: WeldOptions = WELD_DEFAULTS): void { + const graph = prim.getGraph(); + const document = Document.fromGraph(graph)!; + const options = expandWeldOptions(_options); - if (_prim.getIndices() && !_options.overwrite) return; - if (_prim.getMode() === Primitive.Mode.POINTS) return; + if (prim.getIndices() && !_options.overwrite) return; + if (prim.getMode() === Primitive.Mode.POINTS) return; if (_options.tolerance === 0) { - _indexPrimitive(_document, _prim); + _indexPrimitive(document, prim); } else { - _weldPrimitive(_document, _prim, _options); + _weldPrimitive(document, prim, options); } } diff --git a/packages/functions/test/dedup.test.ts b/packages/functions/test/dedup.test.ts index de8646fb6..974da317d 100644 --- a/packages/functions/test/dedup.test.ts +++ b/packages/functions/test/dedup.test.ts @@ -58,7 +58,11 @@ test('materials', (t) => { const document = new Document(); const root = document.getRoot(); - const mat = document.createMaterial('MatA').setBaseColorHex(0xf2f2f2).setAlpha(0.9).setAlphaMode('OPAQUE'); + const mat = document + .createMaterial('MatA') + .setBaseColorFactor([0.8, 0.8, 0.8, 1]) + .setAlpha(0.9) + .setAlphaMode('OPAQUE'); const matCloned = mat.clone(); const matRenamed = mat.clone().setName('MatC'); const matUnequal = mat.clone().setName('MatD').setAlphaMode('MASK'); @@ -82,7 +86,11 @@ test('materials - animation', (t) => { const document = new Document(); const root = document.getRoot(); - const matA = document.createMaterial('MatA').setBaseColorHex(0xf2f2f2).setAlpha(0.9).setAlphaMode('OPAQUE'); + const matA = document + .createMaterial('MatA') + .setBaseColorFactor([0.8, 0.8, 0.8, 1]) + .setAlpha(0.9) + .setAlphaMode('OPAQUE'); const matB = matA.clone(); const matC = matA.clone(); const matD = matA.clone(); @@ -178,9 +186,9 @@ test('textures', async (t) => { test('unique names', async (t) => { const document = new Document(); - const matA = document.createMaterial('A').setBaseColorHex(0xcccccc); + const matA = document.createMaterial('A').setBaseColorFactor([0.5, 0.5, 0.5, 1]); const matB = matA.clone().setName('B'); - const matC = matA.clone().setName('C').setBaseColorHex(0xdddddd); + const matC = matA.clone().setName('C').setBaseColorFactor([0.6, 0.6, 0.6, 1]); const positionA = document .createAccessor() diff --git a/packages/functions/test/get-node-scene.test.ts b/packages/functions/test/get-node-scene.test.ts deleted file mode 100644 index 2a410c7a8..000000000 --- a/packages/functions/test/get-node-scene.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import test from 'ava'; -import { Document } from '@gltf-transform/core'; -import { getNodeScene } from '@gltf-transform/functions'; -import { logger } from '@gltf-transform/test-utils'; - -test('basic', async (t) => { - const document = new Document().setLogger(logger); - const nodeA = document.createNode('A').setTranslation([2, 0, 0]); - const nodeB = document.createNode('B').setScale([4, 4, 4]).addChild(nodeA); - const nodeC = document.createNode('C').addChild(nodeB); - const scene = document.createScene().addChild(nodeC); - - t.is(getNodeScene(nodeA), scene, 'A → Scene'); - t.is(getNodeScene(nodeB), scene, 'B → Scene'); - t.is(getNodeScene(nodeC), scene, 'C → Scene'); - - scene.removeChild(nodeC); - - t.is(getNodeScene(nodeA), null, 'A → null'); - t.is(getNodeScene(nodeB), null, 'B → null'); - t.is(getNodeScene(nodeC), null, 'C → null'); -}); diff --git a/packages/functions/test/palette.test.ts b/packages/functions/test/palette.test.ts index 5988f6f14..f804b43d9 100644 --- a/packages/functions/test/palette.test.ts +++ b/packages/functions/test/palette.test.ts @@ -1,6 +1,6 @@ import test from 'ava'; import { getPixels } from 'ndarray-pixels'; -import { Document, GLTF, Material } from '@gltf-transform/core'; +import { Document, GLTF, Material, vec4 } from '@gltf-transform/core'; import { KHRMaterialsSpecular } from '@gltf-transform/extensions'; import { palette } from '@gltf-transform/functions'; import { logger } from '@gltf-transform/test-utils'; @@ -10,7 +10,13 @@ test('basic', async (t) => { const [materialA, materialB, materialC, materialD, materialE] = createMaterials( document, ['A', 'B', 'C', 'D', 'E'], - [0xff0000, 0x00ff00, 0x0000ff, 0x00ff00, 0xff0000], + [ + [1, 0, 0, 1], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 0, 1], + [1, 0, 0, 1], + ], [1.0, 1.0, 1.0, 0.0, 1.0], ['OPAQUE', 'OPAQUE', 'OPAQUE', 'OPAQUE', 'BLEND'], ); @@ -38,7 +44,13 @@ test('options.blockSize', async (t) => { createMaterials( document, ['A', 'B', 'C', 'D', 'E'], - [0xff0000, 0x00ff00, 0x0000ff, 0x00ff00, 0xff0000], + [ + [1, 0, 0, 1], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 0, 1], + [1, 0, 0, 1], + ], new Array(5).fill(1.0), new Array(5).fill('OPAQUE'), ); @@ -62,7 +74,13 @@ test('options.min', async (t) => { createMaterials( document, ['A', 'B', 'C', 'D', 'E'], - [0xff0000, 0x00ff00, 0x0000ff, 0x00ff00, 0xff0000], + [ + [1, 0, 0, 1], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 0, 1], + [1, 0, 0, 1], + ], new Array(5).fill(1.0), new Array(5).fill('OPAQUE'), ); @@ -83,7 +101,13 @@ test('preserve extensions', async (t) => { const [material] = createMaterials( document, ['A', 'B', 'C', 'D', 'E'], - [0xff0000, 0x00ff00, 0x0000ff, 0x00ff00, 0xff0000], + [ + [1, 0, 0, 1], + [0, 1, 0, 1], + [0, 0, 1, 1], + [0, 1, 0, 1], + [1, 0, 0, 1], + ], new Array(5).fill(1.0), new Array(5).fill('OPAQUE'), ); @@ -111,7 +135,11 @@ test('pixel values', async (t) => { createMaterials( document, ['A', 'B', 'C'], - [0x808080, 0x000080, 0x800000], + [ + [0.218, 0.218, 0.218, 1], + [0, 0, 0.218, 1], + [0.218, 0, 0, 1], + ], new Array(3).fill(1.0), new Array(3).fill('OPAQUE'), ); @@ -154,7 +182,7 @@ test('pixel values', async (t) => { function createMaterials( document: Document, names: string[], - baseColorHexCodes: number[], + baseColorFactors: vec4[], roughnessFactors: number[], alphaModes: GLTF.MaterialAlphaMode[], ): Material[] { @@ -169,7 +197,7 @@ function createMaterials( for (let i = 0; i < names.length; i++) { const material = document .createMaterial(names[i]) - .setBaseColorHex(baseColorHexCodes[i]) + .setBaseColorFactor(baseColorFactors[i]) .setRoughnessFactor(roughnessFactors[i]) .setAlphaMode(alphaModes[i]); mesh.addPrimitive(prim.clone().setMaterial(material)); diff --git a/packages/functions/test/texture-resize.test.ts b/packages/functions/test/texture-resize.test.ts deleted file mode 100644 index 7eb92a486..000000000 --- a/packages/functions/test/texture-resize.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import fs from 'fs'; -import path, { dirname } from 'path'; -import { getPixels, savePixels } from 'ndarray-pixels'; -import test from 'ava'; -import { Document } from '@gltf-transform/core'; -import { textureResize } from '@gltf-transform/functions'; -import ndarray from 'ndarray'; -import { fileURLToPath } from 'url'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -const GRADIENT = getPixels(fs.readFileSync(path.resolve(__dirname, './in/pattern.png')), 'image/png'); -const GRADIENT_HALF = getPixels(fs.readFileSync(path.resolve(__dirname, './in/pattern-half.png')), 'image/png'); -const NON_SQUARE = ndarray(new Uint8Array(256 * 512 * 4), [256, 512, 4]); - -test('square', async (t) => { - const gradientImage = await savePixels(await GRADIENT, 'image/png'); - const gradientHalfImage = await savePixels(await GRADIENT_HALF, 'image/png'); - - const document = new Document(); - const texture = document.createTexture('target').setImage(gradientImage).setMimeType('image/png'); - - await document.transform(textureResize({ size: [100, 100], pattern: /other/ })); - - t.is(texture.getImage(), gradientImage, 'no match - pattern'); - - await document.transform(textureResize({ size: [100, 100], slots: /NotAMatch/ })); - - t.is(texture.getImage(), gradientImage, 'no match - slots'); - - await document.transform(textureResize({ size: [4, 4], pattern: /target/ })); - - t.deepEqual(Array.from(texture.getImage()), Array.from(gradientHalfImage), 'match - resize down'); - - await document.transform(textureResize({ size: [2, 4] })); - - t.deepEqual( - (await getPixels(texture.getImage(), 'image/png')).shape, - [2, 2, 4], - 'all - resize down with aspect ratio' - ); -}); - -test('non-square', async (t) => { - const nonSquareImage = await savePixels(await NON_SQUARE, 'image/png'); - const document = new Document(); - const texture = document.createTexture('target').setImage(nonSquareImage).setMimeType('image/png'); - - await document.transform(textureResize({ size: [16, 16] })); - - t.deepEqual((await getPixels(texture.getImage(), 'image/png')).shape, [8, 16, 4], 'maintain aspect ratio'); -});