| @@ -104,6 +104,7 @@ To make changes and run the example, click on the CodePen button on the top righ | |||
| - [Packages](#threepipe-packages) | |||
| - [@threepipe/plugin-tweakpane](#threepipeplugin-tweakpane) Tweakpane UI Plugin | |||
| - [@threepipe/plugin-tweakpane-editor](#threepipeplugin-tweakpane-editor) - Tweakpane Editor Plugin | |||
| - [@threepipe/plugin-extra-importers](#threepipeplugin-extra-importers) - Plugin for loading even more file types. | |||
| ## Getting Started | |||
| @@ -222,6 +223,9 @@ Plugins can add additional formats: | |||
| * ktx - Using [KTXLoadPlugin](#KTXLoadPlugin) | |||
| * ktx2 - Using [KTX2LoadPlugin](#KTX2LoadPlugin) | |||
| Plugins to support more model formats are available in the package [@threepipe/plugin-extra-importers](#threepipeplugin-extra-importers) including .3ds, | |||
| .3mf, .collada, .amf, .bvh, .vox, .gcode, .mdd, .pcd, .tilt, .wrl, .mpd, .vtk, .xyz | |||
| ## Loading files | |||
| ThreePipe uses the [AssetManager](https://threepipe.org/docs/classes/AssetManager.html) to load files. | |||
| @@ -1938,7 +1942,7 @@ ThreePipe has a simple plugin system that allows you to easily add new features | |||
| ## TonemapPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#tonemap-plugin/ | |||
| @@ -1956,7 +1960,7 @@ TonemapPlugin is added by default in ThreeViewer unless `tonemap` is set to `fal | |||
| ## DropzonePlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#dropzone-plugin/ | |||
| @@ -2002,7 +2006,7 @@ const viewer = new ThreeViewer({ | |||
| ## ProgressivePlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#progressive-plugin/ | |||
| @@ -2016,7 +2020,7 @@ This is used as a dependency in other plugins for progressive rendering effect w | |||
| ## DepthBufferPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#depth-buffer-plugin/ | |||
| @@ -2042,7 +2046,7 @@ The depth values are based on camera near far values, which are controlled autom | |||
| ## NormalBufferPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#normal-buffer-plugin/ | |||
| @@ -2074,7 +2078,7 @@ todo | |||
| ## GLTFAnimationPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#gltf-animation-plugin/ | |||
| @@ -2095,7 +2099,7 @@ To play individual animations, with custom choreography, use the {@link GLTFAnim | |||
| ## PopmotionPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#popmotion-plugin/ | |||
| @@ -2151,7 +2155,7 @@ Note: The animation is started when the animate or animateAsync function is call | |||
| ## RenderTargetPreviewPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#render-target-preview/ | |||
| @@ -2176,7 +2180,7 @@ previewPlugin.addTarget(()=>normalPlugin.target, 'normal', false, false) | |||
| ## GeometryUVPreviewPlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#geometry-uv-preview/ | |||
| @@ -2201,7 +2205,7 @@ previewPlugin.addGeometry(geometry, 'sphere') | |||
| ## FrameFadePlugin | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#frame-fade-plugin/ | |||
| @@ -2344,7 +2348,7 @@ These add support for integrating with other libraries, adding new features, and | |||
| ## @threepipe/plugin-tweakpane | |||
| Tewakpane UI plugin for ThreePipe | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#viewer-uiconfig/ | |||
| @@ -2381,7 +2385,7 @@ plugin.setupPlugins(TonemapPlugin, DropzonePlugin) | |||
| Tweakpane Editor Plugin for ThreePipe | |||
| todo: image | |||
| [//]: # (todo: image) | |||
| Example: https://threepipe.org/examples/#tweakpane-editor/ | |||
| @@ -2422,3 +2426,51 @@ editor.loadPlugins({ | |||
| ['Debug']: [RenderTargetPreviewPlugin], | |||
| }) | |||
| ``` | |||
| ## @threepipe/plugin-extra-importers | |||
| Exports several plugins to add support for various file types. | |||
| Example: https://threepipe.org/examples/#extra-importer-plugins/ | |||
| Source Code: [plugins/extra-importers/src/index.ts](plugins/extra-importers/src/index.ts) | |||
| API Reference: [@threepipe/plugin-extra-importers](https://threepipe.org/plugins/extra-importers/docs) | |||
| NPM: `npm install @threepipe/plugin-extra-importers` | |||
| CDN: https://threepipe.org/plugins/extra-importers/dist/index.mjs | |||
| This package exports several plugins to add support for several file types using the following plugins | |||
| - [TDSLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TDSLoadPlugin.html) - Load 3DS Max (.3ds) files | |||
| - [ThreeMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ThreeMFLoadPlugin.html) - Load 3MF (.3mf) files | |||
| - [ColladaLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/ColladaLoadPlugin.html) - Load Collada (.dae) files | |||
| - [AMFLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/AMFLoadPlugin.html) - Load AMF (.amf) files | |||
| - [BVHLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/BVHLoadPlugin.html) - Load BVH (.bvh) files | |||
| - [VOXLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VOXLoadPlugin.html) - Load MagicaVoxel (.vox) files | |||
| - [GCodeLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/GCodeLoadPlugin.html) - Load GCode (.gcode) files | |||
| - [MDDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MDDLoadPlugin.html) - Load MDD (.mdd) files | |||
| - [PCDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/PCDLoadPlugin.html) - Load Point cloud data (.pcd) files | |||
| - [TiltLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/TiltLoadPlugin.html) - Load Tilt Brush (.tilt) files | |||
| - [VRMLLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VRMLLoadPlugin.html) - Load VRML (.wrl) files | |||
| - [MPDLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/MPDLoadPlugin.html) - Load LDraw (.mpd) files | |||
| - [VTKLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/VTKLoadPlugin.html) - Load VTK (.vtk) files | |||
| - [XYZLoadPlugin](https://threepipe.org/plugins/extra-importers/docs/classes/XYZLoadPlugin.html) - Load XYZ (.xyz) files | |||
| To add all the plugins at once use `extraImporters`. This adds support for loading all the above file types. | |||
| ```typescript | |||
| import {ThreeViewer} from 'threepipe' | |||
| import {extraImporters} from '@threepipe/plugin-extra-importers' | |||
| const viewer = new ThreeViewer({...}) | |||
| viewer.addPluginsSync(extraImporters) | |||
| // Now load any file as is. | |||
| const model = await viewer.load<IObject3D>('file.3mf') | |||
| // To load the file as a data url, use the correct mimetype | |||
| const model1 = await viewer.load<IObject3D>('data:model/3mf;base64,...') | |||
| ``` | |||
| Remove the `<IObject3D>` if using javascript and not typescript. | |||
| @@ -0,0 +1,48 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Extra importer plugins</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": { | |||
| "three": "./../../dist/index.mjs", | |||
| "threepipe": "./../../dist/index.mjs", | |||
| "@threepipe/plugin-extra-importers": "./../../plugins/extra-importers/dist/index.mjs" | |||
| } | |||
| } | |||
| </script> | |||
| <style id="example-style"> | |||
| html, body, #canvas-container, #mcanvas { | |||
| width: 100%; | |||
| height: 100%; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| } | |||
| p{ | |||
| position: absolute; | |||
| top: 5%; | |||
| left: 50%; | |||
| transform: translate(-50%, -50%); | |||
| font-size: 1.25em; | |||
| color: #8cd55b; | |||
| font-family: sans-serif; | |||
| pointer-events: none; | |||
| } | |||
| </style> | |||
| <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"> | |||
| <p>Drop .3ds .3mf .collada .amf .bvh .vox .gcode .mdd .pcd .tilt .wrl .mpd .vtk .xyz files here</p> | |||
| <canvas id="mcanvas"></canvas> | |||
| </div> | |||
| </body> | |||
| @@ -0,0 +1,97 @@ | |||
| import {_testFinish, GLTFAnimationPlugin, HemisphereLight, ImportAddOptions, IObject3D, ThreeViewer} from 'threepipe' | |||
| import { | |||
| AMFLoadPlugin, | |||
| BVHLoadPlugin, | |||
| ColladaLoadPlugin, | |||
| GCodeLoadPlugin, | |||
| LDrawLoadPlugin, | |||
| MDDLoadPlugin, | |||
| PCDLoadPlugin, | |||
| TDSLoadPlugin, | |||
| ThreeMFLoadPlugin, | |||
| TiltLoadPlugin, | |||
| VOXLoadPlugin, | |||
| VRMLLoadPlugin, | |||
| VTKLoadPlugin, | |||
| XYZLoadPlugin, | |||
| } from '@threepipe/plugin-extra-importers' | |||
| async function init() { | |||
| const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||
| msaa: true, | |||
| dropzone: { | |||
| addOptions: { | |||
| disposeSceneObjects: true, | |||
| }, | |||
| }, | |||
| }) | |||
| viewer.addPluginsSync([ | |||
| GLTFAnimationPlugin, | |||
| TDSLoadPlugin, | |||
| ThreeMFLoadPlugin, | |||
| ColladaLoadPlugin, | |||
| AMFLoadPlugin, | |||
| GCodeLoadPlugin, | |||
| BVHLoadPlugin, | |||
| VOXLoadPlugin, | |||
| MDDLoadPlugin, | |||
| PCDLoadPlugin, | |||
| TiltLoadPlugin, | |||
| VRMLLoadPlugin, | |||
| LDrawLoadPlugin, | |||
| VTKLoadPlugin, | |||
| XYZLoadPlugin, | |||
| ]) | |||
| viewer.getPlugin(GLTFAnimationPlugin)!.autoplayOnLoad = true | |||
| viewer.scene.mainCamera.autoNearFar = false | |||
| viewer.scene.setBackgroundColor('#555555') | |||
| viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 2)) | |||
| await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr') | |||
| const urls = [ | |||
| 'https://threejs.org/examples/models/3ds/portalgun/portalgun.3ds', | |||
| 'https://threejs.org/examples/models/3mf/cube_gears.3mf', | |||
| 'https://threejs.org/examples/models/collada/elf/elf.dae', | |||
| 'https://threejs.org/examples/models/amf/rook.amf', | |||
| 'https://threejs.org/examples/models/gcode/benchy.gcode', | |||
| 'https://threejs.org/examples/models/bvh/pirouette.bvh', | |||
| 'https://threejs.org/examples/models/vox/monu10.vox', | |||
| 'https://threejs.org/examples/models/mdd/cube.mdd', | |||
| 'https://threejs.org/examples/models/pcd/binary/Zaghetto.pcd', | |||
| 'https://threejs.org/examples/models/tilt/BRUSH_DOME.tilt', | |||
| 'https://threejs.org/examples/models/ldraw/officialLibrary/models/car.ldr_Packed.mpd', | |||
| 'https://threejs.org/examples/models/vtk/bunny.vtk', | |||
| 'https://threejs.org/examples/models/vtk/cube_binary.vtp', | |||
| 'https://threejs.org/examples/models/xyz/helix_201.xyz', | |||
| ] | |||
| const options: ImportAddOptions = { | |||
| autoScale: true, | |||
| autoCenter: true, | |||
| autoScaleRadius: 0.5, | |||
| clearSceneObjects: false, | |||
| } | |||
| let i = 0 | |||
| const models = await Promise.allSettled(urls.map(async url => | |||
| viewer.load<IObject3D>(url, options).then(res => { | |||
| if (!res) return | |||
| res.position.set(i % 4 - 1.5, 0, Math.floor(i / 4) - 1.5).multiplyScalar(1) | |||
| res.setDirty() | |||
| i++ | |||
| return res | |||
| }))) | |||
| console.log(models) | |||
| } | |||
| init().then(_testFinish) | |||
| @@ -249,6 +249,7 @@ | |||
| <li><a href="./stl-load/">STL Load </a></li> | |||
| <li><a href="./ktx2-load/">KTX2 Load </a></li> | |||
| <li><a href="./ktx-load/">KTX Load </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> | |||
| </ul> | |||
| <h2 class="category">Export</h2> | |||
| <ul> | |||
| @@ -15,9 +15,11 @@ | |||
| <script type="importmap"> | |||
| { | |||
| "imports": { | |||
| "three": "./../../dist/index.mjs", | |||
| "threepipe": "./../../dist/index.mjs", | |||
| "@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs", | |||
| "@threepipe/plugin-tweakpane-editor": "./../../plugins/tweakpane-editor/dist/index.mjs" | |||
| "@threepipe/plugin-tweakpane-editor": "./../../plugins/tweakpane-editor/dist/index.mjs", | |||
| "@threepipe/plugin-extra-importers": "./../../plugins/extra-importers/dist/index.mjs" | |||
| } | |||
| } | |||
| @@ -17,10 +17,12 @@ import { | |||
| STLLoadPlugin, | |||
| ThreeViewer, | |||
| TonemapPlugin, | |||
| USDZLoadPlugin, | |||
| ViewerUiConfigPlugin, | |||
| } from 'threepipe' | |||
| import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane' | |||
| import {TweakpaneEditorPlugin} from '@threepipe/plugin-tweakpane-editor' | |||
| import {extraImportPlugins} from '@threepipe/plugin-extra-importers' | |||
| async function init() { | |||
| @@ -49,11 +51,13 @@ async function init() { | |||
| new NormalBufferPlugin(HalfFloatType, false), | |||
| new RenderTargetPreviewPlugin(false), | |||
| new FrameFadePlugin(), | |||
| new KTX2LoadPlugin(), | |||
| new KTXLoadPlugin(), | |||
| new PLYLoadPlugin(), | |||
| new Rhino3dmLoadPlugin(), | |||
| new STLLoadPlugin(), | |||
| KTX2LoadPlugin, | |||
| KTXLoadPlugin, | |||
| PLYLoadPlugin, | |||
| Rhino3dmLoadPlugin, | |||
| STLLoadPlugin, | |||
| USDZLoadPlugin, | |||
| ...extraImportPlugins, | |||
| ]) | |||
| const rt = viewer.getOrAddPluginSync(RenderTargetPreviewPlugin) | |||
| @@ -1,15 +1,15 @@ | |||
| { | |||
| "name": "threepipe", | |||
| "version": "0.0.13-dev.1", | |||
| "version": "0.0.14", | |||
| "lockfileVersion": 2, | |||
| "requires": true, | |||
| "packages": { | |||
| "": { | |||
| "name": "threepipe", | |||
| "version": "0.0.13-dev.1", | |||
| "version": "0.0.14", | |||
| "license": "Apache-2.0", | |||
| "dependencies": { | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1013/package.tgz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz", | |||
| "@types/webxr": "^0.5.1", | |||
| "@types/wicg-file-system-access": "^2020.9.5", | |||
| "ts-browser-helpers": "^0.8.0" | |||
| @@ -663,9 +663,9 @@ | |||
| "dev": true | |||
| }, | |||
| "node_modules/@types/three": { | |||
| "version": "0.152.1013", | |||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1013/package.tgz", | |||
| "integrity": "sha512-VzrOsb0opD8o9/XKNtiRJiEoe29SPtpJC1dnpN7Da7nl3r71dwpMlsK2uWOpgMVgqJHvdlMQ3qt9Z51mbkW3Dw==", | |||
| "version": "0.152.1014", | |||
| "resolved": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz", | |||
| "integrity": "sha512-1sR9iALwIFtfSXxJshAglvMjLy5litWF2hTbh0JQ+44d+21D2t0nppRZBnWtNQP5XsBYdhCNygnDQNeF6kd+NQ==", | |||
| "dependencies": { | |||
| "@tweenjs/tween.js": "~18.6.4", | |||
| "fflate": "~0.6.9", | |||
| @@ -10863,8 +10863,8 @@ | |||
| "dev": true | |||
| }, | |||
| "@types/three": { | |||
| "version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1013/package.tgz", | |||
| "integrity": "sha512-VzrOsb0opD8o9/XKNtiRJiEoe29SPtpJC1dnpN7Da7nl3r71dwpMlsK2uWOpgMVgqJHvdlMQ3qt9Z51mbkW3Dw==", | |||
| "version": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz", | |||
| "integrity": "sha512-1sR9iALwIFtfSXxJshAglvMjLy5litWF2hTbh0JQ+44d+21D2t0nppRZBnWtNQP5XsBYdhCNygnDQNeF6kd+NQ==", | |||
| "requires": { | |||
| "@tweenjs/tween.js": "~18.6.4", | |||
| "fflate": "~0.6.9", | |||
| @@ -1,6 +1,6 @@ | |||
| { | |||
| "name": "threepipe", | |||
| "version": "0.0.13-dev.1", | |||
| "version": "0.0.13", | |||
| "description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.", | |||
| "main": "src/index.ts", | |||
| "module": "dist/index.mjs", | |||
| @@ -102,7 +102,7 @@ | |||
| "popmotion": "^11.0.5" | |||
| }, | |||
| "dependencies": { | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1013/package.tgz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz", | |||
| "@types/webxr": "^0.5.1", | |||
| "@types/wicg-file-system-access": "^2020.9.5", | |||
| "ts-browser-helpers": "^0.8.0" | |||
| @@ -113,8 +113,8 @@ | |||
| "ts-browser-helpers": "^0.8.0", | |||
| "three": "https://github.com/repalash/three.js-modded/releases/download/v0.152.2012/package.tgz", | |||
| "three-f": "https://github.com/repalash/three.js-modded/archive/refs/tags/v0.152.2012.tar.gz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1013/package.tgz", | |||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1013.tar.gz", | |||
| "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.152.1014/package.tgz", | |||
| "@types/three-f": "https://github.com/repalash/three-ts-types/archive/refs/tags/v0.152.1014.tar.gz", | |||
| "@types/three-pkg": "https://gitpkg.now.sh/repalash/three-ts-types/types/three?modded_three" | |||
| }, | |||
| "local_dependencies": { | |||
| @@ -0,0 +1,30 @@ | |||
| { | |||
| "name": "@threepipe/plugins-extra-importers", | |||
| "version": "0.1.0", | |||
| "lockfileVersion": 2, | |||
| "requires": true, | |||
| "packages": { | |||
| "": { | |||
| "name": "@threepipe/plugins-extra-importers", | |||
| "version": "0.1.0", | |||
| "license": "Apache-2.0", | |||
| "dependencies": { | |||
| "threepipe": "file:./../../src/" | |||
| }, | |||
| "devDependencies": {} | |||
| }, | |||
| "../../src": {}, | |||
| "../tweakpane/src": { | |||
| "extraneous": true | |||
| }, | |||
| "node_modules/threepipe": { | |||
| "resolved": "../../src", | |||
| "link": true | |||
| } | |||
| }, | |||
| "dependencies": { | |||
| "threepipe": { | |||
| "version": "file:../../src" | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,58 @@ | |||
| { | |||
| "name": "@threepipe/plugins-extra-importers", | |||
| "description": "Extra Threepipe plugins for importing several file types.", | |||
| "version": "0.1.0", | |||
| "devDependencies": { | |||
| }, | |||
| "dependencies": { | |||
| "threepipe": "file:./../../src/" | |||
| }, | |||
| "clean-package": { | |||
| "remove": [ | |||
| "clean-package", | |||
| "scripts", | |||
| "devDependencies", | |||
| "//", | |||
| "markdown-to-html" | |||
| ], | |||
| "replace": { | |||
| "dependencies": { | |||
| "threepipe": "^0.0.14" | |||
| } | |||
| } | |||
| }, | |||
| "type": "module", | |||
| "main": "dist/index.js", | |||
| "module": "dist/index.mjs", | |||
| "types": "dist/index.d.ts", | |||
| "files": [ | |||
| "dist", | |||
| "src" | |||
| ], | |||
| "scripts": { | |||
| "new:pack": "npm run prepare && clean-package && npm pack && clean-package restore", | |||
| "new:publish": "npm run prepare && clean-package && npm publish --access public && clean-package restore", | |||
| "prepare": "npm run build", | |||
| "build": "rimraf dist && NODE_ENV=production rollup -c", | |||
| "dev": "rollup -c -w", | |||
| "docs": "rimraf docs && npx typedoc" | |||
| }, | |||
| "author": "repalash <palash@shaders.app>", | |||
| "license": "Apache-2.0", | |||
| "keywords": [ | |||
| "three", | |||
| "three.js", | |||
| "threepipe", | |||
| "tweakpane", | |||
| "editor", | |||
| "plugin" | |||
| ], | |||
| "bugs": { | |||
| "url": "https://github.com/repalash/threepipe/issues" | |||
| }, | |||
| "homepage": "https://github.com/repalash/threepipe#readme", | |||
| "repository": { | |||
| "type": "git", | |||
| "url": "git://github.com/repalash/threepipe.git" | |||
| } | |||
| } | |||
| @@ -0,0 +1,97 @@ | |||
| // rollup.config.js | |||
| import commonjs from '@rollup/plugin-commonjs'; | |||
| import json from '@rollup/plugin-json'; | |||
| import resolve from '@rollup/plugin-node-resolve'; | |||
| import typescript from '@rollup/plugin-typescript'; | |||
| import license from 'rollup-plugin-license' | |||
| import packageJson from './package.json' assert {type: 'json'}; | |||
| import path from 'path' | |||
| import {fileURLToPath} from 'url'; | |||
| import postcss from 'rollup-plugin-postcss' | |||
| import replace from 'rollup-plugin-replace' | |||
| import terser from "@rollup/plugin-terser"; | |||
| const __filename = fileURLToPath(import.meta.url); | |||
| const __dirname = path.dirname(__filename); | |||
| const {name, version, author} = packageJson | |||
| // const {main, module, browser} = packageJson["clean-package"].replace | |||
| const isProduction = process.env.NODE_ENV === 'production' | |||
| const settings = { | |||
| globals: { | |||
| "threepipe": "threepipe", | |||
| "three": "threepipe" | |||
| }, | |||
| sourcemap: true | |||
| } | |||
| export default { | |||
| input: './src/index.ts', | |||
| output: [ | |||
| // { | |||
| // file: main, | |||
| // name: main, | |||
| // ...settings, | |||
| // format: 'cjs', | |||
| // plugins: [ | |||
| // isProduction && terser() | |||
| // ] | |||
| // }, | |||
| { | |||
| file: './dist/index.mjs', | |||
| ...settings, | |||
| name: name, | |||
| format: 'es', | |||
| plugins: [ | |||
| isProduction && terser() | |||
| ] | |||
| }, | |||
| { | |||
| file: './dist/index.js', | |||
| ...settings, | |||
| name: name, | |||
| format: 'umd', | |||
| plugins: [ | |||
| isProduction && terser() | |||
| ] | |||
| } | |||
| ], | |||
| external: Object.keys(settings.globals), | |||
| plugins: [ | |||
| replace({ | |||
| // If you would like DEV messages, specify 'development' | |||
| // Otherwise use 'production' | |||
| 'process.env.NODE_ENV': JSON.stringify('production') // for tippy.js | |||
| }), | |||
| postcss({ | |||
| modules: false, | |||
| autoModules: true, // todo; issues with typescript import css, because inject is false | |||
| inject: false, | |||
| minimize: isProduction, | |||
| // Or with custom options for `postcss-modules` | |||
| }), | |||
| json(), | |||
| resolve({}), | |||
| typescript({ | |||
| }), | |||
| commonjs({ | |||
| include: 'node_modules/**', | |||
| extensions: ['.js'], | |||
| ignoreGlobal: false, | |||
| sourceMap: false | |||
| }), | |||
| license({ | |||
| banner: ` | |||
| @license | |||
| ${name} v${version} | |||
| Copyright 2022<%= moment().format('YYYY') > 2022 ? '-' + moment().format('YYYY') : null %> ${author} | |||
| ${packageJson.license} License | |||
| `, | |||
| thirdParty: { | |||
| output: path.join(__dirname, 'dist', 'dependencies.txt'), | |||
| includePrivate: true, // Default is false. | |||
| }, | |||
| }) | |||
| ] | |||
| } | |||
| @@ -0,0 +1,36 @@ | |||
| declare module '*.txt' { | |||
| const content: string | |||
| export default content | |||
| } | |||
| declare module '*.glsl' { | |||
| const content: string | |||
| export default content | |||
| } | |||
| declare module '*.vert' { | |||
| const content: string | |||
| export default content | |||
| } | |||
| declare module '*.frag' { | |||
| const content: string | |||
| export default content | |||
| } | |||
| declare module '*.module.scss' { | |||
| const content: any | |||
| export default content | |||
| export const stylesheet: string | |||
| } | |||
| declare module '*.module.css' { | |||
| const content: any | |||
| export default content | |||
| export const stylesheet: string | |||
| } | |||
| declare module '*.css' { | |||
| const content: string | |||
| export default content | |||
| } | |||
| // export {} | |||
| // hack for typedoc | |||
| // eslint-disable-next-line @typescript-eslint/naming-convention | |||
| // declare type OffscreenCanvas = HTMLCanvasElement | |||
| @@ -0,0 +1,244 @@ | |||
| import { | |||
| AnyOptions, | |||
| BaseImporterPlugin, | |||
| BoxGeometry, | |||
| BufferGeometry, | |||
| Color, | |||
| Group, | |||
| ILoader, | |||
| Importer, | |||
| Mesh, | |||
| Object3D, | |||
| PhysicalMaterial, | |||
| Points, | |||
| PointsMaterial, | |||
| Scene, | |||
| SkeletonHelper, | |||
| } from 'threepipe' | |||
| import {TDSLoader} from 'three/examples/jsm/loaders/TDSLoader.js' | |||
| import {ThreeMFLoader} from 'three/examples/jsm/loaders/3MFLoader.js' | |||
| import {Collada, ColladaLoader} from 'three/examples/jsm/loaders/ColladaLoader.js' | |||
| import {AMFLoader} from 'three/examples/jsm/loaders/AMFLoader.js' | |||
| import {GCodeLoader} from 'three/examples/jsm/loaders/GCodeLoader.js' | |||
| import {BVH, BVHLoader} from 'three/examples/jsm/loaders/BVHLoader.js' | |||
| import {Chunk, VOXLoader, VOXMesh} from 'three/examples/jsm/loaders/VOXLoader.js' | |||
| import {MDD, MDDLoader} from 'three/examples/jsm/loaders/MDDLoader.js' | |||
| import {PCDLoader} from 'three/examples/jsm/loaders/PCDLoader.js' | |||
| import {TiltLoader} from 'three/examples/jsm/loaders/TiltLoader.js' | |||
| import {VRMLLoader} from 'three/examples/jsm/loaders/VRMLLoader.js' | |||
| import {LDrawLoader} from 'three/examples/jsm/loaders/LDrawLoader.js' | |||
| import {VTKLoader} from 'three/examples/jsm/loaders/VTKLoader.js' | |||
| import {XYZLoader} from 'three/examples/jsm/loaders/XYZLoader.js' | |||
| // 3ds | |||
| /** | |||
| * Adds support for loading Autodesk 3ds `.3ds`, `application/x-3ds` files and data uris | |||
| */ | |||
| export class TDSLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'TDSLoadPlugin' | |||
| protected _importer = new Importer(TDSLoader, ['3ds'], ['image/x-3ds', 'application/x-3ds'], false) | |||
| } | |||
| // 3mf | |||
| /** | |||
| * Adds support for loading `.3mf`, `model/3mf` files and data uris | |||
| */ | |||
| export class ThreeMFLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'ThreeMFLoadPlugin' | |||
| protected _importer = new Importer(ThreeMFLoader, ['3mf'], ['model/3mf'], false) | |||
| } | |||
| // collada | |||
| /** | |||
| * Adds support for loading Collada `.dae`, `model/vnd.collada+xml` files and data uris | |||
| */ | |||
| export class ColladaLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'ColladaLoadPlugin' | |||
| protected _importer = new Importer(class extends ColladaLoader implements ILoader { | |||
| transform(res: Collada, _: AnyOptions): Scene { | |||
| res.scene.userData.kinematics = res.kinematics | |||
| res.scene.userData.library = res.library | |||
| return res.scene | |||
| } | |||
| }, ['dae'], ['model/vnd.collada+xml'], false) | |||
| } | |||
| // amf | |||
| /** | |||
| * Adds support for loading Additive Manufacturing files `.amf`, `application/amf` files and data uris | |||
| */ | |||
| export class AMFLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'AMFLoadPlugin' | |||
| protected _importer = new Importer(AMFLoader, ['amf'], ['application/amf'], false) | |||
| } | |||
| // gcode | |||
| /** | |||
| * Adds support for loading `.gcode`, `application/gcode` files and data uris | |||
| */ | |||
| export class GCodeLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'GCodeLoadPlugin' | |||
| protected _importer = new Importer(GCodeLoader, ['gcode'], ['application/gcode'], false) | |||
| } | |||
| // bvh | |||
| /** | |||
| * Adds support for loading `.bvh`, `application/bvh` files and data uris | |||
| */ | |||
| export class BVHLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'BVHLoadPlugin' | |||
| protected _importer = new Importer(class extends BVHLoader implements ILoader { | |||
| transform(res: BVH, _: AnyOptions): Object3D { | |||
| const obj = new Object3D() | |||
| const helper = new SkeletonHelper(res.skeleton.bones[0]) | |||
| obj.add(res.skeleton.bones[0]) | |||
| obj.add(helper) | |||
| obj.animations = [res.clip] | |||
| obj.scale.set(0.1, 0.1, 0.1) // todo: autoScale and autoCenter not working | |||
| return obj | |||
| } | |||
| }, ['bvh'], ['application/bvh'], false) | |||
| } | |||
| // vox | |||
| /** | |||
| * Adds support for loading Magica Voxel `.vox` files and data uris | |||
| */ | |||
| export class VOXLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'VOXLoadPlugin' | |||
| protected _importer = new Importer(class extends VOXLoader implements ILoader { | |||
| transform(chunks: Chunk[], _: AnyOptions): Object3D { | |||
| const obj = new Object3D() | |||
| for (const chunk of chunks) { | |||
| // displayPalette( chunk.palette ); | |||
| const mesh = new VOXMesh(chunk) | |||
| mesh.scale.setScalar(0.0015) | |||
| obj.add(mesh) | |||
| } | |||
| return obj | |||
| } | |||
| }, ['vox'], [''], false) | |||
| } | |||
| // mdd | |||
| /** | |||
| * Adds support for loading animation `.mdd`, `application/mdd` files and data uris | |||
| */ | |||
| export class MDDLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'MDDLoadPlugin' | |||
| protected _importer = new Importer(class extends MDDLoader implements ILoader { | |||
| transform(res: MDD, _: AnyOptions): Object3D { | |||
| const morphTargets = res.morphTargets | |||
| const geometry = new BoxGeometry() | |||
| geometry.morphAttributes.position = morphTargets // apply morph targets | |||
| const mesh = new Mesh(geometry, new PhysicalMaterial()) | |||
| const obj = new Object3D() | |||
| obj.add(mesh) | |||
| res.clip.tracks.forEach(track=> track.name = mesh.uuid + track.name) | |||
| obj.animations = [res.clip] | |||
| return obj | |||
| } | |||
| }, ['mdd'], ['application/mdd'], false) | |||
| } | |||
| // pcd | |||
| /** | |||
| * Adds support for loading Point cloud data `.pcd`, `application/pcd` files and data uris | |||
| */ | |||
| export class PCDLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'PCDLoadPlugin' | |||
| protected _importer = new Importer(class extends PCDLoader implements ILoader { | |||
| transform(points: Points, options: AnyOptions): any { | |||
| if (options.autoCenter) points.geometry.center() | |||
| points.geometry.rotateX(Math.PI) | |||
| return points | |||
| } | |||
| }, ['pcd'], ['application/pcd'], false) | |||
| } | |||
| // tilt | |||
| /** | |||
| * Adds support for loading Tilt brush `.tilt`, `application/tilt` files and data uris | |||
| */ | |||
| export class TiltLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'TiltLoadPlugin' | |||
| protected _importer = new Importer(TiltLoader, ['tilt'], ['application/tilt'], false) | |||
| } | |||
| // vrml | |||
| /** | |||
| * Adds support for loading VRML `.wrl`, `model/vrml` files and data uris | |||
| */ | |||
| export class VRMLLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'VRMLLoadPlugin' | |||
| protected _importer = new Importer(VRMLLoader, ['wrl'], ['model/vrml'], false) | |||
| } | |||
| // ldraw | |||
| /** | |||
| * Adds support for loading LDraw `.mpd`, `application/mpd` files and data uris. see https://ldraw.org | |||
| */ | |||
| export class LDrawLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'LDrawLoadPlugin' | |||
| protected _importer = new Importer(class extends LDrawLoader implements ILoader { | |||
| transform(res: Group, _: AnyOptions): any { | |||
| // Convert from LDraw coordinates: rotate 180 degrees around OX | |||
| res.rotation.x = Math.PI | |||
| return res | |||
| } | |||
| }, ['mpd'], ['application/ldraw'], false) | |||
| } | |||
| // vtk | |||
| /** | |||
| * Adds support for loading VTK `.vtk`, '.vtp', `application/vtk` files and data uris | |||
| **/ | |||
| export class VTKLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'VTKLoadPlugin' | |||
| protected _importer = new Importer(class extends VTKLoader implements ILoader { | |||
| transform(res: BufferGeometry, _: AnyOptions): Mesh|undefined { | |||
| if (!res.attributes?.normal) res.computeVertexNormals() | |||
| // todo set mesh name from options/path | |||
| return res ? new Mesh(res, new PhysicalMaterial({ | |||
| color: new Color(1, 1, 1), | |||
| vertexColors: res.hasAttribute('color'), | |||
| })) : undefined | |||
| } | |||
| }, ['vtk', 'vtp'], ['application/vtk'], false) | |||
| } | |||
| // xyz | |||
| /** | |||
| * Adds support for loading XYZ `.xyz`, `text/plain+xyz` files and data uris | |||
| */ | |||
| export class XYZLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'XYZLoadPlugin' | |||
| protected _importer = new Importer(class extends XYZLoader implements ILoader { | |||
| transform(res: BufferGeometry, options: AnyOptions): Points|undefined { | |||
| if (!res.attributes?.normal) res.computeVertexNormals() | |||
| if (options.autoCenter) res.center() | |||
| return res ? new Points(res, new PointsMaterial({ | |||
| size: 0.1, | |||
| vertexColors: res.hasAttribute('color'), | |||
| })) : undefined | |||
| } | |||
| }, ['xyz'], ['text/plain+xyz'], false) | |||
| } | |||
| export const extraImportPlugins = [ | |||
| TDSLoadPlugin, | |||
| ThreeMFLoadPlugin, | |||
| ColladaLoadPlugin, | |||
| AMFLoadPlugin, | |||
| GCodeLoadPlugin, | |||
| BVHLoadPlugin, | |||
| VOXLoadPlugin, | |||
| MDDLoadPlugin, | |||
| PCDLoadPlugin, | |||
| TiltLoadPlugin, | |||
| VRMLLoadPlugin, | |||
| LDrawLoadPlugin, | |||
| VTKLoadPlugin, | |||
| XYZLoadPlugin, | |||
| ] as const | |||
| @@ -0,0 +1,41 @@ | |||
| { | |||
| "compilerOptions": { | |||
| "baseUrl": "./src", | |||
| "rootDir": "./src", | |||
| "allowJs": false, | |||
| "checkJs": false, | |||
| "skipLibCheck": true, | |||
| "allowSyntheticDefaultImports": true, | |||
| "experimentalDecorators": true, | |||
| "isolatedModules": true, | |||
| "module": "es2020", | |||
| "noImplicitAny": true, | |||
| "declaration": true, | |||
| "declarationMap": true, | |||
| "declarationDir": "dist", | |||
| "outDir": "dist", | |||
| "noImplicitThis": true, | |||
| "noUnusedLocals": true, | |||
| "noUnusedParameters": true, | |||
| "removeComments": false, | |||
| "preserveConstEnums": true, | |||
| "moduleResolution": "node", | |||
| "emitDecoratorMetadata": false, | |||
| "sourceMap": true, | |||
| "target": "ES2020", | |||
| "strictNullChecks": true, | |||
| "lib": [ | |||
| "es2020", | |||
| "esnext", | |||
| "dom" | |||
| ] | |||
| }, | |||
| "include": [ | |||
| "src/**/*" | |||
| ], | |||
| "exclude": [ | |||
| "node_modules", | |||
| "**/*.spec.ts", | |||
| "dist" | |||
| ] | |||
| } | |||
| @@ -0,0 +1,10 @@ | |||
| { | |||
| "extends": [ | |||
| "../../typedoc.json" | |||
| ], | |||
| "entryPoints": [ | |||
| "src/index.ts" | |||
| ], | |||
| "name": "Threepipe Extra Importer Plugins", | |||
| "readme": "none" | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| { | |||
| "name": "threepipe-plugin-template-rollup", | |||
| "description": "Sample Threepipe plugin using rollup", | |||
| "version": "0.0.1", | |||
| "version": "0.1.0", | |||
| "devDependencies": { | |||
| }, | |||
| "dependencies": { | |||
| @@ -1,5 +1,6 @@ | |||
| import { | |||
| CustomContextMenu, | |||
| DataTexture, | |||
| EXRExporter2, | |||
| FloatType, | |||
| generateUUID, | |||
| @@ -20,7 +21,6 @@ import { | |||
| } from 'threepipe' | |||
| import type {UiObjectConfig} from 'uiconfig.js' | |||
| import {TweakpaneUiPlugin} from './TweakpaneUiPlugin' | |||
| import {DataTexture} from 'three' | |||
| const staticData = { | |||
| placeholderVal: 'placeholder', | |||
| @@ -0,0 +1,24 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {Importer} from '../../assetmanager' | |||
| export abstract class BaseImporterPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof BaseImporterPlugin | |||
| public static readonly PluginType: string | |||
| protected abstract _importer: Importer | |||
| toJSON: any = null // disable serialization | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| } | |||
| @@ -1,19 +1,18 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {ThreeViewer} from '../../viewer' | |||
| import {GLTFWriter2, ILoader, Importer, ImportResultExtras} from '../../assetmanager' | |||
| import {KTX2Loader} from 'three/examples/jsm/loaders/KTX2Loader.js' | |||
| import {CompressedTexture} from 'three' | |||
| import {serializeTextureInExtras} from '../../utils' | |||
| import {ITexture} from '../../core' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading Compressed Textures of format `.ktx2`, `image/ktx2` files and data uris. | |||
| * @category Plugins | |||
| */ | |||
| export class KTX2LoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof KTX2LoadPlugin | |||
| export class KTX2LoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'KTX2LoadPlugin' | |||
| private _importer = new Importer(KTX2Loader2, ['ktx2'], ['image/ktx2'], false) | |||
| protected _importer = new Importer(KTX2Loader2, ['ktx2'], ['image/ktx2'], false) | |||
| public static TRANSCODER_LIBRARY_PATH = 'https://cdn.jsdelivr.net/gh/BinomialLLC/basis_universal@1.16.4/webgl/transcoder/build/' | |||
| @@ -21,20 +20,17 @@ export class KTX2LoadPlugin implements IViewerPluginSync { | |||
| this._importer.onCtor = (l: KTX2Loader2) => l | |||
| .setTranscoderPath(KTX2LoadPlugin.TRANSCODER_LIBRARY_PATH) | |||
| .detectSupport(viewer.renderManager.renderer) | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| super.onAdded(viewer) | |||
| viewer.assetManager.exporter.getExporter('gltf', 'glb')?.extensions?.push(glTFTextureBasisUExtensionExport) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| super.onRemove(viewer) | |||
| const exporter = viewer.assetManager.exporter.getExporter('gltf', 'glb') | |||
| const index = exporter?.extensions?.indexOf(glTFTextureBasisUExtensionExport) | |||
| if (index !== undefined && index !== -1) exporter?.extensions?.splice(index, 1) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| } | |||
| @@ -1,27 +1,13 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {Importer} from '../../assetmanager' | |||
| import {KTXLoader} from 'three/examples/jsm/loaders/KTXLoader.js' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading `.ktx`, `image/ktx` files and data uris. | |||
| * @category Plugins | |||
| */ | |||
| export class KTXLoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof KTXLoadPlugin | |||
| export class KTXLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'KTXLoadPlugin' | |||
| private _importer = new Importer(KTXLoader, ['ktx'], ['image/ktx'], false) | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| protected _importer = new Importer(KTXLoader, ['ktx'], ['image/ktx'], false) | |||
| } | |||
| @@ -1,36 +1,24 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {ILoader, Importer} from '../../assetmanager' | |||
| import {PLYLoader} from 'three/examples/jsm/loaders/PLYLoader.js' | |||
| import {AnyOptions} from 'ts-browser-helpers' | |||
| import {BufferGeometry, Color, Mesh} from 'three' | |||
| import {PhysicalMaterial} from '../../core' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading `.ply`, `text/plain+ply` files and data uris | |||
| * @category Plugins | |||
| */ | |||
| export class PLYLoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof PLYLoadPlugin | |||
| export class PLYLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'PLYLoadPlugin' | |||
| private _importer = new Importer(class extends PLYLoader implements ILoader { | |||
| protected _importer = new Importer(class extends PLYLoader implements ILoader { | |||
| transform(res: BufferGeometry, _: AnyOptions): Mesh|undefined { | |||
| if (!res.attributes?.normal) res.computeVertexNormals() | |||
| // todo set mesh name from options/path | |||
| return res ? new Mesh(res, new PhysicalMaterial({color: new Color(1, 1, 1)})) : undefined | |||
| return res ? new Mesh(res, new PhysicalMaterial({ | |||
| color: new Color(1, 1, 1), | |||
| vertexColors: res.hasAttribute('color'), | |||
| })) : undefined | |||
| } | |||
| }, ['ply'], ['text/plain+ply'], false) | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| } | |||
| @@ -1,26 +1,11 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {Importer, Rhino3dmLoader2} from '../../assetmanager' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading Rhino `.3dm`, `model/vnd.3dm`, `model/3dm` files and data uris. | |||
| * @category Plugins | |||
| */ | |||
| export class Rhino3dmLoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof Rhino3dmLoadPlugin | |||
| export class Rhino3dmLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'Rhino3dmLoadPlugin' | |||
| private _importer = new Importer(Rhino3dmLoader2, ['3dm'], ['model/vnd.3dm', 'model/3dm'], true) | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| protected _importer = new Importer(Rhino3dmLoader2, ['3dm'], ['model/vnd.3dm', 'model/3dm'], true) | |||
| } | |||
| @@ -1,36 +1,25 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {ILoader, Importer} from '../../assetmanager' | |||
| import {STLLoader} from 'three/examples/jsm/loaders/STLLoader.js' | |||
| import {BufferGeometry, Color, Mesh} from 'three' | |||
| import {AnyOptions} from 'ts-browser-helpers' | |||
| import {PhysicalMaterial} from '../../core' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading `.stl`, `model/stl` files and data uris. | |||
| * @category Plugins | |||
| */ | |||
| export class STLLoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof STLLoadPlugin | |||
| export class STLLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'STLLoadPlugin' | |||
| private _importer = new Importer(class extends STLLoader implements ILoader { | |||
| protected _importer = new Importer(class extends STLLoader implements ILoader { | |||
| transform(res: BufferGeometry, _: AnyOptions): Mesh|undefined { | |||
| if (!res.attributes?.normal) res.computeVertexNormals() | |||
| // todo set mesh name from options/path | |||
| return res ? new Mesh(res, new PhysicalMaterial({color: new Color(1, 1, 1)})) : undefined | |||
| return res ? new Mesh(res, new PhysicalMaterial({ | |||
| color: new Color(1, 1, 1), | |||
| vertexColors: res.hasAttribute('color'), | |||
| })) : undefined | |||
| } | |||
| }, ['stl'], ['model/stl', 'model/x.stl-binary', 'model/x.stl-ascii'], false) | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| } | |||
| @@ -1,30 +1,30 @@ | |||
| import {IViewerPluginSync, ThreeViewer} from '../../viewer' | |||
| import {Importer} from '../../assetmanager' | |||
| import {USDZLoader} from 'three/examples/jsm/loaders/USDZLoader.js' | |||
| import {Group, Mesh} from 'three' | |||
| import {Zippable, zipSync} from 'three/examples/jsm/libs/fflate.module.js' | |||
| import {BaseImporterPlugin} from '../base/BaseImporterPlugin' | |||
| /** | |||
| * Adds support for loading `.usdz`, `model/vnd.usd+zip` and `.usda`, `model/vnd.usda` files and data uris | |||
| * @category Plugins | |||
| */ | |||
| export class USDZLoadPlugin implements IViewerPluginSync { | |||
| declare ['constructor']: typeof USDZLoadPlugin | |||
| export class USDZLoadPlugin extends BaseImporterPlugin { | |||
| public static readonly PluginType = 'USDZLoadPlugin' | |||
| private _importer = new Importer(class extends USDZLoader { | |||
| private _currentUrl = '' | |||
| protected _importer = new Importer(class extends USDZLoader { | |||
| currentUrl = '' | |||
| async loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<Mesh> { | |||
| this._currentUrl = url | |||
| this.currentUrl = url | |||
| const res = await super.loadAsync(url, onProgress) | |||
| this._currentUrl = '' | |||
| this.currentUrl = '' | |||
| return res | |||
| } | |||
| parse(buffer: ArrayBuffer): Group { | |||
| parse(buffer: ArrayBuffer|string): Group { | |||
| // todo make changes in three.js to allow passing unzipped buffer directly for usda | |||
| if (this._currentUrl.endsWith('.usda')) { | |||
| const filename = this._currentUrl.split('/').pop() | |||
| if (this.currentUrl.endsWith('.usda') && typeof buffer !== 'string') { | |||
| const filename = this.currentUrl.split('/').pop() | |||
| if (filename) { | |||
| const zip: Zippable = {} | |||
| zip[filename] = new Uint8Array(buffer) | |||
| @@ -35,16 +35,4 @@ export class USDZLoadPlugin implements IViewerPluginSync { | |||
| } | |||
| }, ['usdz', 'usda'], ['model/vnd.usd+zip', 'model/vnd.usdz+zip', 'model/vnd.usda'], false) | |||
| onAdded(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.addImporter(this._importer) | |||
| } | |||
| onRemove(viewer: ThreeViewer) { | |||
| viewer.assetManager.importer.removeImporter(this._importer) | |||
| } | |||
| dispose() { | |||
| return | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| // base | |||
| export {PipelinePassPlugin} from './base/PipelinePassPlugin' | |||
| export {BaseImporterPlugin} from './base/BaseImporterPlugin' | |||
| // pipeline | |||
| export {ProgressivePlugin} from './pipeline/ProgressivePlugin' | |||
| @@ -1 +1 @@ | |||
| export const VERSION = '0.0.13-dev.1' | |||
| export const VERSION = '0.0.14' | |||