UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 8.51 kB
import{BoundingBox as e}from"../core/shape/bounding-box.js";import{BoundingSphere as t}from"../core/shape/bounding-sphere.js";import{BindGroup as s}from"../platform/graphics/bind-group.js";import{UniformBuffer as a}from"../platform/graphics/uniform-buffer.js";import{MASK_AFFECT_DYNAMIC as i,SHADERDEF_UV0 as r,SHADERDEF_UV1 as h,SHADERDEF_VCOLOR as n,SHADERDEF_TANGENTS as l,LAYER_WORLD as c,RENDERSTYLE_SOLID as o,SHADERDEF_NOSHADOW as m,SHADERDEF_SKIN as d,SHADERDEF_MORPH_TEXTURE_BASED as u,SHADERDEF_MORPH_POSITION as p,SHADERDEF_MORPH_NORMAL as _,SHADERDEF_SCREENSPACE as b,SORTKEY_FORWARD as f,BLEND_NORMAL as g,BLEND_NONE as S,SHADERDEF_INSTANCING as y,MASK_AFFECT_LIGHTMAPPED as D,MASK_BAKE as I,SHADERDEF_LM as v,SHADERDEF_DIRLM as k,SHADERDEF_LMAMBIENT as A}from"./constants.js";import{GraphNode as w}from"./graph-node.js";import{getDefaultMaterial as x}from"./materials/default-material.js";import{LightmapCache as F}from"./graphics/lightmap-cache.js";let V=0;const P=new e,R=new e,C=new t,B=new Set;class M{constructor(e){this.vertexBuffer=null,this.count=e}}class j{constructor(){this.shader=void 0,this.bindGroup=null}getBindGroup(e){if(!this.bindGroup){const t=this.shader,i=t.meshUniformBufferFormat,r=new a(e,i,!1),h=t.meshBindGroupFormat;this.bindGroup=new s(e,h,r)}return this.bindGroup}destroy(){const e=this.bindGroup;var t;e&&(null==(t=e.defaultUniformBuffer)||t.destroy(),e.destroy(),this.bindGroup=null)}}class T{constructor(){this.shaderInstances=new Map}destroy(){this.shaderInstances.forEach((e=>e.destroy())),this.shaderInstances.clear()}}class G{constructor(t,s,a=null){if(this.visible=!0,this.castShadow=!1,this.transparent=!1,this._material=null,this._shaderCache=[],this.id=V++,this.pick=!0,t instanceof w){const e=t;t=s,s=a,a=e}if(this._key=[0,0],this.node=a,this._mesh=t,t.incRefCount(),this.material=s,this._shaderDefs=i<<16,t.vertexBuffer){const e=t.vertexBuffer.format;this._shaderDefs|=e.hasUv0?r:0,this._shaderDefs|=e.hasUv1?h:0,this._shaderDefs|=e.hasColor?n:0,this._shaderDefs|=e.hasTangents?l:0}this.layer=c,this._renderStyle=o,this._receiveShadow=!0,this._screenSpace=!1,this.cull=!0,this._updateAabb=!0,this._updateAabbFunc=null,this._calculateSortDistance=null,this.updateKey(),this._skinInstance=null,this._morphInstance=null,this.gsplatInstance=null,this.instancingData=null,this._customAabb=null,this.aabb=new e,this._aabbVer=-1,this._aabbMeshVer=-1,this.drawOrder=0,this.visibleThisFrame=!1,this.isVisibleFunc=null,this.parameters={},this.stencilFront=null,this.stencilBack=null,this.flipFacesFactor=1}set renderStyle(e){this._renderStyle=e,this.mesh.prepareRenderState(e)}get renderStyle(){return this._renderStyle}set mesh(e){e!==this._mesh&&(this._mesh&&this._mesh.decRefCount(),this._mesh=e,e&&e.incRefCount())}get mesh(){return this._mesh}set aabb(e){this._aabb=e}get aabb(){if(!this._updateAabb)return this._aabb;if(this._updateAabbFunc)return this._updateAabbFunc(this._aabb);let e=this._customAabb,t=!!e;if(!e)if(e=P,this.skinInstance){if(!this.mesh.boneAabb){const e=this._morphInstance?this._morphInstance.morph._targets:null;this.mesh._initBoneAabbs(e)}const s=this.mesh.boneUsed;let a=!0;for(let t=0;t<this.mesh.boneAabb.length;t++)s[t]&&(R.setFromTransformedAabb(this.mesh.boneAabb[t],this.skinInstance.matrices[t]),a?(a=!1,e.center.copy(R.center),e.halfExtents.copy(R.halfExtents)):e.add(R));t=!0}else if(this.node._aabbVer!==this._aabbVer||this.mesh._aabbVer!==this._aabbMeshVer){if(this.mesh?(e.center.copy(this.mesh.aabb.center),e.halfExtents.copy(this.mesh.aabb.halfExtents)):(e.center.set(0,0,0),e.halfExtents.set(0,0,0)),this.mesh&&this.mesh.morph){const t=this.mesh.morph.aabb;e._expand(t.getMin(),t.getMax())}t=!0,this._aabbVer=this.node._aabbVer,this._aabbMeshVer=this.mesh._aabbVer}return t&&this._aabb.setFromTransformedAabb(e,this.node.getWorldTransform()),this._aabb}clearShaders(){const e=this._shaderCache;for(let s=0;s<e.length;s++){var t;null==(t=e[s])||t.destroy(),e[s]=null}}getShaderInstance(e,t,s,a,i,r){let h,n=this._shaderCache[e];if(n?h=n.shaderInstances.get(t):(n=new T,this._shaderCache[e]=n),!h){const c=this._material,o=this._shaderDefs,m=`${e}_${o}_${t}`;if(h=new j,h.shader=c.variants.get(m),!h.shader){var l;const t=c.getShaderVariant(this.mesh.device,s,o,null,e,r,a,i,null==(l=this._mesh.vertexBuffer)?void 0:l.format);c.variants.set(m,t),h.shader=t}n.shaderInstances.set(t,h)}return h}set material(e){this.clearShaders();const t=this._material;t&&t.removeMeshInstanceRef(this),this._material=e,e&&(e.addMeshInstanceRef(this),this.transparent=e.transparent,this.updateKey())}get material(){return this._material}set layer(e){this._layer=e,this.updateKey()}get layer(){return this._layer}_updateShaderDefs(e){e!==this._shaderDefs&&(this._shaderDefs=e,this.clearShaders())}set calculateSortDistance(e){this._calculateSortDistance=e}get calculateSortDistance(){return this._calculateSortDistance}set receiveShadow(e){this._receiveShadow!==e&&(this._receiveShadow=e,this._updateShaderDefs(e?this._shaderDefs&~m:this._shaderDefs|m))}get receiveShadow(){return this._receiveShadow}set skinInstance(e){this._skinInstance=e,this._updateShaderDefs(e?this._shaderDefs|d:this._shaderDefs&~d),this._setupSkinUpdate()}get skinInstance(){return this._skinInstance}set morphInstance(e){var t;null==(t=this._morphInstance)||t.destroy(),this._morphInstance=e;let s=this._shaderDefs;s=e&&e.morph.useTextureMorph?s|u:s&~u,s=e&&e.morph.morphPositions?s|p:s&~p,s=e&&e.morph.morphNormals?s|_:s&~_,this._updateShaderDefs(s)}get morphInstance(){return this._morphInstance}set screenSpace(e){this._screenSpace!==e&&(this._screenSpace=e,this._updateShaderDefs(e?this._shaderDefs|b:this._shaderDefs&~b))}get screenSpace(){return this._screenSpace}set key(e){this._key[f]=e}get key(){return this._key[f]}set mask(e){const t=65535&this._shaderDefs;this._updateShaderDefs(t|e<<16)}get mask(){return this._shaderDefs>>16}set instancingCount(e){this.instancingData&&(this.instancingData.count=e)}get instancingCount(){return this.instancingData?this.instancingData.count:0}destroy(){var e,t;const s=this.mesh;s&&(this.mesh=null,s.refCount<1&&s.destroy()),this.setRealtimeLightmap(G.lightmapParamNames[0],null),this.setRealtimeLightmap(G.lightmapParamNames[1],null),null==(e=this._skinInstance)||e.destroy(),this._skinInstance=null,null==(t=this.morphInstance)||t.destroy(),this.morphInstance=null,this.clearShaders(),this.material=null}static _prepareRenderStyleForArray(e,t){if(e){for(let s=0;s<e.length;s++){e[s]._renderStyle=t;const a=e[s].mesh;B.has(a)||(B.add(a),a.prepareRenderState(t))}B.clear()}}_isVisible(e){return!!this.visible&&(this.isVisibleFunc?this.isVisibleFunc(e):(C.center=this.aabb.center,C.radius=this._aabb.halfExtents.length(),e.frustum.containsSphere(C)))}updateKey(){const e=this.material,t=e.alphaToCoverage||e.alphaTest?g:e.blendType;this._key[f]=(15&this.layer)<<27|(t===S?1:0)<<26|33554431&e.id}setInstancing(e,t=!1){e?(this.instancingData=new M(e.numVertices),this.instancingData.vertexBuffer=e,e.format.instancing=!0,this.cull=t):(this.instancingData=null,this.cull=!0),this._updateShaderDefs(e?this._shaderDefs|y:this._shaderDefs&~y)}ensureMaterial(e){this.material||(this.material=x(e))}clearParameters(){this.parameters={}}getParameters(){return this.parameters}getParameter(e){return this.parameters[e]}setParameter(e,t,s=-262141){if(void 0===t&&"object"==typeof e){const s=e;if(s.length){for(let e=0;e<s.length;e++)this.setParameter(s[e]);return}e=s.name,t=s.value}const a=this.parameters[e];a?(a.data=t,a.passFlags=s):this.parameters[e]={scopeId:null,data:t,passFlags:s}}setRealtimeLightmap(e,t){const s=this.getParameter(e);s!==t&&(s&&F.decRef(s.data),t?(F.incRef(t),this.setParameter(e,t)):this.deleteParameter(e))}deleteParameter(e){this.parameters[e]&&delete this.parameters[e]}setParameters(e,t){const s=this.parameters;for(const a in s){const i=s[a];i.passFlags&t&&(i.scopeId||(i.scopeId=e.scope.resolve(a)),i.scopeId.setValue(i.data))}}setLightmapped(e){e?this.mask=(this.mask|D)&~(i|I):(this.setRealtimeLightmap(G.lightmapParamNames[0],null),this.setRealtimeLightmap(G.lightmapParamNames[1],null),this._shaderDefs&=~(v|k|A),this.mask=(this.mask|i)&~(D|I))}setCustomAabb(e){e?this._customAabb?this._customAabb.copy(e):this._customAabb=e.clone():(this._customAabb=null,this._aabbVer=-1),this._setupSkinUpdate()}_setupSkinUpdate(){this._skinInstance&&(this._skinInstance._updateBeforeCull=!this._customAabb)}}G.lightmapParamNames=["texture_lightMap","texture_dirLightMap"];export{G as MeshInstance};