Sfoglia il codice sorgente

Add assimp to tweakpane editor, add utility for export model and convert

master
Palash Bansal 1 anno fa
parent
commit
d1524056bb
Nessun account collegato all'indirizzo email del committer

+ 1
- 9
examples/fbx-export/script.ts Vedi File

converting = true converting = true


// export to glb // export to glb
const blob = await viewer.export(result, {
fbxBlob = await assimp.exportModel('fbx', result, {
embedUrlImages: true, embedUrlImages: true,
}) })
// const blob = await viewer.exportScene(); // its possible to export the whole scene also // 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) { if (!fbxBlob) {
alert('Failed to convert glb to fbx') alert('Failed to convert glb to fbx')
converting = false converting = false

+ 3
- 1
examples/tweakpane-editor/ThreeEditor.ts Vedi File

EnvironmentControlsPlugin, EnvironmentControlsPlugin,
GlobeControlsPlugin, GlobeControlsPlugin,
} from '@threepipe/plugin-3d-tiles-renderer' } from '@threepipe/plugin-3d-tiles-renderer'
import {AssimpJsPlugin} from '@threepipe/plugin-assimpjs'
// @ts-expect-error todo fix import // @ts-expect-error todo fix import
import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, OutlinePlugin, SSGIPlugin, AnisotropyPlugin} from '@threepipe/webgi-plugins' import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, OutlinePlugin, SSGIPlugin, AnisotropyPlugin} from '@threepipe/webgi-plugins'


EnvironmentControlsPlugin, GlobeControlsPlugin, EnvironmentControlsPlugin, GlobeControlsPlugin,
B3DMLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, CMPTLoadPlugin, B3DMLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, CMPTLoadPlugin,
TilesRendererPlugin, DeepZoomImageLoadPlugin, /* SlippyMapTilesLoadPlugin,*/ TilesRendererPlugin, DeepZoomImageLoadPlugin, /* SlippyMapTilesLoadPlugin,*/
new AssimpJsPlugin(false),
] ]


editorModes: Record<string, Class<IViewerPlugin<any>>[]> = { editorModes: Record<string, Class<IViewerPlugin<any>>[]> = {
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, OutlinePlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin, MeshOptSimplifyModifierPlugin], ['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, OutlinePlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin, MeshOptSimplifyModifierPlugin],
['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin], ['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, SSAOPlugin, SSReflectionPlugin, BloomPlugin, DepthOfFieldPlugin, SSGIPlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSContactShadowsPlugin], ['Post-processing']: [TonemapPlugin, ProgressivePlugin, SSAOPlugin, SSReflectionPlugin, BloomPlugin, DepthOfFieldPlugin, SSGIPlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSContactShadowsPlugin],
['Export']: [AssetExporterPlugin, CanvasSnapshotPlugin, AWSClientPlugin, TransfrSharePlugin],
['Export']: [AssetExporterPlugin, CanvasSnapshotPlugin, AWSClientPlugin, TransfrSharePlugin, AssimpJsPlugin],
['Configurator']: [MaterialConfiguratorPlugin, SwitchNodePlugin, GLTFKHRMaterialVariantsPlugin], ['Configurator']: [MaterialConfiguratorPlugin, SwitchNodePlugin, GLTFKHRMaterialVariantsPlugin],
['Animation']: [GLTFAnimationPlugin, CameraViewPlugin], ['Animation']: [GLTFAnimationPlugin, CameraViewPlugin],
['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, AnisotropyPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin, TilesRendererPlugin], ['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, AnisotropyPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin, TilesRendererPlugin],

+ 1
- 0
examples/tweakpane-editor/index.html Vedi File

"@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs", "@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs",
"@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs", "@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs", "@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs",
"@threepipe/plugin-assimpjs": "./../../plugins/assimpjs/dist/index.mjs",
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.4.1/dist/index.mjs" "@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.4.1/dist/index.mjs"
} }
} }

+ 2
- 2
plugins/assimpjs/package-lock.json Vedi File

