Quellcode durchsuchen

Fix GLTFAnimationPlugin for objects in root, Wait for postFrame in CanvasSnapshotPlugin, export material parameter types from three, fix texture serialization in material userData,

master
Palash Bansal vor 1 Jahr
Ursprung
Commit
75c2bf4ea8
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 5
- 5
package.json Datei anzeigen

"browser": "dist/index.js", "browser": "dist/index.js",
"exports": { "exports": {
".": { ".": {
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"require": "./dist/index.js"
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}, },
"./dist/": { "./dist/": {
"import": "./dist/", "import": "./dist/",
"require": "./dist/" "require": "./dist/"
}, },
"./lib": { "./lib": {
"import": "./lib/index.js",
"types": "./lib/index.d.ts"
"types": "./lib/index.d.ts",
"import": "./lib/index.js"
}, },
"./lib/": { "./lib/": {
"import": "./lib/", "import": "./lib/",

+ 6
- 5
src/plugins/animation/GLTFAnimationPlugin.ts Datei anzeigen

import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer' import {AViewerPluginEventMap, AViewerPluginSync, ThreeViewer} from '../../viewer'
import {absMax, now, onChange, onChange2, PointerDragHelper, serialize} from 'ts-browser-helpers' import {absMax, now, onChange, onChange2, PointerDragHelper, serialize} from 'ts-browser-helpers'
import {uiButton, uiDropdown, uiFolderContainer, uiMonitor, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js' import {uiButton, uiDropdown, uiFolderContainer, uiMonitor, UiObjectConfig, uiSlider, uiToggle} from 'uiconfig.js'
import {AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat} from 'three'
import {AnimationAction, AnimationClip, AnimationMixer, EventListener2, LoopOnce, LoopRepeat, Scene} from 'three'
import {ProgressivePlugin} from '../pipeline/ProgressivePlugin' import {ProgressivePlugin} from '../pipeline/ProgressivePlugin'
import {IObject3D} from '../../core'
import {IObject3D, ISceneEventMap} from '../../core'
import {generateUUID} from '../../three' import {generateUUID} from '../../three'
import type {FrameFadePlugin} from '../pipeline/FrameFadePlugin' import type {FrameFadePlugin} from '../pipeline/FrameFadePlugin'


} }
} }


protected _objectAdded = (ev: any)=>{
protected _objectAdded: EventListener2<'addSceneObject', ISceneEventMap, Scene> = (ev)=>{
const object = ev.object as IObject3D const object = ev.object as IObject3D
if (!this._viewer) return if (!this._viewer) return
let changed = false let changed = false
const isInRoot = ev.options?.addToRoot // for model stage etc


object.traverse((obj)=>{ object.traverse((obj)=>{
if (!this._viewer) return if (!this._viewer) return
object.userData.gltfAnim_SyncMaxDuration = true object.userData.gltfAnim_SyncMaxDuration = true
} // todo: check why do we need to do this? wont this create problems with looping or is it for that so that looping works in sync. } // todo: check why do we need to do this? wont this create problems with looping or is it for that so that looping works in sync.


const mixer = new AnimationMixer(this._viewer.scene.modelRoot) // add to modelRoot so it works with GLTF export...
const mixer = new AnimationMixer(isInRoot ? this._viewer.scene : this._viewer.scene.modelRoot) // add to modelRoot so it works with GLTF export...
const actions = clips.map(an=>mixer.clipAction(an).setLoop(this.loopAnimations ? LoopRepeat : LoopOnce, this.loopRepetitions)) const actions = clips.map(an=>mixer.clipAction(an).setLoop(this.loopAnimations ? LoopRepeat : LoopOnce, this.loopRepetitions))


actions.forEach(ac=>ac.clampWhenFinished = true) actions.forEach(ac=>ac.clampWhenFinished = true)
this.animations.push({ this.animations.push({
mixer, clips, actions, duration, mixer, clips, actions, duration,
}) })
// todo remove on object dispose
// todo remove on object dispose/remove


changed = true changed = true



+ 3
- 4
src/plugins/export/CanvasSnapshotPlugin.ts Datei anzeigen

* @param options waitForProgressive: wait for progressive rendering to finish, default: true * @param options waitForProgressive: wait for progressive rendering to finish, default: true
*/ */
async getFile(filename?: string, options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {waitForProgressive: true}): Promise<File|undefined> { async getFile(filename?: string, options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {waitForProgressive: true}): Promise<File|undefined> {
options.getDataUrl = false
return await this._getFile(filename || this.filename, options) as File
return await this._getFile(filename || this.filename, {...options, getDataUrl: false}) as File
} }


/** /**
* @param options waitForProgressive: wait for progressive rendering to finish, default: true * @param options waitForProgressive: wait for progressive rendering to finish, default: true
*/ */
async getDataUrl(options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {}): Promise<string> { async getDataUrl(options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {}): Promise<string> {
options.getDataUrl = true
return await this._getFile('', options) as string ?? ''
return await this._getFile('', {...options, getDataUrl: true}) as string ?? ''
} }


private async _getFile(filename: string, options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {}): Promise<File|string|undefined> { private async _getFile(filename: string, options: CanvasSnapshotOptions&{waitForProgressive?: boolean} = {}): Promise<File|string|undefined> {
await this._viewer?.doOnce('postFrame')
const viewer = this._viewer const viewer = this._viewer
const canvas = this._viewer?.canvas const canvas = this._viewer?.canvas
if (!viewer || !canvas) return undefined if (!viewer || !canvas) return undefined

+ 1
- 0
src/three/Threejs.ts Datei anzeigen

export {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js' export {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
export * from 'three/examples/jsm/utils/BufferGeometryUtils.js' export * from 'three/examples/jsm/utils/BufferGeometryUtils.js'
export type {Event, EventListener, EventListener2} from 'three' export type {Event, EventListener, EventListener2} from 'three'
export type {MeshPhysicalMaterialParameters, MeshBasicMaterialParameters, MaterialParameters} from 'three'

+ 2
- 2
src/utils/serialization.ts Datei anzeigen

isType: (obj: any) => obj.isMaterial || obj.metadata?.type === 'Material', isType: (obj: any) => obj.isMaterial || obj.metadata?.type === 'Material',
serialize: (obj: any, meta?: SerializationMetaType) => { serialize: (obj: any, meta?: SerializationMetaType) => {
if (!obj?.isMaterial) throw new Error('Expected a material') if (!obj?.isMaterial) throw new Error('Expected a material')
if (meta?.materials[obj.uuid]) return {uuid: obj.uuid, resource: 'materials'}
if (meta?.materials?.[obj.uuid]) return {uuid: obj.uuid, resource: 'materials'}
if (obj.userData.rootPath) { if (obj.userData.rootPath) {
// todo // todo
// it works for textures because image(Source) are immutable // it works for textures because image(Source) are immutable
obj.userData = {} obj.userData = {}
let res = {} as any let res = {} as any
try { try {
res = obj.toJSON(meta, true) // copying userData is handled in toJSON, see MeshStandardMaterial2
res = obj.toJSON(meta || meta2, true) // copying userData is handled in toJSON, see MeshStandardMaterial2
serializeMaterialUserData(res, userData, meta) serializeMaterialUserData(res, userData, meta)
res.userData.uuid = userData.uuid res.userData.uuid = userData.uuid
// todo: override generator to mention that this is a custom serializer? // todo: override generator to mention that this is a custom serializer?

Laden…
Abbrechen
Speichern