namespace NT { /**
     * Holds reference information for a given material.
     */ class MaterialReferenceNode { /** The referenced material. */ public material : Material ; /** The number of times the material is referenced. Default is 1 because this is only created when a material is needed. */ public referenceCount : number = 1 ; param material public constructor ( material ) { this . material = material ; } } /** Represents the configuration for a material. These are typically created and stored in a materials file. */ export class MaterialConfig { /** The name of this material. */ public name : string ; /** The name of the shader used by this material. Default: undefined (BuiltinShader.BASIC) */ public shader ? : string ; /** The diffuse texture path of this material. */ public diffuse : string ; /** The specular texture path of this material. */ public specular : string ; /** The tint of this material. */ public tint : Color ; public static fromJson ( json ) { let config = new MaterialConfig ( ) ; if ( json . name !== undefined ) { config . name = String ( json . name ) ; } if ( json . shader !== undefined ) { config . shader = String ( json . shader ) ; } if ( json . diffuse !== undefined ) { config . diffuse = String ( json . diffuse ) ; } if ( json . specular !== undefined ) { config . specular = String ( json . specular ) ; } if ( json . tint !== undefined ) { config . tint = Color . fromJson ( json . tint ) ; } else { config . tint = Color . white ( ) ; } return config ; } } /**
     * Manages materials in the engine. This is responsible for managing material references, and automatically
     * destroying unreferenced materials.
     */ export class MaterialManager { private static _configLoaded : boolean = false ; private static _materials : { [ name ] : MaterialReferenceNode ; } = { } ; private static _materialConfigs : { [ name ] : MaterialConfig ; } = { } ; /** Private to enforce singleton pattern. */ private constructor ( ) { } /** Indicates if this manager is loaded. */ public static get isLoaded ( ) : boolean { return MaterialManager . _configLoaded ; } param message public static onMessage ( message ) { if ( message . code === MESSAGE_ASSET_LOADER_ASSET_LOADED + "assets/materials/baseMaterials.json" ) { Message . unsubscribeCallback ( MESSAGE_ASSET_LOADER_ASSET_LOADED + "assets/materials/baseMaterials.json" , MaterialManager . onMessage ) ; MaterialManager . processMaterialAsset ( message . context as JsonAsset ) ; } } /** Loads this manager. */ public static load ( ) { let asset = AssetManager . getAsset ( "assets/materials/baseMaterials.json" ) ; if ( asset !== undefined ) { MaterialManager . processMaterialAsset ( asset as JsonAsset ) ; } else { Message . subscribeCallback ( MESSAGE_ASSET_LOADER_ASSET_LOADED + "assets/materials/baseMaterials.json" , MaterialManager . onMessage ) ; } } param material public static registerMaterial ( materialConfig ) { if ( MaterialManager . _materialConfigs [ materialConfig . name ] === undefined ) { MaterialManager . _materialConfigs [ materialConfig . name ] = materialConfig ; } } param materialName public static getMaterial ( materialName ) { if ( MaterialManager . _materials [ materialName ] === undefined ) { if ( MaterialManager . _materialConfigs [ materialName ] !== undefined ) { let mat = Material . FromConfig ( MaterialManager . _materialConfigs [ materialName ] ) ; MaterialManager . _materials [ materialName ] = new MaterialReferenceNode ( mat ) ; return MaterialManager . _materials [ materialName ] . material ; } return undefined ; } else { MaterialManager . _materials [ materialName ] . referenceCount ++ ; return MaterialManager . _materials [ materialName ] . material ; } } param materialName public static releaseMaterial ( materialName ) { if ( MaterialManager . _materials [ materialName ] === undefined ) { console . warn ( "Cannot release a material which has not been registered." ) ; } else { MaterialManager . _materials [ materialName ] . referenceCount -- ; if ( MaterialManager . _materials [ materialName ] . referenceCount < 1 ) { MaterialManager . _materials [ materialName ] . material . destroy ( ) ; MaterialManager . _materials [ materialName ] . material = undefined ; delete MaterialManager . _materials [ materialName ] ; } } } private static processMaterialAsset ( asset ) { let materials = asset . Data . materials ; if ( materials ) { for ( let material of materials ) { let c = MaterialConfig . fromJson ( material ) ; MaterialManager . registerMaterial ( c ) ; } } MaterialManager . _configLoaded = true ; } } }