Bläddra i källkod

Add assimpjs plugin, examples, version bump

master
Palash Bansal 1 år sedan
förälder
incheckning
650cb34a87
Inget konto är kopplat till bidragsgivarens mejladress

+ 2
- 2
CONTRIBUTING.md Visa fil

@@ -78,6 +78,6 @@ Checklist
- Add example and any other tests to `tests/`
- Add info to `README.md`
- Add info to `./website/guide/threepipe-packages.md`
- Add info to `./website/packages/PluginName.md`
- Add info to `./website/package/plugin-name.md` and add to `./website/.vitepress/config.ts`
- `npm run build` and test with example
- Publish package with `npm run new:publish`. Add tag to git like `plugin-name-v0.0.1`
- Publish package with `npm run new:publish`. Check that tag is added to git like `plugin-name-v0.0.1`

+ 2
- 1
README.md Visa fil

@@ -315,6 +315,7 @@ Many features will be added but the core API will not change significantly in fu
- [SimplifyModifierPlugin](https://threepipe.org/plugin/SimplifyModifierPlugin.html) - Boilerplate for plugin to simplify geometries
- [MeshOptSimplifyModifierPlugin](https://threepipe.org/plugin/MeshOptSimplifyModifierPlugin.html) - Simplify geometries using [meshoptimizer](https://github.com/zeux/meshoptimizer) library
- [Packages](https://threepipe.org/guide/threepipe-packages.html)
- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)
- [@threepipe/plugin-tweakpane](https://threepipe.org/package/plugin-tweakpane.html) [Tweakpane](https://tweakpane.github.io/docs/) UI Plugin
- [@threepipe/plugin-blueprintjs](https://threepipe.org/package/plugin-blueprintjs.html) [BlueprintJs](https://blueprintjs.com/) UI Plugin
- [@threepipe/plugin-tweakpane-editor](https://threepipe.org/package/plugin-tweakpane-editor.html) - Editor Plugin using Tweakpane for plugin UI
@@ -327,7 +328,7 @@ Many features will be added but the core API will not change significantly in fu
- [@threepipe/plugin-network](https://threepipe.org/package/plugin-network.html) - Network/Cloud related plugin implementations for Threepipe
- [@threepipe/plugin-svg-renderer](https://threepipe.org/package/plugin-svg-renderer.html) - Add support for exporting a 3d scene as SVG using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer)
- [@threepipe/plugin-3d-tiles-renderer](https://threepipe.org/package/plugin-3d-tiles-renderer.html) - Plugins for [3d-tiles-renderer](https://github.com/NASA-AMMOS/3DTilesRendererJS), b3dm, i3dm, cmpt, pnts, dzi, slippy maps importers.
- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)
- [@threepipe/plugin-assimpjs](https://threepipe.org/package/plugin-assimpjs.html) - Plugin and helpers to load and use [assimpjs](https://github.com/kovacsv/assimpjs) (with fbx, other exporters) in the browser.

## Documentation


+ 37
- 0
examples/assimpjs-plugin/index.html Visa fil

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AssimpJs Plugin</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-assimpjs": "./../../plugins/assimpjs/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>

+ 61
- 0
examples/assimpjs-plugin/script.ts Visa fil

@@ -0,0 +1,61 @@
import {
_testFinish,
_testStart,
downloadBlob, HemisphereLight,
IObject3D,
LoadingScreenPlugin,
ThreeViewer,
} from 'threepipe'
import {AssimpJsPlugin} from '@threepipe/plugin-assimpjs'

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
plugins: [LoadingScreenPlugin],
})

async function init() {

const assimp = viewer.addPluginSync(AssimpJsPlugin)
await assimp.init()

console.log('AssimpJsPlugin initialized:', assimp.ajs)

// Direct way to convert without using the viewer
const files = [
'https://threejs.org/examples/models/obj/male02/male02.obj',
'https://threejs.org/examples/models/obj/male02/male02.mtl', // mtl doesnt work?
]
const fe = files.map(async f=>fetch(`${f}`).then(async t=>t.arrayBuffer()))
const responses = await Promise.all(fe)
const fileList: Record<string, ArrayBuffer> = {}
for (let i = 0; i < files.length; i++) {
fileList[files[i]] = responses[i]
}
const fbx = assimp.convertFiles(fileList, 'fbx')
if (!fbx) {
console.error('Failed to convert files to fbx')
return
}

// load the fbx file
await viewer.load<IObject3D>({path: 'file.fbx', file: fbx}, {
autoCenter: true,
autoScale: true,
})
viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 2))

// add download button
const downloadButton = document.createElement('button')
downloadButton.innerText = 'Download .fbx'
downloadButton.style.position = 'absolute'
downloadButton.style.bottom = '3rem'
downloadButton.style.right = '3rem'
downloadButton.style.zIndex = '10000'
downloadButton.onclick = () => downloadBlob(fbx, 'file.fbx')
document.body.appendChild(downloadButton)

}

_testStart()
init().finally(_testFinish)

+ 37
- 0
examples/fbx-export/index.html Visa fil

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FBX Export (Assimp)</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-assimpjs": "./../../plugins/assimpjs/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>

+ 106
- 0
examples/fbx-export/script.ts Visa fil

@@ -0,0 +1,106 @@
import {
_testFinish,
_testStart,
downloadBlob,
HemisphereLight,
IObject3D,
LoadingScreenPlugin,
ThreeViewer,
} from 'threepipe'
import {AssimpJsPlugin} from '@threepipe/plugin-assimpjs'

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
plugins: [LoadingScreenPlugin],
})

// Export to fbx is done by first exporting to glb and converting that to fbx using AssimpJsPlugin

async function init() {

const assimp = viewer.addPluginSync(AssimpJsPlugin)
await assimp.init()

viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
// load a file
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})

let fbxBlob: Blob | undefined = undefined
let converting = false
async function exportFbx() {
if (fbxBlob) return fbxBlob
if (converting) {
console.warn('Already converting, please wait...')
return
}
converting = true

// export to glb
const blob = await viewer.export(result, {
embedUrlImages: true,
})
// const blob = await viewer.exportScene(); // its possible to export the whole scene also

if (!blob || blob.ext !== 'glb') {
alert('Unable to export scene')
converting = false
return
}

fbxBlob = assimp.convertFiles({['file.glb']: await blob.arrayBuffer()}, 'fbx')
if (!fbxBlob) {
alert('Failed to convert glb to fbx')
converting = false
return
}

// clear scene
viewer.scene.disposeSceneModels()

// load a light and fbx file
const hemiLight = viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 5), {addToRoot: true})
hemiLight.name = 'Hemisphere Light'
await viewer.load({
path: 'file.fbx',
file: fbxBlob,
}, {
autoCenter: true,
autoScale: true,
})

