threepipe
Version:
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.
52 lines (46 loc) • 2.47 kB
text/typescript
import {SimpleJSONLoader} from './SimpleJSONLoader'
import {ThreeViewer} from '../../viewer'
import {getEmptyMeta, SerializationMetaType, ThreeSerialization} from '../../utils/serialization'
import {IMaterial} from '../../core'
export class JSONMaterialLoader extends SimpleJSONLoader {
// todo remove spread after node 22 widespread support
static SupportedJSONTypes = ()=>['Material', ...[...ThreeSerialization.SerializableMaterials.values()].flatMap(t => [t.TYPE, ...t.TypeAlias || []])]
static SupportedJSONExtensions = ()=>['mat', ...[...ThreeSerialization.SerializableMaterials.values()].map(t => t.TypeSlug)]
viewer?: ThreeViewer
/**
* Find any existing material with the same uuid and update it instead of creating a new one
* This is a global flag to toggle this behavior on or off
* @default false
*/
static FindExistingMaterial = false
async parseAsync(json: Record<string, any>): Promise<any> {
if (!this.viewer) throw 'Viewer not set in JSONMaterialLoader.'
let mat = undefined
if (JSONMaterialLoader.FindExistingMaterial && json.uuid && this.viewer) {
// find any existing mat with the same uuid.
mat = this.viewer.materialManager.findMaterial(json.uuid)
}
return await JSONMaterialLoader.DeserializeMaterialJSON(json, this.viewer, undefined, mat)
}
static async DeserializeMaterialJSON(json: any, viewer: ThreeViewer, meta?: SerializationMetaType, obj?: IMaterial|IMaterial[]) {
meta = meta || getEmptyMeta()
const json2 = {...json}
if (json.images) {
if (Array.isArray(json.images)) meta.images = Object.fromEntries(json.images.map((i: any) => [i.uuid, i]))
else meta.images = json.images
delete json2.images
}
if (json.textures) {
if (Array.isArray(json.textures)) meta.textures = Object.fromEntries(json.textures.map((t: any) => [t.uuid, t]))
else meta.textures = json.textures
delete json2.textures
}
if (json.materials) {
if (Array.isArray(json.materials)) meta.materials = Object.fromEntries(json.materials.map((m: any) => [m.uuid, m]))
else meta.materials = json.materials
delete json2.materials
}
const resources = await viewer.loadConfigResources(meta)
return ThreeSerialization.Deserialize(json2, obj || undefined, resources)
}
}