| // or | // or | ||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'threepipe' // if using import maps | // import {ThreeViewer, LoadingScreenPlugin} from 'threepipe' // if using import maps | ||||
| // import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | // import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | ||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://threepipe.org/dist/index.mjs' | |||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://unpkg.com/threepipe@latest/dist/index.mjs' | |||||
| const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas')}) | const viewer = new ThreeViewer({canvas: document.getElementById('three-canvas')}) | ||||
| <body> | <body> | ||||
| <div id="root"></div> | <div id="root"></div> | ||||
| <script id="example-script" type="module" data-scripts="./index.html"> | <script id="example-script" type="module" data-scripts="./index.html"> | ||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://threepipe.org/dist/index.mjs' | |||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://unpkg.com/threepipe@latest/dist/index.mjs' | |||||
| import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | ||||
| import React from 'https://esm.sh/react@18' | import React from 'https://esm.sh/react@18' | ||||
| import ReactDOM from 'https://esm.sh/react-dom@18' | import ReactDOM from 'https://esm.sh/react-dom@18' |
| <body> | <body> | ||||
| <div id="root"></div> | <div id="root"></div> | ||||
| <script id="example-script" type="text/babel" data-scripts="./index.html" data-type="module"> | <script id="example-script" type="text/babel" data-scripts="./index.html" data-type="module"> | ||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://threepipe.org/dist/index.mjs' | |||||
| // import {ThreeViewer, LoadingScreenPlugin} from 'https://unpkg.com/threepipe@latest/dist/index.mjs' | |||||
| import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | import {ThreeViewer, LoadingScreenPlugin} from './../../dist/index.mjs' | ||||
| import React from 'https://esm.sh/react@18' | import React from 'https://esm.sh/react@18' | ||||
| import ReactDOM from 'https://esm.sh/react-dom@18' | import ReactDOM from 'https://esm.sh/react-dom@18' |
| <canvas id="three-canvas" style="width: 800px; height: 600px" ref="canvasRef"></canvas> | <canvas id="three-canvas" style="width: 800px; height: 600px" ref="canvasRef"></canvas> | ||||
| </div> | </div> | ||||
| <script id="example-script" type="module" data-scripts="./index.html"> | <script id="example-script" type="module" data-scripts="./index.html"> | ||||
| // import { ThreeViewer, LoadingScreenPlugin } from 'https://threepipe.org/dist/index.mjs' | |||||
| // import { ThreeViewer, LoadingScreenPlugin } from 'https://unpkg.com/threepipe@latest/dist/index.mjs' | |||||
| import { ThreeViewer, LoadingScreenPlugin } from './../../dist/index.mjs' | import { ThreeViewer, LoadingScreenPlugin } from './../../dist/index.mjs' | ||||
| import { createApp, ref, onMounted, onBeforeUnmount } from "https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js"; | import { createApp, ref, onMounted, onBeforeUnmount } from "https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js"; | ||||
| Color, | Color, | ||||
| Group, | Group, | ||||
| ILoader, | ILoader, | ||||
| ImportAddOptions, | |||||
| Importer, | Importer, | ||||
| Mesh, | Mesh, | ||||
| Object3D, | Object3D, | ||||
| export class PCDLoadPlugin extends BaseImporterPlugin { | export class PCDLoadPlugin extends BaseImporterPlugin { | ||||
| public static readonly PluginType = 'PCDLoadPlugin' | public static readonly PluginType = 'PCDLoadPlugin' | ||||
| protected _importer = new Importer(class extends PCDLoader implements ILoader { | protected _importer = new Importer(class extends PCDLoader implements ILoader { | ||||
| transform(points: Points, options: AnyOptions): any { | |||||
| transform(points: Points, options: ImportAddOptions): any { | |||||
| if (options.autoCenter) points.geometry.center() | if (options.autoCenter) points.geometry.center() | ||||
| points.geometry.rotateX(Math.PI) | points.geometry.rotateX(Math.PI) | ||||
| return points | return points | ||||
| export class XYZLoadPlugin extends BaseImporterPlugin { | export class XYZLoadPlugin extends BaseImporterPlugin { | ||||
| public static readonly PluginType = 'XYZLoadPlugin' | public static readonly PluginType = 'XYZLoadPlugin' | ||||
| protected _importer = new Importer(class extends XYZLoader implements ILoader { | protected _importer = new Importer(class extends XYZLoader implements ILoader { | ||||
| transform(res: BufferGeometry, options: AnyOptions): Points|undefined { | |||||
| transform(res: BufferGeometry, options: ImportAddOptions): Points|undefined { | |||||
| if (!res.attributes?.normal) res.computeVertexNormals() | if (!res.attributes?.normal) res.computeVertexNormals() | ||||
| if (options.autoCenter) res.center() | if (options.autoCenter) res.center() | ||||
| return res ? new Points(res, new PointsMaterial({ | return res ? new Points(res, new PointsMaterial({ |
| // baseUrl: LoaderUtils.extractUrlBase(url), | // baseUrl: LoaderUtils.extractUrlBase(url), | ||||
| } | } | ||||
| loader.loadFileOptions = options | |||||
| loader.importOptions = options | |||||
| res = await loader.loadAsync(path + (options.queryString ? (path.includes('?') ? '&' : '?') + options.queryString : ''), (e)=>{ | res = await loader.loadAsync(path + (options.queryString ? (path.includes('?') ? '&' : '?') + options.queryString : ''), (e)=>{ | ||||
| if (onDownloadProgress) onDownloadProgress(e) | if (onDownloadProgress) onDownloadProgress(e) | ||||
| const total = e.lengthComputable ? e.total : undefined | const total = e.lengthComputable ? e.total : undefined | ||||
| }) | }) | ||||
| }) | }) | ||||
| if (loader.transform) res = await loader.transform(res, options) | if (loader.transform) res = await loader.transform(res, options) | ||||
| delete loader.loadFileOptions | |||||
| delete loader.importOptions | |||||
| this._rootContext = undefined | this._rootContext = undefined | ||||
| */ | */ | ||||
| autoSetBackground?: boolean | autoSetBackground?: boolean | ||||
| } | } | ||||
| export type ImportAddOptions = ImportAssetOptions & AddAssetOptions | |||||
| export type AddRawOptions = ProcessRawOptions & AddAssetOptions | |||||
| export interface ImportAddOptions extends ImportAssetOptions, AddAssetOptions{} | |||||
| export interface AddRawOptions extends ProcessRawOptions, AddAssetOptions{} | |||||
| export interface AssetManagerEventMap{ | export interface AssetManagerEventMap{ | ||||
| loadAsset: {data: ImportResult} | loadAsset: {data: ImportResult} |
| import {Loader} from 'three' | import {Loader} from 'three' | ||||
| import {IAssetImporter, LoadFileOptions} from './IAssetImporter' | |||||
| import {IAssetImporter} from './IAssetImporter' | |||||
| import {IDisposable} from 'ts-browser-helpers' | import {IDisposable} from 'ts-browser-helpers' | ||||
| import {ImportAddOptions} from './AssetManager' | |||||
| export interface ILoader<T = any, T2 = T> extends Loader, Partial<IDisposable> { | export interface ILoader<T = any, T2 = T> extends Loader, Partial<IDisposable> { | ||||
| loadFileOptions?: LoadFileOptions | |||||
| importOptions?: ImportAddOptions | |||||
| loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<any>; | loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<any>; | ||||
| /** | /** | ||||
| * Transform after load, like convert geometry to mesh, etc. for reference see {@link DRACOLoader2} or {@link PLYLoadPlugin} | * Transform after load, like convert geometry to mesh, etc. for reference see {@link DRACOLoader2} or {@link PLYLoadPlugin} | ||||
| * @param res - result of load | * @param res - result of load | ||||
| * @param options | * @param options | ||||
| */ | */ | ||||
| transform?(res: T, options: LoadFileOptions): T2|Promise<T2> | |||||
| transform?(res: T, options: ImportAddOptions): T2|Promise<T2> | |||||
| } | } | ||||
| export interface IImporter { | export interface IImporter { | ||||
| ext: string[]; | ext: string[]; |
| @uiInput() @serialize() minPolarAngle = 0 | @uiInput() @serialize() minPolarAngle = 0 | ||||
| @uiInput() @serialize() maxPolarAngle = Math.PI | @uiInput() @serialize() maxPolarAngle = Math.PI | ||||
| @uiInput() @serialize() minAzimuthAngle = -10000 // should be -Infinity but this breaks the UI | |||||
| @uiInput() @serialize() maxAzimuthAngle = 10000 // should be Infinity but this breaks the UI | |||||
| @uiInput() @serialize() minAzimuthAngle = -1e6 // should be -Infinity but this breaks the UI | |||||
| @uiInput() @serialize() maxAzimuthAngle = 1e6 // should be Infinity but this breaks the UI | |||||
| @uiVector() @serialize() clampMin = new Vector3(-10000, -10000, -10000) // should be -Infinity but this breaks the UI | |||||
| @uiVector() @serialize() clampMax = new Vector3(10000, 10000, 10000) // should be Infinity but this breaks the UI | |||||
| @uiVector() @serialize() clampMin = new Vector3(-1e6, -1e6, -1e6) // should be -Infinity but this breaks the UI | |||||
| @uiVector() @serialize() clampMax = new Vector3(1e6, 1e6, 1e6) // should be Infinity but this breaks the UI | |||||
| // @uiToggle() | // @uiToggle() | ||||
| @serialize() screenSpacePanning = true | @serialize() screenSpacePanning = true |