converting = false
return fbxBlob
}

// add download button
const convertButton = document.createElement('button')
convertButton.innerText = 'Convert to fbx'
convertButton.style.position = 'absolute'
convertButton.style.bottom = '6rem'
convertButton.style.right = '3rem'
convertButton.style.zIndex = '10000'
convertButton.onclick = async() => {
await exportFbx()
}
document.body.appendChild(convertButton)

const downloadButton = document.createElement('button')
downloadButton.innerText = 'Download as .fbx'
downloadButton.style.position = 'absolute'
downloadButton.style.bottom = '3rem'
downloadButton.style.right = '3rem'
downloadButton.style.zIndex = '10000'
downloadButton.onclick = async() => {
await exportFbx()
if (fbxBlob) downloadBlob(fbxBlob, 'file.fbx')
}
document.body.appendChild(downloadButton)

}

_testStart()
init().finally(_testFinish)

+ 2
- 0
examples/index.html Visa fil

@@ -442,6 +442,7 @@
<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="./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>
<li><a href="./pnts-load/">PNTS Load (3D Points) </a></li>
@@ -459,6 +460,7 @@
<li><a href="./render-target-export/">EXR, PNG, JPEG, WEBP Export<br/>(Render Target Export) </a></li>
<li><a href="./glb-export/">GLB Export </a></li>
<li><a href="./glb-draco-export/">GLB (+DRACO) Export </a></li>
<li><a href="./flx-export/">FBX Export (AssimpJs)<br/>(glTF To FBX) </a></li>
<li><a href="./pmat-material-export/">PMAT Material Export </a></li>
<li><a href="./transfr-share-plugin/">Transfr.one Share Plugin<br/>(Upload, share link) </a></li>
</ul>

