@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 4.26 kB
JavaScript
import{http as e}from"../../platform/net/http.js";import{PIXELFORMAT_RGBA8 as a}from"../../platform/graphics/constants.js";import{Texture as s}from"../../platform/graphics/texture.js";import{SPECULAR_PHONG as r}from"../../scene/constants.js";import{standardMaterialTextureParameters as t,standardMaterialCubemapParameters as o}from"../../scene/materials/standard-material-parameters.js";import{AssetReference as l}from"../asset/asset-reference.js";import{JsonStandardMaterialParser as n}from"../parsers/material/json-standard-material.js";import{ResourceHandler as i}from"./handler.js";const d={aoMap:"white",diffuseMap:"gray",specularMap:"gray",specularityFactorMap:"white",metalnessMap:"black",glossMap:"gray",sheenMap:"black",sheenGlossinessMap:"gray",clearCoatMap:"black",clearCoatGlossMap:"gray",clearCoatNormalMap:"normal",refractionMap:"white",emissiveMap:"gray",normalMap:"normal",heightMap:"gray",opacityMap:"gray",sphereMap:"gray",lightMap:"white"};class u extends i{constructor(e){super(e,"material"),this._assets=e.assets,this._device=e.graphicsDevice,this._placeholderTextures=null,this._parser=new n}load(a,s){"string"==typeof a&&(a={load:a,original:a}),e.get(a.load,{retry:this.maxRetries>0,maxRetries:this.maxRetries},((e,r)=>{e?s&&s(`Error loading material: ${a.original} [${e}]`):s&&(r._engine=!0,s(null,r))}))}open(e,a){const s=this._parser.parse(a);return a._engine&&(s._data=a,delete a._engine),s}_createPlaceholders(){this._placeholderTextures={};const e={white:[255,255,255,255],gray:[128,128,128,255],black:[0,0,0,255],normal:[128,128,255,255]};for(const r in e){if(!e.hasOwnProperty(r))continue;this._placeholderTextures[r]=new s(this._device,{width:2,height:2,format:a,name:"material_placeholder"});const t=this._placeholderTextures[r].lock();for(let a=0;a<4;a++)for(let s=0;s<4;s++)t[4*a+s]=e[r][s];this._placeholderTextures[r].unlock()}}patch(e,a){e.resource._data&&(e._data=e.resource._data,delete e.resource._data),e.data.name=e.name,e.resource.name=e.name,this._bindAndAssignAssets(e,a),e.off("unload",this._onAssetUnload,this),e.on("unload",this._onAssetUnload,this)}_onAssetUnload(e){delete e.data.parameters,delete e.data.chunks,delete e.data.name}_assignTexture(e,a,s){a.resource[e]=s}_getPlaceholderTexture(e){this._placeholderTextures||this._createPlaceholders();const a=d[e];return this._placeholderTextures[a]}_assignPlaceholderTexture(e,a){a.resource[e]=this._getPlaceholderTexture(e)}_onTextureLoad(e,a,s){this._assignTexture(e,a,s.resource),a.resource.update()}_onTextureAdd(e,a,s){this._assets.load(s)}_onTextureRemoveOrUnload(e,a,s){const r=a.resource;r&&a.resource[e]===s.resource&&(this._assignPlaceholderTexture(e,a),r.update())}_assignCubemap(e,a,s){if(a.resource[e]=s[0],"cubeMap"===e){const e=s.slice(1);e.every((e=>e))?a.resource.prefilteredCubemaps=e:e[0]&&(a.resource.envAtlas=e[0])}}_onCubemapLoad(e,a,s){this._assignCubemap(e,a,s.resources),this._parser.initialize(a.resource,a.data)}_onCubemapAdd(e,a,s){a.data.shadingModel===r&&(a.loadFaces=!0),this._assets.load(s)}_onCubemapRemoveOrUnload(e,a,s){const r=a.resource;a.data.prefilteredCubeMap128===s.resources[1]&&(this._assignCubemap(e,a,[null,null,null,null,null,null,null]),r.update())}_bindAndAssignAssets(e,a){const s=this._parser.migrate(e.data),r=e.resource,n="path"===s.mappingFormat,i=t;let d,u,c;for(d=0;d<i.length;d++){u=i[d],c=r._assetReferences[u];const t=s[u],o=r[u],h=o===this._getPlaceholderTexture(u),p=s.validated;!t||o&&p&&!h?c&&(n?c.url=null:c.id=null):(c||(c=new l(u,e,a,{load:this._onTextureLoad,add:this._onTextureAdd,remove:this._onTextureRemoveOrUnload,unload:this._onTextureRemoveOrUnload},this),r._assetReferences[u]=c),n?c.url=e.getAbsoluteUrl(t):c.id=t,c.asset&&(c.asset.resource?this._assignTexture(u,e,c.asset.resource):this._assignPlaceholderTexture(u,e),a.load(c.asset)))}const h=o;for(d=0;d<h.length;d++)u=h[d],c=r._assetReferences[u],s[u]&&!e.data.prefilteredCubeMap128&&(c||(c=new l(u,e,a,{load:this._onCubemapLoad,add:this._onCubemapAdd,remove:this._onCubemapRemoveOrUnload,unload:this._onCubemapRemoveOrUnload},this),r._assetReferences[u]=c),n?c.url=s[u]:c.id=s[u],c.asset&&(c.asset.loaded&&this._assignCubemap(u,e,c.asset.resources),a.load(c.asset)));this._parser.initialize(r,s)}}export{u as MaterialHandler};