{ {
"name": "@threepipe/plugin-assimpjs", "name": "@threepipe/plugin-assimpjs",
"version": "0.1.0",
"version": "0.2.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@threepipe/plugin-assimpjs", "name": "@threepipe/plugin-assimpjs",
"version": "0.1.0",
"version": "0.2.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"assimpjs": "^0.0.10", "assimpjs": "^0.0.10",

+ 2
- 2
plugins/assimpjs/package.json Vedi File

{ {
"name": "@threepipe/plugin-assimpjs", "name": "@threepipe/plugin-assimpjs",
"description": "Assimp.js Plugin for ThreePipe", "description": "Assimp.js Plugin for ThreePipe",
"version": "0.1.0",
"version": "0.2.0",
"devDependencies": { "devDependencies": {
}, },
"dependencies": { "dependencies": {
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/repalash/threepipe.git", "url": "git://github.com/repalash/threepipe.git",
"directory": "plugins/plugin-template-vite"
"directory": "plugins/assimpjs"
}, },
"clean-package": { "clean-package": {
"remove": [ "remove": [

+ 59
- 4
plugins/assimpjs/src/AssimpJsPlugin.ts Vedi File

import {AViewerPluginSync, ThreeViewer, getUrlQueryParam, createScriptFromURL} from 'threepipe'
import {
AViewerPluginSync,
ThreeViewer,
getUrlQueryParam,
createScriptFromURL,
IObject3D,
ExportFileOptions, uiButton, uiToggle, PickingPlugin, uiFolderContainer,
} from 'threepipe'


interface AssimpJsInterface{ interface AssimpJsInterface{
[key: string]: any [key: string]: any
* Assimpjs - https://github.com/kovacsv/assimpjs * Assimpjs - https://github.com/kovacsv/assimpjs
* Fork with a custom build to support fbx export - https://github.com/repalash/assimpjs * Fork with a custom build to support fbx export - https://github.com/repalash/assimpjs
*/ */
@uiFolderContainer('Assimp')
export class AssimpJsPlugin extends AViewerPluginSync { export class AssimpJsPlugin extends AViewerPluginSync {
public static readonly PluginType: string = 'SamplePlugin' public static readonly PluginType: string = 'SamplePlugin'
enabled = true enabled = true
dependencies = [] dependencies = []


initOnAdd: boolean

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


constructor() {
constructor(initOnAdd = true) {
super() super()
this.initOnAdd = initOnAdd
} }

protected _scriptElement?: HTMLScriptElement protected _scriptElement?: HTMLScriptElement
private _initing: Promise<void>|undefined private _initing: Promise<void>|undefined


} }
ajs?: AssimpJsInterface ajs?: AssimpJsInterface


initOnAdd = true

onAdded(viewer: ThreeViewer) { onAdded(viewer: ThreeViewer) {
super.onAdded(viewer) super.onAdded(viewer)
if (this.initOnAdd) this.init() if (this.initOnAdd) this.init()
const blob = new Blob([resultFile.GetContent()], {type: 'application/octet-stream'}) const blob = new Blob([resultFile.GetContent()], {type: 'application/octet-stream'})
return blob return blob
} }

async exportModel(format: 'fbx'|'gltf2'|'glb2'|'assjson' = 'glb2', object?: IObject3D, options: ExportFileOptions = {embedUrlImages: true}) {
if (!this._viewer) {
console.error('AssimpJsPlugin - No viewer attached, please add the plugin to a viewer instance.')
return
}
const initing = this.init()
const selected = this.exportSelected ? this._viewer.getPlugin(PickingPlugin)?.getSelectedObject() : undefined
object = object || selected || this._viewer.scene.modelRoot

// export to glb
const blob = await this._viewer.export(object, options)
if (!blob || blob.ext !== 'glb') {
console.error('AssimpJsPlugin - Unable to export model, no blob returned.')
return
}
await initing // wait for assimp.js to be initialized
const blob2 = this.convertFiles({['file.glb']: await blob.arrayBuffer()}, format)
if (!blob2) {
console.error('AssimpJsPlugin - Unable to convert model to format:', format)
return
}
// convert to ArrayBuffer
return new File([blob2], 'model.' + format.replace(/2$/, ''), {type: 'application/octet-stream'})
}

@uiToggle('Export Selected')
exportSelected = true

@uiButton('Download FBX')
async exportAsFbx(object?: IObject3D) {
if (!object?.isObject3D) object = undefined
const blob = await this.exportModel('fbx', object)
if (blob) {
await this._viewer?.exportBlob(blob, blob.name)
}
}
@uiButton('Download Assimp JSON')
async exportAsGlb(object?: IObject3D) {
if (!object?.isObject3D) object = undefined
const blob = await this.exportModel('assjson', object)
if (blob) {
await this._viewer?.exportBlob(blob, blob.name)
}
}
} }

+ 3
- 8
website/package/plugin-assimpjs.md Vedi File



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


This package uses a custom fork of [assimpjs](https://github.com/kovacsv/assimpjs) with custom build to support fbx export etc - https://github.com/repalash/assimpjs

```bash ```bash
npm install @threepipe/plugin-assimpjs npm install @threepipe/plugin-assimpjs
``` ```
// load some models // load some models
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf') const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf')


// export to glb
const blob = await viewer.export(result, {
const fbxBlob = await assimp.exportModel('fbx', result, {
embedUrlImages: true, embedUrlImages: true,
}) })


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

// download the fbx file // download the fbx file
downloadBlob(fbxBlob, 'model.fbx') downloadBlob(fbxBlob, 'model.fbx')
``` ```

Loading…
Annulla
Salva