+ 2
- 2
package-lock.json Visa fil

@@ -1,12 +1,12 @@
{
"name": "threepipe",
"version": "0.0.45",
"version": "0.0.46",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "threepipe",
"version": "0.0.45",
"version": "0.0.46",
"license": "Apache-2.0",
"dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.158.1003/package.tgz",

+ 1
- 1
package.json Visa fil

@@ -1,6 +1,6 @@
{
"name": "threepipe",
"version": "0.0.45",
"version": "0.0.46",
"description": "A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.",
"main": "dist/index.js",
"module": "dist/index.mjs",

+ 29
- 0
plugins/assimpjs/package-lock.json Visa fil

@@ -0,0 +1,29 @@
{
"name": "@threepipe/plugin-assimpjs",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@threepipe/plugin-assimpjs",
"version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
"assimpjs": "^0.0.10",
"threepipe": "file:./../../src/"
},
"devDependencies": {}
},
"../../src": {},
"node_modules/assimpjs": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/assimpjs/-/assimpjs-0.0.10.tgz",
"integrity": "sha512-iY8M+eQzdCvfSkdduj6sPmIbP2fIn40PK6JRrAMxBawL3tHG6Mm0qvitkxB3ZoFBug5o7IdbzQK+jujZTopGPQ==",
"license": "MIT"
},
"node_modules/threepipe": {
"resolved": "../../src",
"link": true
}
}
}

+ 71
- 0
plugins/assimpjs/package.json Visa fil

@@ -0,0 +1,71 @@
{
"name": "@threepipe/plugin-assimpjs",
"description": "Assimp.js Plugin for ThreePipe",
"version": "0.1.0",
"devDependencies": {
},
"dependencies": {
"threepipe": "file:./../../src/",
"assimpjs": "^0.0.10"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./dist/": {
"import": "./dist/",
"require": "./dist/"
}
},
"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": "git diff --exit-code --name-only HEAD * && npm run prepare && clean-package && npm publish --access public && clean-package restore && git tag $npm_package_name-$npm_package_version",
"prepare": "npm run build && npm run docs",
"build": "rimraf dist && vite build",
"dev": "NODE_ENV=development vite build --watch",
"docs": "rimraf docs && npx typedoc"
},
"author": "repalash <palash@shaders.app>",
"license": "Apache-2.0",
"keywords": [
"three",
"three.js",
"threepipe",
"vite",
"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",
"directory": "plugins/plugin-template-vite"
},
"clean-package": {
"remove": [
"clean-package",
"scripts",
"devDependencies",
"//",
"markdown-to-html"
],
"replace": {
"dependencies": {},
"peerDependencies": {
"threepipe": "^0.0.46"
}
}
}
}

+ 96
- 0
plugins/assimpjs/src/AssimpJsPlugin.ts Visa fil

@@ -0,0 +1,96 @@
import {AViewerPluginSync, ThreeViewer, getUrlQueryParam, createScriptFromURL} from 'threepipe'

interface AssimpJsInterface{
[key: string]: any
}

/**
* AssimpJsPlugin
*
* Helper plugin to load the assimp.js library from a CDN and provide a method to convert files using Assimp.js.
*
* Assimpjs - https://github.com/kovacsv/assimpjs
* Fork with a custom build to support fbx export - https://github.com/repalash/assimpjs
*/
export class AssimpJsPlugin extends AViewerPluginSync {
public static readonly PluginType: string = 'SamplePlugin'
enabled = true
dependencies = []

// public static LIBRARY_PATH = `https://cdn.jsdelivr.net/npm/assimpjs@${getUrlQueryParam('assimpjs', '0.0.10')}/`
// adds fbx export support
public static LIBRARY_PATH = `https://cdn.jsdelivr.net/gh/repalash/assimpjs@${getUrlQueryParam('assimpjs', 'main')}/`

constructor() {
super()
}
protected _scriptElement?: HTMLScriptElement
private _initing: Promise<void>|undefined

async init() {
if (!this._initing) this._initing = this._init()
await this._initing
return this.ajs
}
private async _init() {
if (!(window as any).assimpjs) {
this._scriptElement = await createScriptFromURL(AssimpJsPlugin.LIBRARY_PATH + 'dist/assimpjs.js')
}
const ctor = (window as any).assimpjs
const ajs = ctor ? await ctor({
locateFile: (file: string) => AssimpJsPlugin.LIBRARY_PATH + 'dist/' + file,
// print: (text: string) => console.log(text),
// printErr: (text: string) => console.error(text),
// onRuntimeInitialized: () => {
// console.log('Assimp.js initialized')
// this.viewer?.emit('assimpjs-initialized', ajs)
// },
// noExitRuntime: true,
}) : null
if (!ajs) {
this._initing = undefined
this._scriptElement?.remove()
throw new Error('Failed to load Assimp.js library')
}
this.ajs = ajs

}
ajs?: AssimpJsInterface

initOnAdd = true

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
if (this.initOnAdd) this.init()
}

