Explorar el Código

Add GLTFSpecGlossinessConverterPlugin with example, export GLTFDracoExportPlugin.gltfTransformExtensions, bump gltf-transform version to 4.2.0

master
Palash Bansal hace 11 meses
padre
commit
b180f58a4a
No account linked to committer's email address

+ 37
- 0
examples/gltf-spec-gloss-import/index.html Ver fichero

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GLB PBR SpecularGlossiness Extension Import</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/global-loading.mjs"></script>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 38
- 0
examples/gltf-spec-gloss-import/script.ts Ver fichero

@@ -0,0 +1,38 @@
import {_testFinish, _testStart, AssetExporterPlugin, IObject3D, LoadingScreenPlugin, ThreeViewer} from 'threepipe'
import {GLTFDracoExportPlugin, GLTFSpecGlossinessConverterPlugin} from '@threepipe/plugin-gltf-transform'

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
msaa: true,
})

async function init() {

viewer.addPluginSync(LoadingScreenPlugin)
viewer.addPluginSync(AssetExporterPlugin)
viewer.addPluginSync(GLTFDracoExportPlugin)
viewer.addPluginSync(GLTFSpecGlossinessConverterPlugin)

// Note: see asset-exporter-plugin example as well

// load obj + mtl
await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
const model = await viewer.load<IObject3D>('https://asset-samples.threepipe.org/tests/SpecGlossVsMetalRough.glb', {
autoCenter: true,
autoScale: true,
confirmSpecGlossConversion: false, // prevents the confirmation dialog
})
if (!model) {
console.error('Unable to load model')
return
}

}

_testStart()
init().finally(_testFinish)

+ 2
- 1
examples/index.html Ver fichero

@@ -442,7 +442,8 @@
<li><a href="./splat-load/">SPLAT Load<br/>(Gaussian Splatting) </a></li>
<li><a href="./extra-importer-plugins/">Extra (3ds, 3mf, collada, amf, bvh, vox, gcode, mdd, pcd, tilt, wrl, ldraw, vtk, xyz) Load </a></li>
<li><a href="./gltf-meshopt-compression/">glTF MeshOpt Decode (Compression Extension) </a></li>
<li><a href="./gltf-mesh-lines/">glTF Mesh Lines <br/>(Fat Lines) </a></li>
<li><a href="./gltf-mesh-lines/">glTF Mesh Lines (Fat Lines) </a></li>
<li><a href="./gltf-spec-gloss-import">glTF pbrSpecularGlossiness <br/>(Convert/Import) </a></li>
<li><a href="./assimpjs-plugin/">AssimpJs Plugin </a></li>
<li><a href="./b3dm-load/">B3DM Load (3D Tile) </a></li>
<li><a href="./i3dm-load/">I3DM Load (3D Tile) </a></li>

+ 2
- 1
examples/tweakpane-editor/ThreeEditor.ts Ver fichero

