import tableJpg from 'url:../img/table.jpg' ; import glbModels from 'url:../img/models.auto.glb' ; import { Texture , Mesh , TextureLoader , Material , LinearEncoding , MeshStandardMaterial , MeshLambertMaterial , PlaneGeometry , RepeatWrapping } from 'three' ; import { GLTFLoader , GLTF } from 'three/examples/jsm/loaders/GLTFLoader' ; import { World } from './world' ; import { Size } from './types' ; export class AssetLoader { textures : Record < string , Texture > = { } ; meshes : Record < string , Mesh > = { } ; makeTable ( ) { const tableGeometry = new PlaneGeometry ( World . WIDTH + Size . TILE . y , World . WIDTH + Size . TILE . y ) ; const tableMaterial = new MeshLambertMaterial ( { color : 0xeeeeee , map : this . textures . table } ) ; const tableMesh = new Mesh ( tableGeometry , tableMaterial ) ; return tableMesh ; } makeCenter ( ) { return this . cloneMesh ( this . meshes . center ) ; } makeTray ( ) { const mesh = this . cloneMesh ( this . meshes . tray ) ; ( mesh . material as MeshStandardMaterial ) . color . setHex ( 0x363636 ) ; return mesh ; } make ( what ) { return this . cloneMesh ( this . meshes [ what ] ) ; } makeMarker ( ) { return this . cloneMesh ( this . meshes . marker ) ; } cloneMesh ( mesh ) { const newMesh = mesh . clone ( ) ; if ( Array . isArray ( mesh . material ) ) { newMesh . material = mesh . material . map ( m => m . clone ( ) ) ; } else { newMesh . material = mesh . material . clone ( ) ; } return newMesh ; } loadAll ( ) { return Promise . all ( [ this . loadTexture ( tableJpg , 'table' ) , this . loadModels ( glbModels ) , ( document as any ) . fonts . load ( '40px "Segment7Standard"' ) , ] ) . then ( ( ) => { this . textures . table . wrapS = RepeatWrapping ; this . textures . table . wrapT = RepeatWrapping ; this . textures . table . repeat . set ( 3 , 3 ) ; ( this . meshes . tile . material as MeshStandardMaterial ) . color . setHex ( 0xeeeeee ) ; } ) ; } loadTexture ( url , name ) { const loader = new TextureLoader ( ) ; return new Promise ( resolve => { loader . load ( url , ( texture ) => { this . textures [ name ] = this . processTexture ( texture ) ; ; resolve ( ) ; } ) ; } ) ; } loadModels ( url ) { const loader = new GLTFLoader ( ) ; return new Promise ( resolve => { loader . load ( url , ( model ) => { for ( const obj of model . scene . children ) { if ( ( obj as Mesh ) . isMesh ) { this . meshes [ obj . name ] = this . processMesh ( obj as Mesh ) ; } else { console . warn ( 'unrecognized object' , obj ) ; } } resolve ( ) ; } ) ; } ) ; } processTexture ( texture ) { texture . flipY = false ; texture . anisotropy = 4 ; return texture ; } processMesh ( mesh ) { if ( Array . isArray ( mesh . material ) ) { mesh . material = mesh . material . map ( this . processMaterial . bind ( this ) ) ; } else { mesh . material = this . processMaterial ( mesh . material ) ; } return mesh ; } processMaterial ( material ) { const standard = material as MeshStandardMaterial ; const map = standard . map ; if ( map !== null ) { map . encoding = LinearEncoding ; map . anisotropy = 4 ; } return new MeshLambertMaterial ( { map } ) ; } }