// todo add ui config to export the scene, selected object as fbx or glb2 etc. or interface with the AssetExporter.

convertFiles(files: Record<string, ArrayBuffer>, format: 'fbx'|'gltf2'|'glb2'|'assjson' = 'glb2') {
const ajs = this.ajs
if (!ajs) {
console.error('Assimp.js is not initialized, wait for the promise like - `await assimpPlugin.init()`')
return
}
const fileList = new ajs.FileList()
for (const [name, content] of Object.entries(files)) {
fileList.AddFile(name, new Uint8Array(content))
}

// convert file list to assimp json
const result = ajs.ConvertFileList(fileList, format)

// check if the conversion succeeded
if (!result.IsSuccess() || result.FileCount() == 0) {
// resultDiv.innerHTML = result.GetErrorCode()
console.error(result.GetErrorCode())
console.error(result)
return
}

// get the result file, and convert to blob
const resultFile = result.GetFile(0)
const blob = new Blob([resultFile.GetContent()], {type: 'application/octet-stream'})
return blob
}
}

+ 40
- 0
plugins/assimpjs/src/global.d.ts Visa fil

@@ -0,0 +1,40 @@
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
}
declare module '*.css?inline' { // for vite
const content: string
export default content
}

// export {}

// hack for typedoc
// eslint-disable-next-line @typescript-eslint/naming-convention
// declare type OffscreenCanvas = HTMLCanvasElement

+ 1
- 0
plugins/assimpjs/src/index.ts Visa fil

@@ -0,0 +1 @@
export {AssimpJsPlugin} from './AssimpJsPlugin'

+ 41
- 0
plugins/assimpjs/tsconfig.json Visa fil

@@ -0,0 +1,41 @@
{
"compilerOptions": {
"baseUrl": "./src",
"rootDir": "./src",
"allowJs": true,
"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": "ES2021",
"strictNullChecks": true,
"lib": [
"es2020",
"esnext",
"dom"
]
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts",
"dist"
]
}

+ 10
- 0
plugins/assimpjs/typedoc.json Visa fil

@@ -0,0 +1,10 @@
{
"extends": [
"../../typedoc.json"
],
"entryPoints": [
"src/index.ts"
],
"name": "Threepipe Assimpjs Plugin",
"readme": "none"
}

+ 90
- 0
plugins/assimpjs/vite.config.js Visa fil

@@ -0,0 +1,90 @@
import {defineConfig} from 'vite'
import json from '@rollup/plugin-json';
import dts from 'vite-plugin-dts'
import packageJson from './package.json';
import license from 'rollup-plugin-license';
import replace from '@rollup/plugin-replace';
import glsl from 'rollup-plugin-glsl';
import path from 'node:path';

const isProd = process.env.NODE_ENV === 'production'
const { name, version, author } = packageJson
const {main, module, browser} = packageJson

const globals = {
'three': 'threepipe', // just incase someone uses three
'threepipe': 'threepipe',
}

