@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 6.93 kB
JavaScript
import{hash32Fnv1a as t}from"../core/hash.js";import{SORTMODE_MATERIALMESH as e,SORTMODE_BACK2FRONT as s,SHADER_FORWARD as i,LIGHTTYPE_DIRECTIONAL as h,LAYER_FX as r,SORTMODE_NONE as a,SORTMODE_CUSTOM as n,SORTMODE_FRONT2BACK as l,SORTKEY_FORWARD as o}from"./constants.js";import{Material as c}from"./materials/material.js";const d=[null,function(t,e){return t.drawOrder-e.drawOrder},function(t,e){const s=t._key[o],i=e._key[o];return s===i&&t.mesh&&e.mesh?e.mesh.id-t.mesh.id:i-s},function(t,e){return e.zdist-t.zdist},function(t,e){return t.zdist-e.zdist}];let u=0;const g=[],_=new Set;class f{constructor(){this.opaque=[],this.transparent=[]}}class m{constructor(t={}){var h,r,a,n;this.meshInstances=[],this.meshInstancesSet=new Set,this.shadowCasters=[],this.shadowCastersSet=new Set,this._visibleInstances=new WeakMap,this._lights=[],this._lightsSet=new Set,this._clusteredLightsSet=new Set,this._splitLights=[[],[],[]],this._splitLightsDirty=!0,this.requiresLightCube=!1,this.cameras=[],this.camerasSet=new Set,this._dirtyComposition=!1,void 0!==t.id?(this.id=t.id,u=Math.max(this.id+1,u)):this.id=u++,this.name=t.name,this._enabled=null==(h=t.enabled)||h,this._refCounter=this._enabled?1:0,this.opaqueSortMode=null!=(r=t.opaqueSortMode)?r:e,this.transparentSortMode=null!=(a=t.transparentSortMode)?a:s,t.renderTarget&&(this.renderTarget=t.renderTarget),this.shaderPass=null!=(n=t.shaderPass)?n:i,this._clearColorBuffer=!!t.clearColorBuffer,this._clearDepthBuffer=!!t.clearDepthBuffer,this._clearStencilBuffer=!!t.clearStencilBuffer,this.onPreCull=t.onPreCull,this.onPreRender=t.onPreRender,this.onPreRenderOpaque=t.onPreRenderOpaque,this.onPreRenderTransparent=t.onPreRenderTransparent,this.onPostCull=t.onPostCull,this.onPostRender=t.onPostRender,this.onPostRenderOpaque=t.onPostRenderOpaque,this.onPostRenderTransparent=t.onPostRenderTransparent,this.onDrawCall=t.onDrawCall,this.onEnable=t.onEnable,this.onDisable=t.onDisable,this._enabled&&this.onEnable&&this.onEnable(),this.layerReference=t.layerReference,this.customSortCallback=null,this.customCalculateSortValues=null,this._lightHash=0,this._lightHashDirty=!1,this._lightIdHash=0,this._lightIdHashDirty=!1,this._shaderVersion=-1}set enabled(t){t!==this._enabled&&(this._dirtyComposition=!0,this._enabled=t,t?(this.incrementCounter(),this.onEnable&&this.onEnable()):(this.decrementCounter(),this.onDisable&&this.onDisable()))}get enabled(){return this._enabled}set clearColorBuffer(t){this._clearColorBuffer=t,this._dirtyComposition=!0}get clearColorBuffer(){return this._clearColorBuffer}set clearDepthBuffer(t){this._clearDepthBuffer=t,this._dirtyComposition=!0}get clearDepthBuffer(){return this._clearDepthBuffer}set clearStencilBuffer(t){this._clearStencilBuffer=t,this._dirtyComposition=!0}get clearStencilBuffer(){return this._clearStencilBuffer}get hasClusteredLights(){return this._clusteredLightsSet.size>0}get clusteredLightsSet(){return this._clusteredLightsSet}incrementCounter(){0===this._refCounter&&(this._enabled=!0,this.onEnable&&this.onEnable()),this._refCounter++}decrementCounter(){if(1===this._refCounter)this._enabled=!1,this.onDisable&&this.onDisable();else if(0===this._refCounter)return;this._refCounter--}addMeshInstances(t,e){const s=this.meshInstances,i=this.meshInstancesSet;for(let e=0;e<t.length;e++){const h=t[e];i.has(h)||(s.push(h),i.add(h),_.add(h.material))}if(e||this.addShadowCasters(t),_.size>0){const t=this._shaderVersion;_.forEach((e=>{t>=0&&e._shaderVersion!==t&&(e.getShaderVariant!==c.prototype.getShaderVariant&&e.clearVariants(),e._shaderVersion=t)})),_.clear()}}removeMeshInstances(t,e){const s=this.meshInstances,i=this.meshInstancesSet;for(let e=0;e<t.length;e++){const h=t[e];if(i.has(h)){i.delete(h);const t=s.indexOf(h);t>=0&&s.splice(t,1)}}e||this.removeShadowCasters(t)}addShadowCasters(t){const e=this.shadowCasters,s=this.shadowCastersSet;for(let i=0;i<t.length;i++){const h=t[i];h.castShadow&&!s.has(h)&&(s.add(h),e.push(h))}}removeShadowCasters(t){const e=this.shadowCasters,s=this.shadowCastersSet;for(let i=0;i<t.length;i++){const h=t[i];if(s.has(h)){s.delete(h);const t=e.indexOf(h);t>=0&&e.splice(t,1)}}}clearMeshInstances(t=!1){this.meshInstances.length=0,this.meshInstancesSet.clear(),t||(this.shadowCasters.length=0,this.shadowCastersSet.clear())}markLightsDirty(){this._lightHashDirty=!0,this._lightIdHashDirty=!0,this._splitLightsDirty=!0}addLight(t){const e=t.light;this._lightsSet.has(e)||(this._lightsSet.add(e),this._lights.push(e),this.markLightsDirty()),e.type!==h&&this._clusteredLightsSet.add(e)}removeLight(t){const e=t.light;this._lightsSet.has(e)&&(this._lightsSet.delete(e),this._lights.splice(this._lights.indexOf(e),1),this.markLightsDirty()),e.type!==h&&this._clusteredLightsSet.delete(e)}clearLights(){this._lightsSet.forEach((t=>t.removeLayer(this))),this._lightsSet.clear(),this._clusteredLightsSet.clear(),this._lights.length=0,this.markLightsDirty()}get splitLights(){if(this._splitLightsDirty){this._splitLightsDirty=!1;const t=this._splitLights;for(let e=0;e<t.length;e++)t[e].length=0;const e=this._lights;for(let s=0;s<e.length;s++){const i=e[s];i.enabled&&t[i._type].push(i)}for(let e=0;e<t.length;e++)t[e].sort(((t,e)=>t.key-e.key))}return this._splitLights}evaluateLightHash(e,s,i){let r=0;const a=this._lights;for(let t=0;t<a.length;t++){const r=a[t].type!==h;(e&&r||s&&!r)&&g.push(i?a[t].id:a[t].key)}return g.length>0&&(g.sort(),r=t(g),g.length=0),r}getLightHash(t){return this._lightHashDirty&&(this._lightHashDirty=!1,this._lightHash=this.evaluateLightHash(!t,!0,!1)),this._lightHash}getLightIdHash(){return this._lightIdHashDirty&&(this._lightIdHashDirty=!1,this._lightIdHash=this.evaluateLightHash(!0,!1,!0)),this._lightIdHash}addCamera(t){this.camerasSet.has(t.camera)||(this.camerasSet.add(t.camera),this.cameras.push(t),this._dirtyComposition=!0)}removeCamera(t){if(this.camerasSet.has(t.camera)){this.camerasSet.delete(t.camera);const e=this.cameras.indexOf(t);this.cameras.splice(e,1),this._dirtyComposition=!0}}clearCameras(){this.cameras.length=0,this.camerasSet.clear(),this._dirtyComposition=!0}_calculateSortDistances(t,e,s,i){for(let h=0;h<e;h++){const e=t[h];if(e.layer<=r)continue;if(e.calculateSortDistance){e.zdist=e.calculateSortDistance(e,s,i);continue}const a=e.aabb.center,n=a.x-s.x,l=a.y-s.y,o=a.z-s.z;e.zdist=n*i.x+l*i.y+o*i.z}}getCulledInstances(t){let e=this._visibleInstances.get(t);return e||(e=new f,this._visibleInstances.set(t,e)),e}sortVisible(t,e){const i=e?this.transparentSortMode:this.opaqueSortMode;if(i===a)return;const h=this.getCulledInstances(t),r=e?h.transparent:h.opaque,o=t.node;if(i===n){const t=o.getPosition(),e=o.forward;this.customCalculateSortValues&&this.customCalculateSortValues(r,r.length,t,e),this.customSortCallback&&r.sort(this.customSortCallback)}else{if(i===s||i===l){const t=o.getPosition(),e=o.forward;this._calculateSortDistances(r,r.length,t,e)}r.sort(d[i])}}}export{f as CulledInstances,m as Layer};