@@ -63,7 +63,7 @@ import {GeometryGeneratorPlugin} from '@threepipe/plugin-geometry-generator'
import {GaussianSplattingPlugin} from '@threepipe/plugin-gaussian-splatting'
import {MaterialConfiguratorPlugin, SwitchNodePlugin} from '@threepipe/plugin-configurator'
import {AWSClientPlugin, TransfrSharePlugin} from '@threepipe/plugin-network'
import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'
import {GLTFDracoExportPlugin, GLTFSpecGlossinessConverterPlugin} from '@threepipe/plugin-gltf-transform'
import {
B3DMLoadPlugin,
CMPTLoadPlugin,
@@ -85,6 +85,7 @@ export class ThreeEditor extends ThreeViewer {
LoadingScreenPlugin,
AssetExporterPlugin,
GLTFDracoExportPlugin,
GLTFSpecGlossinessConverterPlugin,
PopmotionPlugin,
new ProgressivePlugin(),
new SSAAPlugin(),

+ 657
- 21
plugins/gltf-transform/package-lock.json Ver fichero

@@ -1,59 +1,695 @@
{
"name": "@threepipe/plugin-gltf-transform",
"version": "0.1.3",
"version": "0.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@threepipe/plugin-gltf-transform",
"version": "0.1.3",
"version": "0.2.0",
"license": "Apache-2.0",
"dependencies": {
"threepipe": "file:./../../src/"
},
"devDependencies": {
"@gltf-transform/core": "3.2.1",
"@gltf-transform/extensions": "3.2.1"
"@gltf-transform/core": "4.2.0",
"@gltf-transform/extensions": "4.2.0",
"@gltf-transform/functions": "4.2.0"
}
},
"../../src": {},
"../tweakpane/src": {
"extraneous": true
},
"node_modules/@emnapi/runtime": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz",
"integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@gltf-transform/core": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@gltf-transform/core/-/core-3.2.1.tgz",
"integrity": "sha512-EE4AXJsu1jsSvcTnzk+mCu/VgLldPsb0gGhOV7onRlHM4DYh8m9aCCjGdLJf1uNJi+KUP5hPmOrUteXuopFq2A==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@gltf-transform/core/-/core-4.2.0.tgz",
"integrity": "sha512-43FtHNxMhT+VX/WZeXISorbtknwusdcfwu0qzfrDa1azsk5CBVOaZwM+ul7DsHty47eC49lSPN0g8uNso35WVw==",
"dev": true,
"license": "MIT",
"dependencies": {
"property-graph": "^1.2.0"
"property-graph": "^3.0.0"
},
"funding": {
"url": "https://github.com/sponsors/donmccurdy"
}
},
"node_modules/@gltf-transform/extensions": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@gltf-transform/extensions/-/extensions-3.2.1.tgz",
"integrity": "sha512-7uiCXDV7/o2pnuXM9z/URdP9RR3baOaVo3f3eo65WtoUBIRKO6I/WHJzwGrRdWIWKQQWfxwZLTzYYaAgprnxDg==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@gltf-transform/extensions/-/extensions-4.2.0.tgz",
"integrity": "sha512-ujw3RdS1/tVEixFUNuI21cApCgYXTeew4VCF22S0PzHT1I3O+oxFctyllhJOo+BYnlC9w/AnCuQpTAy+pMIboA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@gltf-transform/core": "^3.2.1",
"ktx-parse": "^0.5.0"
"@gltf-transform/core": "^4.2.0",
"ktx-parse": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/donmccurdy"
}
},
"node_modules/@gltf-transform/functions": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@gltf-transform/functions/-/functions-4.2.0.tgz",
"integrity": "sha512-Umi/ATt5ktPBylD3a/l5oC1jPbZF60Xnm87qmVBJiLbRMcubN881WB2xP2d7je/UjVSd10fgIZ78GoS37Lpygg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@gltf-transform/core": "^4.2.0",
"@gltf-transform/extensions": "^4.2.0",
"ktx-parse": "^1.0.0",
"ndarray": "^1.0.19",
"ndarray-lanczos": "^0.3.0",
"ndarray-pixels": "^4.1.0"
},
"funding": {
"url": "https://github.com/sponsors/donmccurdy"
}
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-darwin-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
"integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.0.4"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
"integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
"integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
"integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
"cpu": [
"arm"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
"integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
"integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
"cpu": [
"s390x"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
"integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
"cpu": [
"x64"
],
"dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
"integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.0.5"
}
},
"node_modules/@img/sharp-linux-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
"integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linux-s390x": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
"integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
"cpu": [
"s390x"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-s390x": "1.0.4"
}
},
"node_modules/@img/sharp-linux-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
"integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.0.4"
}
},
"node_modules/@img/sharp-wasm32": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
"integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
"cpu": [
"wasm32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
"@emnapi/runtime": "^1.2.0"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
"integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@types/ndarray": {
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/@types/ndarray/-/ndarray-1.0.14.tgz",
"integrity": "sha512-oANmFZMnFQvb219SSBIhI1Ih/r4CvHDOzkWyJS/XRqkMrGH5/kaPSA1hQhdIBzouaE+5KpE/f5ylI9cujmckQg==",
"dev": true,
"license": "MIT"
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"node_modules/cwise-compiler": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz",
"integrity": "sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"uniq": "^1.0.0"
}
},
"node_modules/detect-libc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/iota-array": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz",
"integrity": "sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==",
"dev": true,
"license": "MIT"
},
"node_modules/is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
"dev": true,
"license": "MIT"
},
"node_modules/is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true,
"license": "MIT"
},
"node_modules/ktx-parse": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.5.0.tgz",
"integrity": "sha512-5IZrv5s1byUeDTIee1jjJQBiD5LPDB0w9pJJ0oT9BCKKJf16Tuj123vm1Ps0GOHSHmeWPgKM0zuViCVuTRpqaA==",
"dev": true
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-1.0.1.tgz",
"integrity": "sha512-djwUWv/82Xc8LOVinJU4EBrVqYkO8OsUDSPEtY/OOVY8BSe3DMU7D7PlIAZ0pI7ZZtErj7mqpJcgffUTABvgaA==",
"dev": true,
"license": "MIT"
},
"node_modules/ndarray": {
"version": "1.0.19",
"resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz",
"integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"iota-array": "^1.0.0",
"is-buffer": "^1.0.2"
}
},
"node_modules/ndarray-lanczos": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/ndarray-lanczos/-/ndarray-lanczos-0.3.0.tgz",
"integrity": "sha512-5kBmmG3Zvyj77qxIAC4QFLKuYdDIBJwCG+DukT6jQHNa1Ft74/hPH1z5mbQXeHBt8yvGPBGVrr3wEOdJPYYZYg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/ndarray": "^1.0.11",
"ndarray": "^1.0.19"
}
},
"node_modules/ndarray-ops": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/ndarray-ops/-/ndarray-ops-1.2.2.tgz",
"integrity": "sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"cwise-compiler": "^1.0.0"
}
},
"node_modules/ndarray-pixels": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ndarray-pixels/-/ndarray-pixels-4.1.0.tgz",
"integrity": "sha512-xKPI4zXJ2pkUcVX24zIN1AWqqPWvRWWhRuO6PlY4EdB2VNRauNwA6rDdsAQG/ldQp0sU7nTXgPR/io1duy3Zyg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/ndarray": "^1.0.14",
"ndarray": "^1.0.19",
"ndarray-ops": "^1.2.2",
"sharp": "^0.33.4"
}
},
"node_modules/property-graph": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/property-graph/-/property-graph-1.3.1.tgz",
"integrity": "sha512-gei3N/bHWJdCItJ4blnlGWd9iauEZI+JZYj/A0D177XSI01+QhiJGAVscYBhe3Yywow3A2QJzVtsO2P+UgrRRQ==",
"dev": true
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/property-graph/-/property-graph-3.0.0.tgz",
"integrity": "sha512-TnzxUsttmGtw+OiU0LDw+0FlMbJ8vV8pOjyDI7+Kdni4Tj0hW5BFh7TatQu7Y68hcvvFmiFOHilKShsA4R82fA==",
"dev": true,
"license": "MIT"
},
"node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/sharp": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
"integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.3",
"semver": "^7.6.3"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-darwin-arm64": "0.33.5",
"@img/sharp-darwin-x64": "0.33.5",
"@img/sharp-libvips-darwin-arm64": "1.0.4",
"@img/sharp-libvips-darwin-x64": "1.0.4",
"@img/sharp-libvips-linux-arm": "1.0.5",
"@img/sharp-libvips-linux-arm64": "1.0.4",
"@img/sharp-libvips-linux-s390x": "1.0.4",
"@img/sharp-libvips-linux-x64": "1.0.4",
"@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
"@img/sharp-libvips-linuxmusl-x64": "1.0.4",
"@img/sharp-linux-arm": "0.33.5",
"@img/sharp-linux-arm64": "0.33.5",
"@img/sharp-linux-s390x": "0.33.5",
"@img/sharp-linux-x64": "0.33.5",
"@img/sharp-linuxmusl-arm64": "0.33.5",
"@img/sharp-linuxmusl-x64": "0.33.5",
"@img/sharp-wasm32": "0.33.5",
"@img/sharp-win32-ia32": "0.33.5",
"@img/sharp-win32-x64": "0.33.5"
}
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
"node_modules/threepipe": {
"resolved": "../../src",
"link": true
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
},
"node_modules/uniq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
"integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==",
"dev": true,
"license": "MIT"
}
}
}

