浏览代码

Tweakpane image drag drop support for using the same texture references.

master
Palash Bansal 2 年前
父节点
当前提交
69a9794010
没有帐户链接到提交者的电子邮件
共有 1 个文件被更改,包括 32 次插入14 次删除
  1. 32
    14
      src/plugins/ui/tweakpane/tpImageInputGenerator.ts

+ 32
- 14
src/plugins/ui/tweakpane/tpImageInputGenerator.ts 查看文件

import {ThreeViewer} from '../../../viewer' import {ThreeViewer} from '../../../viewer'
import type {FolderApi} from 'tweakpane' import type {FolderApi} from 'tweakpane'
import {UiObjectConfig} from 'uiconfig.js' import {UiObjectConfig} from 'uiconfig.js'
import {imageBitmapToBase64, makeTextSvg} from 'ts-browser-helpers'
import {getOrCall, imageBitmapToBase64, makeTextSvg} from 'ts-browser-helpers'
import {generateUUID, textureToDataUrl} from '../../../three' import {generateUUID, textureToDataUrl} from '../../../three'
import {ITexture, upgradeTexture} from '../../../core' import {ITexture, upgradeTexture} from '../../../core'
import { import {
dataTexImage: makeTextSvg('Data Texture'), dataTexImage: makeTextSvg('Data Texture'),
lutCubeTexImage: makeTextSvg('CUBE Texture'), lutCubeTexImage: makeTextSvg('CUBE Texture'),
compressedTexImage: makeTextSvg('Compressed Texture'), compressedTexImage: makeTextSvg('Compressed Texture'),
textureMap: {} as any,
imageMap: {} as any, imageMap: {} as any,
tempMap: {} as any, tempMap: {} as any,
} }
} }


const setterTex = (v1: any, config: UiObjectConfig, renderer: TweakpaneUiPlugin)=>{ const setterTex = (v1: any, config: UiObjectConfig, renderer: TweakpaneUiPlugin)=>{
if (v1?.isTexture) {
if (v1 && v1.isTexture) {
if (!v1.isDataTexture) { if (!v1.isDataTexture) {
const key = renderer.methods.getBinding(config)[1] + '' const key = renderer.methods.getBinding(config)[1] + ''
const isLinear = ['normalMap', 'aoMap', 'emissiveMap', 'roughnessMap', 'metalnessMap', 'displacementMap', 'bumpMap', 'alphaMap'].includes(key) const isLinear = ['normalMap', 'aoMap', 'emissiveMap', 'roughnessMap', 'metalnessMap', 'displacementMap', 'bumpMap', 'alphaMap'].includes(key)
} else { } else {
v1.needsUpdate = true v1.needsUpdate = true
} }
if (!staticData.textureMap[v1.image?.id]) staticData.textureMap[v1.image?.id] = v1
} }
config.__proxy.value_ = v1 config.__proxy.value_ = v1
renderer.methods.setValue(config, v1, {last: true}, false) renderer.methods.setValue(config, v1, {last: true}, false)
setterTex(iMapKey, config, renderer) setterTex(iMapKey, config, renderer)
return return
} }
if (cc?.image === v
|| cc?.image?.src === v.src
|| cc?.image?.tp_src === v.tp_src && v.tp_src != null
|| cc?.image?.tp_src === v.src && v.src != null
|| cc?.image?.src === v.tp_src && v.tp_src != null
) return
if (cc === v || cc && (
cc.image === v
|| cc.image?.src === v.src
|| cc.image?.tp_src === v.tp_src && v.tp_src != null
|| cc.image?.tp_src === v.src && v.src != null
|| cc.image?.src === v.tp_src && v.tp_src != null
)) return


if (v instanceof File) { // v.src must be from createObjectURL. if (v instanceof File) { // v.src must be from createObjectURL.
viewer.assetManager.importer.importSingle<ITexture>({file: v, path: (v as any).src}).then(texture => { viewer.assetManager.importer.importSingle<ITexture>({file: v, path: (v as any).src}).then(texture => {
} }
setterTex(texture, config, renderer) setterTex(texture, config, renderer)
}) })
} else if (v.isTexture) {
setterTex(v, config, renderer)
} else { // HTMLImageElement, ImageBitmap, HTMLVideoElement } else { // HTMLImageElement, ImageBitmap, HTMLVideoElement
const tex: ITexture = new Texture(v)
let tex: ITexture = staticData.textureMap[v.id] || staticData.textureMap[v.src] || staticData.textureMap[v.tp_src]
if (tex) {
setterTex(tex, config, renderer)
return
}
tex = new Texture(v)
upgradeTexture.call(tex) upgradeTexture.call(tex)
tex.assetType = 'texture' tex.assetType = 'texture'
tex.needsUpdate = true tex.needsUpdate = true
Object.defineProperty(config.__proxy, 'value', { Object.defineProperty(config.__proxy, 'value', {
get: () => { get: () => {
config.__proxy.value_ = renderer.methods.getValue(config) config.__proxy.value_ = renderer.methods.getValue(config)
return proxyGetValue(config.__proxy.value_, viewer)
const ret = proxyGetValue(config.__proxy.value_, viewer)
if (!staticData.textureMap[ret.id ?? ret]) staticData.textureMap[ret.id ?? ret] = config.__proxy.value_
return ret
}, },
set: (v: any) => { set: (v: any) => {
config.__proxy.value_ = renderer.methods.getValue(config)
if (getOrCall(config.readOnly)) return
config.__proxy.value_ = renderer.methods.getValue(config) // current value
proxySetValue(v, config.__proxy.value_, config, viewer, renderer) proxySetValue(v, config.__proxy.value_, config, viewer, renderer)
}, },
}) })
const cv = config.uiRef.controller_.valueController.value.rawValue const cv = config.uiRef.controller_.valueController.value.rawValue
const isPlaceholder = cv === staticData.placeholderVal || cv?.isPlaceholder const isPlaceholder = cv === staticData.placeholderVal || cv?.isPlaceholder
const items: any = isPlaceholder ? {} : { const items: any = isPlaceholder ? {} : {
['remove image']: () => removeImage(config, renderer),
['download image']: () => downloadImage(config, renderer, viewer), ['download image']: () => downloadImage(config, renderer, viewer),
} }
const menu = CustomContextMenu.Create({
...items,
const readOnly = getOrCall(config.readOnly)
if (!isPlaceholder && !readOnly) Object.assign(items, {
['remove image']: () => removeImage(config, renderer),
})
if (!readOnly) Object.assign(items, {
['set/replace image']: () => inp.click(), ['set/replace image']: () => inp.click(),
['from url']: async() => imageFromUrl(renderer, config, viewer), ['from url']: async() => imageFromUrl(renderer, config, viewer),
})
const menu = CustomContextMenu.Create({
...items,
'cancel': () => {return}, 'cancel': () => {return},
}, 2, rect.height + 8, false, true) }, 2, rect.height + 8, false, true)
target.parentElement?.appendChild(menu) target.parentElement?.appendChild(menu)

正在加载...
取消
保存