export default defineConfig({
optimizeDeps: {
exclude: ['uiconfig.js', 'ts-browser-helpers'],
},
base: '',
// define: {
// 'process.env': process.env
// },
build: {
sourcemap: true,
minify: false,
cssMinify: isProd,
cssCodeSplit: false,
watch: !isProd ? {
buildDelay: 1000,
} : null,
lib: {
entry: 'src/index.ts',
formats: isProd ? ['es', 'umd'] : ['es'],
name: name,
fileName: (format) => (format === 'umd' ? main : module).replace('dist/', ''),
},
outDir: 'dist',
emptyOutDir: isProd,
commonjsOptions: {
exclude: [/uiconfig.js/, /ts-browser-helpers/],
},
rollupOptions: {
output: {
// inlineDynamicImports: false,
globals,
},
external: Object.keys(globals),

},
},
plugins: [
isProd ? dts({tsconfigPath: './tsconfig.json'}) : null,
replace({
'from \'three\'': 'from \'threepipe\'',
delimiters: ['', ''],
}),
replace({
'process.env.NODE_ENV': JSON.stringify(isProd ? 'production' : 'development'),
preventAssignment: true,
}),
glsl({ // todo: minify glsl.
include: 'src/**/*.glsl',
}),
json(),
// 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`
// }),
license({
banner: `
@license
${name} v${version}
Copyright 2022<%= moment().format('YYYY') > 2022 ? '-' + moment().format('YYYY') : null %> ${author}
${packageJson.license} License
See ./dependencies.txt for any bundled third-party dependencies and licenses.
`,
thirdParty: {
output: path.join(__dirname, 'dist', 'dependencies.txt'),
includePrivate: true, // Default is false.
},
}),
],
})

+ 1
- 1
src/viewer/version.ts Visa fil

@@ -1 +1 @@
export const VERSION = '0.0.45'
export const VERSION = '0.0.46'

+ 2
- 1
website/.vitepress/config.ts Visa fil

@@ -175,7 +175,8 @@ export default defineConfig({
{text: 'Blend Importer Plugin', link: 'package/plugin-blend-importer'},
{text: 'Gaussian Splatting Plugin', link: 'package/plugin-gaussian-splatting'},
{text: 'svg-renderer Plugin', link: 'package/plugin-svg-renderer'},
{text: 'Tiles (OGC) Renderer Plugin', link: 'package/plugin-3d-tiles-renderer'},
{text: '3D Tiles (OGC) Renderer Plugin', link: 'package/plugin-3d-tiles-renderer'},
{text: 'Assimpjs Plugin', link: 'package/plugin-assimpjs'},
]
},
],

+ 2
- 1
website/guide/threepipe-packages.md Visa fil