+ 5
- 4
plugins/gltf-transform/package.json Ver fichero

@@ -1,10 +1,11 @@
{
"name": "@threepipe/plugin-gltf-transform",
"description": "Utility plugins for threepipe using gltf-transform to optimize/compress glTF files.",
"version": "0.1.3",
"version": "0.2.0",
"devDependencies": {
"@gltf-transform/core": "3.2.1",
"@gltf-transform/extensions": "3.2.1"
"@gltf-transform/core": "4.2.0",
"@gltf-transform/extensions": "4.2.0",
"@gltf-transform/functions": "4.2.0"
},
"dependencies": {
"threepipe": "file:./../../src/"
@@ -29,7 +30,7 @@
"replace": {
"dependencies": {},
"peerDependencies": {
"threepipe": "^0.0.39"
"threepipe": "^0.0.47"
}
}
},

+ 12
- 5
plugins/gltf-transform/src/GLTFDracoExportPlugin.ts Ver fichero

@@ -17,9 +17,14 @@ import {
noiseBumpMaterialGLTFExtension,
fragmentClippingGLTFExtension,
} from 'threepipe'
import {GLTFDracoExporter} from './GLTFDracoExporter'
import {
createGenericExtensionClass,
GLTFDracoExporter,
GLTFViewerConfigExtensionGP,
} from './GLTFDracoExporter'
import {UiObjectConfig} from 'uiconfig.js'
import {EncoderOptions} from '@gltf-transform/extensions/dist/khr-draco-mesh-compression/encoder'
import {Extension} from '@gltf-transform/core'

export enum EncoderMethod {
EDGEBREAKER = 1,
@@ -42,7 +47,7 @@ export class GLTFDracoExportPlugin extends AViewerPluginSync {
* These are added here, but also added as plugins. Added here by default so that the data is not lost if some plugin is not added in an app.
* To explicitly remove the data, use `removeExtension` with the name of the extension
*/
extraExtensions = [
extraExtensions = [ // its array because we want to keep the order of extensions
[GLTFMaterialsBumpMapExtension.WebGiMaterialsBumpMapExtension, GLTFMaterialsBumpMapExtension.Textures],
[GLTFMaterialsLightMapExtension.WebGiMaterialsLightMapExtension, GLTFMaterialsLightMapExtension.Textures],
[GLTFMaterialsAlphaMapExtension.WebGiMaterialsAlphaMapExtension, GLTFMaterialsAlphaMapExtension.Textures],
@@ -69,6 +74,10 @@ export class GLTFDracoExportPlugin extends AViewerPluginSync {
// SSBevelMaterialExtension
] as [string, Record<string, string|number>|undefined][]

get gltfTransformExtensions(): (typeof Extension)[] {
return [GLTFViewerConfigExtensionGP, ...this.extraExtensions.map(e => createGenericExtensionClass(e[0], e[1]))]
}

addExtension(name: string, textures?: Record<string, string|number>) {
const ext = this.extraExtensions.findIndex(e => e[0] === name)
if (ext >= 0) this.extraExtensions[ext] = [name, textures]
@@ -95,9 +104,7 @@ export class GLTFDracoExportPlugin extends AViewerPluginSync {
// todo unregister on dispose
this._viewer.assetManager.importer.registerFile(tempFile) as DRACOLoader2)
ex.setup(this._viewer, _exporter.extensions)
for (const [ext, config] of this.extraExtensions) {
ex.createAndAddExtension(ext, config)
}
ex.addExtension(...this.gltfTransformExtensions)
return ex
}


+ 6
- 6
plugins/gltf-transform/src/GLTFDracoExporter.ts Ver fichero

@@ -34,9 +34,6 @@ export class GLTFDracoExporter extends GLTFExporter2 implements IExportWriter {
encodeSpeed: 5,
}
this._io = new WebIO().registerExtensions(ALL_EXTENSIONS)
.registerExtensions([
GLTFViewerConfigExtensionGP,
])
this._encoderOptions = encoderOptions

if (loader) {
@@ -131,13 +128,16 @@ export class GLTFDracoExporter extends GLTFExporter2 implements IExportWriter {
}
}

addExtension(extension: typeof Extension): this {
this._io.registerExtensions([extension])
addExtension(...extension: (typeof Extension)[]): this {
this._io.registerExtensions(extension)
return this
}
createAndAddExtension(name: string, textures?: Record<string, string|number>): this {
return this.addExtension(createGenericExtensionClass(name, textures))
}
createAndAddExtensions(extensions: [string, Record<string, string|number>|undefined][]): this {
return this.addExtension(...extensions.map(e=> createGenericExtensionClass(e[0], e[1])))
}
}

declare module 'threepipe'{
@@ -157,7 +157,7 @@ class ViewerJSONExtensionProperty extends ExtensionProperty {
protected init(): void {return}

}
class GLTFViewerConfigExtensionGP extends Extension {
export class GLTFViewerConfigExtensionGP extends Extension {
public readonly extensionName = GLTFViewerConfigExtension.ViewerConfigGLTFExtension
public static readonly EXTENSION_NAME = GLTFViewerConfigExtension.ViewerConfigGLTFExtension
private _viewerConfig: any = {}

+ 126
- 0
plugins/gltf-transform/src/GLTFSpecGlossinessConverterPlugin.ts Ver fichero

@@ -0,0 +1,126 @@
import {AViewerPluginSync, DRACOLoader2, GLTFBinaryExtension, GLTFLoader2, GLTFParser, ThreeViewer} from 'threepipe'
import {Extension, WebIO} from '@gltf-transform/core'
import {ALL_EXTENSIONS} from '@gltf-transform/extensions'
import {GLTFDracoExportPlugin} from './GLTFDracoExportPlugin'
import {metalRough} from '@gltf-transform/functions'

/**
* GLTFSpecGlossinessConverterPlugin
*
* Plugin that adds a gltf loader extension that automatically converts GLTF files with specular glossiness materials ([KHR_materials_pbrSpecularGlossiness](https://kcoley.github.io/glTF/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/)) to metallic roughness during import.
*
* To use this plugin, simply add it to the viewer and import a file with specular glossiness materials.
* If `confirm` is set to true, a confirmation dialog will be shown before the conversion.
*/
export class GLTFSpecGlossinessConverterPlugin extends AViewerPluginSync {
enabled = true

static readonly PluginType = 'GLTFSpecGlossinessConverterPlugin'
toJSON: any = undefined

// dependencies = [GLTFDracoExportPlugin]

/**
* Whether to show the confirmation dialog when loading a GLTF file with specular glossiness materials.
* If set to false, the conversion will be done automatically without confirmation.
* To disable the conversion entirely, disable the plugin.
*/
confirm = true
/**
* The message to show in the confirmation dialog when loading a GLTF file with specular glossiness materials.
*/
confirmMessage = 'GLTF Load: This file includes specular glossiness materials, do you want to convert it to metallic roughness before load?'

private _loaderCreate({loader}: {loader: GLTFLoader2}) {
if (!loader.isGLTFLoader2) return

const ep = this._viewer?.getPlugin(GLTFDracoExportPlugin)
if (!ep) {
console.error('GLTFSpecGlossinessConverterPlugin requires GLTFDracoExportPlugin in the plugin for extra extensions')
}
loader.register(gltfKhrPbrSpecularGlossinessConverter(async(m)=>!this.enabled ? false : !this.confirm ? true : this._viewer?.dialog.confirm(this.confirmMessage || m) ?? true, ep?.gltfTransformExtensions))
}

constructor() {
super()
this._loaderCreate = this._loaderCreate.bind(this)
}

onAdded(v: ThreeViewer) {
super.onAdded(v)
v.assetManager.importer.addEventListener('loaderCreate', this._loaderCreate as any)
}

onRemove(v: ThreeViewer) {
v.assetManager.importer.removeEventListener('loaderCreate', this._loaderCreate as any)
return super.onRemove(v)
}
}


export const gltfKhrPbrSpecularGlossinessConverter = (confirm?: (s: string)=>Promise<boolean>, extensions?: (typeof Extension)[])=>(parser: GLTFParser)=>({
name: 'KHR_materials_pbrSpecularGlossiness',
beforeRoot: async() => {
try {
if (!parser.json.extensionsUsed || !parser.json.extensionsUsed.includes('KHR_materials_pbrSpecularGlossiness')) return
const doConfirm = parser.importOptions?.confirmSpecGlossConversion ?? true
if (doConfirm && confirm && !await confirm('Convert KHR_materials_pbrSpecularGlossiness to KHR_materials_pbrMetallicRoughness?')) return

const json = parser.json
const io = new WebIO().registerExtensions(ALL_EXTENSIONS).registerExtensions(extensions ?? [])

if (parser.extensions.KHR_draco_mesh_compression) {
const dracoLoader = parser.extensions.KHR_draco_mesh_compression.dracoLoader as DRACOLoader2
if (!dracoLoader.isDRACOLoader2) {
console.error('gltfKhrPbrSpecularGlossinessConverter: DRACOLoader2 required')
return
}
const decoder = await dracoLoader.initDecoder()
io.registerDependencies({
// 'draco3d.encoder': libs[0],
['draco3d.decoder']: decoder,
})
}

const document = await io.readJSON({
json, resources: {
['@glb.bin']: new Uint8Array(parser.extensions.KHR_binary_glTF?.body),
},
})


// Convert materials.
await document.transform(metalRough())

// no need to compress
if (parser.extensions.KHR_draco_mesh_compression) {
document.getRoot().listExtensionsUsed().find(e => e.extensionName === 'KHR_draco_mesh_compression')?.dispose()
}

// Write back to GLB.
const res = await io.writeBinary(document)
const binaryExtension = new GLTFBinaryExtension(res.buffer as any)
parser.extensions.KHR_binary_glTF = binaryExtension
parser.json = JSON.parse(binaryExtension.content)

// this doesn't work for some reason
// const res = await io.writeJSON(document, {format: Format.GLB})
// parser.extensions.KHR_binary_glTF.data = res.resources['@glb.bin'].buffer as any
// parser.extensions.KHR_binary_glTF.content = res.json
// parser.json = res.json
} catch (e) {
console.error(e)
return
}
},
})

declare module 'threepipe'{
interface ImportAddOptions{
/**
* Whether to confirm the conversion of specular glossiness materials to metallic roughness.
* @default true
*/
confirmSpecGlossConversion?: boolean
}
}

+ 2
- 1
plugins/gltf-transform/src/index.ts Ver fichero

@@ -1,2 +1,3 @@
export {GLTFDracoExporter, createGenericExtensionClass} from './GLTFDracoExporter'
export {GLTFDracoExportPlugin} from './GLTFDracoExportPlugin'
export {GLTFDracoExportPlugin, EncoderMethod} from './GLTFDracoExportPlugin'
export {GLTFSpecGlossinessConverterPlugin, gltfKhrPbrSpecularGlossinessConverter} from './GLTFSpecGlossinessConverterPlugin'

+ 49
- 3
website/package/plugin-gltf-transform.md Ver fichero

@@ -11,9 +11,6 @@ next:

# @threepipe/plugin-gltf-transform

Exports [GLTFDracoExportPlugin](https://threepipe.org/plugins/gltf-transform/docs/classes/GLTFDracoExportPlugin.html) that extends the default gltf exporter to compress the file after export.

[Example](https://threepipe.org/examples/#glb-draco-export/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/src/plugins/gltf-transform/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/gltf-transform/docs)

@@ -23,6 +20,12 @@ Exports [GLTFDracoExportPlugin](https://threepipe.org/plugins/gltf-transform/doc
npm install @threepipe/plugin-gltf-transform
```

## GLTFDracoExportPlugin

Exports [GLTFDracoExportPlugin](https://threepipe.org/plugins/gltf-transform/docs/classes/GLTFDracoExportPlugin.html) that extends the default gltf exporter to compress the file (using [KHR_draco_mesh_compression](https://github.com/KhronosGroup/gltf/tree/main/extensions/2.0/Khronos/KHR_draco_mesh_compression)) after export.

[Example](https://threepipe.org/examples/#glb-draco-export/) &mdash;

To use, simply add the plugin to the viewer and export using the `viewer.export` or `viewer.exportScene` functions. This also adds UI options to `AssetExporterPlugin` which are used when exporting using the plugin or using `viewer.exportScene`

The plugin overloads the default gltf exporter in the asset manager with `GLTFDracoExporter`. Using the [gltf-transform](https://gltf-transform.donmccurdy.com/) library, it compresses the exported gltf file using the [khr_draco_mesh_compression](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md) extension.
@@ -47,3 +50,46 @@ const blob = await viewer.exportScene({
// download the file
downloadBlob(blob, 'scene.glb')
```

## GLTFSpecGlossinessConverterPlugin

[GLTFSpecGlossinessConverterPlugin](https://threepipe.org/plugins/gltf-transform/docs/classes/GLTFSpecGlossinessConverterPlugin.html) that extends the default gltf exporter to compress the file after export.

[Example](https://threepipe.org/examples/#gltf-spec-gloss-import/)

```bash
npm install @threepipe/plugin-gltf-transform
```

Plugin that adds a gltf loader extension that automatically converts GLTF files with specular glossiness materials ([KHR_materials_pbrSpecularGlossiness](https://kcoley.github.io/glTF/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/)) to metallic roughness during import.

To use this plugin, simply add it to the viewer and import a file with `viewer.load` with specular glossiness materials.

If `confirm` is set to true, a confirmation dialog will be shown before the conversion.

To disable confirmation while loading a specific file, it can be passed as an option to `viewer.load`:

Sample Usage:

```typescript
import {ThreeViewer, downloadBlob} from 'threepipe'
import {GLTFDracoExportPlugin, GLTFSpecGlossinessConverterPlugin} from '@threepipe/plugin-gltf-transform'

const viewer = new ThreeViewer({...})
viewer.addPluginSync(GLTFDracoExportPlugin)
const plugin = viewer.addPluginSync(GLTFSpecGlossinessConverterPlugin) // it requires GLTFDracoExportPlugin

plugin.confirm = true // show a confirmation dialog before conversion
// customize the confirmation message
plugin.confirmMessage = "Convert KHR_materials_pbrSpecularGlossiness to KHR_materials_pbrMetallicRoughness?"

await viewer.load('file.glb', {
autoScale: true,
autoCenter: true,
confirmSpecGlossConversion: false, // prevents the confirmation dialog while loading this file, even if set to true in the plugin
})
```

::: tip
The plugin uses `viewer.dialog` API to show the confirmation dialog. If you want to customize the dialog, you can use the `viewer.dialog` API to set a custom dialog component.
:::

Cargando…
Cancelar
Guardar