@@ -18,6 +18,7 @@ Checkout the [model-viewer](https://threepipe.org/examples/#model-viewer) or [tw

## List of all the packages

- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)
- [@threepipe/plugin-tweakpane](../package/plugin-tweakpane) Tweakpane UI Plugin. Renders a [tweakpane](https://tweakpane.github.io/docs/) UI attached to the viewer for any ui config object.
- [@threepipe/plugin-blueprintjs](../package/plugin-blueprintjs) BlueprintJs UI Plugin. Renders a [blueprintjs](https://blueprintjs.com/) ([React](https://react.dev/)) UI attached to the viewer for any ui config object.
- [@threepipe/plugin-tweakpane-editor](../package/plugin-tweakpane-editor) - Tweakpane Editor Plugin. Uses the tweakpane ui plugin to create a [full editor](https://threepipe.org/examples/tweakpane-editor).
@@ -30,4 +31,4 @@ Checkout the [model-viewer](https://threepipe.org/examples/#model-viewer) or [tw
- [@threepipe/plugin-gaussian-splatting](../package/plugin-gaussian-splatting) - [3D Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) plugin for loading and rendering splat files
- [@threepipe/plugin-svg-renderer](../package/plugin-svg-renderer) - Add support for exporting 3d scene as SVG (WIP) using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer).
- [@threepipe/plugin-3d-tiles-renderer](https://threepipe.org/package/plugin-3d-tiles-renderer.html) - Plugins for [3d-tiles-renderer](https://github.com/NASA-AMMOS/3DTilesRendererJS), b3dm, i3dm, cmpt, pnts importers.
- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)
- [@threepipe/plugin-assimpjs](https://threepipe.org/package/plugin-assimpjs.html) - Plugin and helpers to load and use [assimpjs](https://github.com/kovacsv/assimpjs) (with fbx, other exporters) in the browser.

+ 4
- 1
website/package/plugin-3d-tiles-renderer.md Visa fil

@@ -3,7 +3,10 @@ prev:
text: '@threepipe/plugin-svg-renderer'
link: './plugin-svg-renderer'

next: false
next:
text: '@threepipe/plugin-assimpjs'
link: './plugin-assimpjs'

---

# @threepipe/plugin-3d-tiles-renderer

+ 231
- 0
website/package/plugin-assimpjs.md Visa fil

@@ -0,0 +1,231 @@
---
prev:
text: '@threepipe/plugin-3d-tiles-renderer'
link: './plugin-3d-tiles-renderer'

next: false
---

# @threepipe/plugin-assimpjs
This package exports [AssimpJsPlugin](https://threepipe.org/plugins/assimpjs/docs/classes/AssimpJsPlugin.html) which loads the assimpjs library and provides `ajs` interface.

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

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-assimpjs.svg)](https://www.npmjs.com/package/@threepipe/plugin-assimpjs)

```bash
npm install @threepipe/plugin-assimpjs
```

## Sample Usage

### Load and render tileset
To import a tileset, simply add the `TilesRendererPlugin` and load the root json with the plugin or the viewer.

The near, far plane of the camera can be set based on the file.

```typescript
import {ThreeViewer} from 'threepipe'
import {TilesRendererPlugin, TilesRendererGroup} from '@threepipe/plugin-assimpjs'

const viewer = new ThreeViewer({...})
const tiles = viewer.addPluginSync(TilesRendererPlugin)

viewer.scene.mainCamera.position.set(300, 300, 300)

// optional. (Required for GlobeControls)
viewer.scene.mainCamera.autoNearFar = false
viewer.scene.mainCamera.minNearPlane = 1
viewer.scene.mainCamera.maxFarPlane = 1000

// Now load any tileset json file.
const group = await tiles.load('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesRendererJS/c7a9a7f7607e8759d16c26fb83815ad1cd1fd865/example/data/tileset.json', {
autoScale: true,
autoCenter: true,
autoScaleRadius: 100,
})

// or load directly from the viewer. A custom fileExtension or fileHandler must be passed, to tell the viewer the type of the json file.
const group1 = await viewer.load<TilesRendererGroup>('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesRendererJS/c7a9a7f7607e8759d16c26fb83815ad1cd1fd865/example/data/tileset.json', {
fileExtension: TilesRendererPlugin.DUMMY_EXT,
autoScale: true,
autoCenter: true,
autoScaleRadius: 100,
})

```

Check the [assimpjs](https://threepipe.com/examples/#assimpjs/), [ogc-tiles-mars](https://threepipe.com/examples/#ogc-tiles-mars/) examples for a live demo.

### Use `EnvironmentControls` with `TilesRendererPlugin`

```typescript
import {TilesRendererPlugin, TilesRendererGroup, EnvironmentControlsPlugin, EnvironmentControls2, GlobeControlsPlugin, GlobeControls2} from '@threepipe/plugin-assimpjs'
const viewer = new ThreeViewer({...})
const tiles = viewer.addPluginSync(TilesRendererPlugin)
const group = await tiles.load('...')

viewer.addPluginSync(EnvironmentControlsPlugin)
viewer.addPluginSync(GlobeControlsPlugin)

viewer.scene.mainCamera.controlsMode = 'environment'
viewer.scene.mainCamera.lookAt(0, 0, 0)
let controls = viewer.scene.mainCamera.controls as EnvironmentControls2
controls.minDistance = 0.25;

// For globe controls
viewer.scene.mainCamera.controlsMode = 'globe'
viewer.scene.mainCamera.lookAt(0, 0, 0)
controls = viewer.scene.mainCamera.controls as GlobeControls2

// optional. (Required for GlobeControls)
controls.setTilesRenderer(group.tilesRenderer)
```

### Additional `TilesRenderer` Plugins

Some plugins are used by default in the `TilesRendererPlugin` to load and render the tileset. These can be disabled/configured when loading a file and more can be added.
Custom plugins can be added to the individual `TilesRenderer` when loading a tileset file.
```typescript
import {UnloadTilesPlugin, TileCompressionPlugin} from '@threepipe/plugin-assimpjs'
const result = await tiles.load('url', {
autoCenter: true,
autoScale: false,
tiles: {
TilesFadePlugin: {
fadeDuration: 0.5,
},
plugins: [
()=>new UnloadTilesPlugin(),
()=>new TileCompressionPlugin(),
],
},
})
```

### Loading Cesium Ion Assets

Cesium Ion assets like Google Maps can be loaded with the `loadCesiumIon` function in the plugin, or by passing a custom plugin in the viewer.

```typescript
const tiles = viewer.getPlugin(TilesRendererPlugin)
const result = await tiles.loadCesiumIon({
assetId: '2275207',
apiToken: CESIUM_ION_API_TOKEN,
autoRefreshToken: true,
}, {
autoCenter: false,
// more options
tiles: {
TilesFadePlugin: true,
plugins: [
()=>new TileCompressionPlugin(),
()=>new UnloadTilesPlugin(),
],
},
})

// or
const result2 = await viewer.load('file.tileset', {
tiles: {
CesiumIonAuthPlugin: {
assetId: '2275207',
apiToken: CESIUM_ION_API_TOKEN,
autoRefreshToken: true,
},
TilesFadePlugin: true,
plugins: [
()=>new TileCompressionPlugin(),
()=>new UnloadTilesPlugin(),
],
},
})
```

Note - `TilesRendererPlugin.DUMMY_EXT` = `tileset`

:::info
Get the `CESIUM_ION_API_TOKEN` for free from [cesium ion](https://ion.cesium.com/)
:::

Check the Google Maps examples - [ogc-tiles-google-maps](https://threepipe.com/examples/#ogc-tiles-google-maps/), [ogc-tiles-google-maps-3d](https://threepipe.com/examples/#ogc-tiles-google-maps-3d/) examples for sample usage

### Loading 3d tiles files

To load any individual tile file format, add the plugin to the viewer and load the file directly as you would with any other file. The plugin will automatically detect the type of the file and load it.
```typescript
import {ThreeViewer} from 'threepipe'
import {B3DMLoadPlugin, CMPTLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin} from '@threepipe/plugin-assimpjs'

const viewer = new ThreeViewer({...})
viewer.addPluginsSync([B3DMLoadPlugin, CMPTLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, LoadingScreenPlugin])

// Now load any file
const b3dm = await viewer.load<IObject3D>('https://example.com/file.b3dm')
const cmpt = await viewer.load<IObject3D>('https://example.com/file.cmpt')
const i3dm = await viewer.load<IObject3D>('https://example.com/file.i3dm')
const pnts = await viewer.load<IObject3D>('https://example.com/file.pnts')

// Load file by data url
const model = await viewer.load<IObject3D>('data:application/octet-stream;base64,...', {
fileExtension: 'b3dm',
})
// or by using `model/<extension>` mime type
const model2 = await viewer.load<IObject3D>('data:model/b3dm;base64,...')
```

The asset importer will automatically detect the type of the file and load it.

Checkout the examples [b3dm-load](https://threepipe.org/examples/#b3dm-load/),
[cmpt-load](https://threepipe.org/examples/#cmpt-load/),
[pnts-load](https://threepipe.org/examples/#pnts-load/),
[i3dm-load](https://threepipe.org/examples/#i3dm-load/) for more details.

### Loading Image tiles

The package exports plugins `DeepZoomImageLoadPlugin` and `SlippyMapTilesLoadPlugin` to load deep zoom images and slippy map tiles respectively.
They add and use the `TilesRendererPlugin` automatically.

The plugins can be added to the viewer and files can be loaded directly from the viewer or asset manager.

```typescript
import {ThreeViewer} from 'threepipe'
import {TilesRendererPlugin, DeepZoomImageLoadPlugin, SlippyMapTilesLoadPlugin} from '@threepipe/plugin-assimpjs'

const viewer = new ThreeViewer({...})

viewer.addPluginsSync([TilesRendererPlugin, DeepZoomImageLoadPlugin, SlippyMapTilesLoadPlugin])

// Load deep zoom image
const result = await viewer.load('https://openseadragon.github.io/example-images/duomo/duomo.dzi', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
tiles: {
DeepZoomImagePlugin: {
center: true
},
errorTarget: 1,
}
})

const result2 = await viewer.load('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
fileExtension: SlippyMapTilesLoadPlugin.DUMMY_EXT,
tiles: {
errorTarget: 1,
XYZTilesPlugin: {
projection: 'planar',
center: true
},
}
})
```

Checkout the examples [dzi-load](https://threepipe.org/examples/#dzi-load/),
[slippy-map-tiles](https://threepipe.org/examples/#slippy-map-tiles/) for a demo.

Laddar…
Avbryt
Spara