@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 12.2 kB
JavaScript
import{math as t}from"../../../core/math/math.js";import{Color as e}from"../../../core/math/color.js";import{Vec2 as s}from"../../../core/math/vec2.js";import{Vec4 as i}from"../../../core/math/vec4.js";import{LAYERID_WORLD as h,SPRITE_RENDERMODE_TILED as r,SPRITE_RENDERMODE_SLICED as n}from"../../../scene/constants.js";import{BatchGroup as a}from"../../../scene/batching/batch-group.js";import{GraphNode as l}from"../../../scene/graph-node.js";import{MeshInstance as o}from"../../../scene/mesh-instance.js";import{Model as _}from"../../../scene/model.js";import{Component as d}from"../component.js";import{SPRITETYPE_SIMPLE as c,SPRITETYPE_ANIMATED as p}from"./constants.js";import{SpriteAnimationClip as m}from"./sprite-animation-clip.js";const u="texture_emissiveMap",f="texture_opacityMap",y="material_emissive",I="material_opacity";class b extends d{constructor(t,r){super(t,r),this._evtLayersChanged=null,this._evtLayerAdded=null,this._evtLayerRemoved=null,this._type=c,this._material=t.defaultMaterial,this._color=new e(1,1,1,1),this._colorUniform=new Float32Array(3),this._speed=1,this._flipX=!1,this._flipY=!1,this._width=1,this._height=1,this._drawOrder=0,this._layers=[h],this._outerScale=new s(1,1),this._outerScaleUniform=new Float32Array(2),this._innerOffset=new i,this._innerOffsetUniform=new Float32Array(4),this._atlasRect=new i,this._atlasRectUniform=new Float32Array(4),this._batchGroupId=-1,this._batchGroup=null,this._node=new l,this._model=new _,this._model.graph=this._node,this._meshInstance=null,r.addChild(this._model.graph),this._model._entity=r,this._updateAabbFunc=this._updateAabb.bind(this),this._addedModel=!1,this._autoPlayClip=null,this._clips={},this._defaultClip=new m(this,{name:this.entity.name,fps:0,loop:!1,spriteAsset:null}),this._currentClip=this._defaultClip}set type(t){this._type!==t&&(this._type=t,this._type===c?(this.stop(),this._currentClip=this._defaultClip,this.enabled&&this.entity.enabled&&(this._currentClip.frame=this.frame,this._currentClip.sprite?this._showModel():this._hideModel())):this._type===p&&(this.stop(),this._autoPlayClip&&this._tryAutoPlay(),this._currentClip&&this._currentClip.isPlaying&&this.enabled&&this.entity.enabled?this._showModel():this._hideModel()))}get type(){return this._type}set frame(t){this._currentClip.frame=t}get frame(){return this._currentClip.frame}set spriteAsset(t){this._defaultClip.spriteAsset=t}get spriteAsset(){return this._defaultClip._spriteAsset}set sprite(t){this._currentClip.sprite=t}get sprite(){return this._currentClip.sprite}set material(t){this._material=t,this._meshInstance&&(this._meshInstance.material=t)}get material(){return this._material}set color(t){this._color.r=t.r,this._color.g=t.g,this._color.b=t.b,this._meshInstance&&(this._colorUniform[0]=this._color.r,this._colorUniform[1]=this._color.g,this._colorUniform[2]=this._color.b,this._meshInstance.setParameter(y,this._colorUniform))}get color(){return this._color}set opacity(t){this._color.a=t,this._meshInstance&&this._meshInstance.setParameter(I,t)}get opacity(){return this._color.a}set clips(t){if(t){for(const e in this._clips){let s=!1;for(const i in t)if(t[i].name===e){s=!0,this._clips[e].fps=t[i].fps,this._clips[e].loop=t[i].loop,t[i].hasOwnProperty("sprite")?this._clips[e].sprite=t[i].sprite:t[i].hasOwnProperty("spriteAsset")&&(this._clips[e].spriteAsset=t[i].spriteAsset);break}s||this.removeClip(e)}for(const e in t)this._clips[t[e].name]||this.addClip(t[e]);this._autoPlayClip&&this._tryAutoPlay(),this._currentClip&&this._currentClip.sprite||this._hideModel()}else for(const t in this._clips)this.removeClip(t)}get clips(){return this._clips}get currentClip(){return this._currentClip}set speed(t){this._speed=t}get speed(){return this._speed}set flipX(t){this._flipX!==t&&(this._flipX=t,this._updateTransform())}get flipX(){return this._flipX}set flipY(t){this._flipY!==t&&(this._flipY=t,this._updateTransform())}get flipY(){return this._flipY}set width(t){t!==this._width&&(this._width=t,this._outerScale.x=this._width,!this.sprite||this.sprite.renderMode!==r&&this.sprite.renderMode!==n||this._updateTransform())}get width(){return this._width}set height(t){t!==this._height&&(this._height=t,this._outerScale.y=this.height,!this.sprite||this.sprite.renderMode!==r&&this.sprite.renderMode!==n||this._updateTransform())}get height(){return this._height}set batchGroupId(t){if(this._batchGroupId===t)return;const e=this._batchGroupId;var s,i;(this._batchGroupId=t,this.entity.enabled&&e>=0)&&(null==(s=this.system.app.batcher)||s.remove(a.SPRITE,e,this.entity));this.entity.enabled&&t>=0?null==(i=this.system.app.batcher)||i.insert(a.SPRITE,t,this.entity):e>=0&&this._currentClip&&this._currentClip.sprite&&this.enabled&&this.entity.enabled&&this._showModel()}get batchGroupId(){return this._batchGroupId}set autoPlayClip(t){this._autoPlayClip=t instanceof m?t.name:t,this._tryAutoPlay()}get autoPlayClip(){return this._autoPlayClip}set drawOrder(t){this._drawOrder=t,this._meshInstance&&(this._meshInstance.drawOrder=t)}get drawOrder(){return this._drawOrder}set layers(t){this._addedModel&&this._hideModel(),this._layers=t,this._meshInstance&&this.enabled&&this.entity.enabled&&this._showModel()}get layers(){return this._layers}get aabb(){return this._meshInstance?this._meshInstance.aabb:null}onEnable(){const t=this.system.app,e=t.scene,s=e.layers;var i;(this._evtLayersChanged=e.on("set:layers",this._onLayersChanged,this),s&&(this._evtLayerAdded=s.on("add",this._onLayerAdded,this),this._evtLayerRemoved=s.on("remove",this._onLayerRemoved,this)),this._showModel(),this._autoPlayClip&&this._tryAutoPlay(),this._batchGroupId>=0)&&(null==(i=t.batcher)||i.insert(a.SPRITE,this._batchGroupId,this.entity))}onDisable(){var t;const e=this.system.app,s=e.scene.layers;var i,h,r;(null==(t=this._evtLayersChanged)||t.off(),this._evtLayersChanged=null,s)&&(null==(i=this._evtLayerAdded)||i.off(),this._evtLayerAdded=null,null==(h=this._evtLayerRemoved)||h.off(),this._evtLayerRemoved=null);(this.stop(),this._hideModel(),this._batchGroupId>=0)&&(null==(r=e.batcher)||r.remove(a.SPRITE,this._batchGroupId,this.entity))}onDestroy(){var t;this._currentClip=null,this._defaultClip&&(this._defaultClip._destroy(),this._defaultClip=null);for(const t in this._clips)this._clips[t]._destroy();this._clips=null,this._hideModel(),this._model=null,null==(t=this._node)||t.remove(),this._node=null,this._meshInstance&&(this._meshInstance.material=null,this._meshInstance.mesh=null,this._meshInstance=null)}_showModel(){if(this._addedModel)return;if(!this._meshInstance)return;const t=[this._meshInstance];for(let e=0,s=this._layers.length;e<s;e++){const s=this.system.app.scene.layers.getLayerById(this._layers[e]);s&&s.addMeshInstances(t)}this._addedModel=!0}_hideModel(){if(!this._addedModel||!this._meshInstance)return;const t=[this._meshInstance];for(let e=0,s=this._layers.length;e<s;e++){const s=this.system.app.scene.layers.getLayerById(this._layers[e]);s&&s.removeMeshInstances(t)}this._addedModel=!1}_showFrame(t){if(!this.sprite)return;const e=this.sprite.meshes[t];if(!e)return void(this._meshInstance&&(this._meshInstance.mesh=null,this._meshInstance.visible=!1));let s;if(s=this.sprite.renderMode===n?this.system.default9SlicedMaterialSlicedMode:this.sprite.renderMode===r?this.system.default9SlicedMaterialTiledMode:this.system.defaultMaterial,this._meshInstance||(this._meshInstance=new o(e,this._material,this._node),this._meshInstance.castShadow=!1,this._meshInstance.receiveShadow=!1,this._meshInstance.drawOrder=this._drawOrder,this._model.meshInstances.push(this._meshInstance),this._colorUniform[0]=this._color.r,this._colorUniform[1]=this._color.g,this._colorUniform[2]=this._color.b,this._meshInstance.setParameter(y,this._colorUniform),this._meshInstance.setParameter(I,this._color.a),this.enabled&&this.entity.enabled&&this._showModel()),this._meshInstance.material!==s&&(this._meshInstance.material=s),this._meshInstance.mesh!==e&&(this._meshInstance.mesh=e,this._meshInstance.visible=!0,this._meshInstance._aabbVer=-1),this.sprite.atlas&&this.sprite.atlas.texture?(this._meshInstance.setParameter(u,this.sprite.atlas.texture),this._meshInstance.setParameter(f,this.sprite.atlas.texture)):(this._meshInstance.deleteParameter(u),this._meshInstance.deleteParameter(f)),!this.sprite.atlas||this.sprite.renderMode!==n&&this.sprite.renderMode!==r)this._meshInstance._updateAabbFunc=null;else{this._meshInstance._updateAabbFunc=this._updateAabbFunc;const e=this.sprite.atlas.frames[this.sprite.frameKeys[t]];if(e){const t=2/e.rect.z,s=2/e.rect.w;this._innerOffset.set(e.border.x*t,e.border.y*s,e.border.z*t,e.border.w*s);const i=this.sprite.atlas.texture;this._atlasRect.set(e.rect.x/i.width,e.rect.y/i.height,e.rect.z/i.width,e.rect.w/i.height)}else this._innerOffset.set(0,0,0,0);this._innerOffsetUniform[0]=this._innerOffset.x,this._innerOffsetUniform[1]=this._innerOffset.y,this._innerOffsetUniform[2]=this._innerOffset.z,this._innerOffsetUniform[3]=this._innerOffset.w,this._meshInstance.setParameter("innerOffset",this._innerOffsetUniform),this._atlasRectUniform[0]=this._atlasRect.x,this._atlasRectUniform[1]=this._atlasRect.y,this._atlasRectUniform[2]=this._atlasRect.z,this._atlasRectUniform[3]=this._atlasRect.w,this._meshInstance.setParameter("atlasRect",this._atlasRectUniform)}this._updateTransform()}_updateTransform(){let e=this.flipX?-1:1,s=this.flipY?-1:1,i=0,h=0;if(this.sprite&&(this.sprite.renderMode===n||this.sprite.renderMode===r)){let r=1,n=1;if(this.sprite.atlas){const t=this.sprite.atlas.frames[this.sprite.frameKeys[this.frame]];t&&(r=t.rect.z,n=t.rect.w,i=(.5-t.pivot.x)*this._width,h=(.5-t.pivot.y)*this._height)}const a=r/this.sprite.pixelsPerUnit,l=n/this.sprite.pixelsPerUnit;this._outerScale.set(Math.max(this._width,this._innerOffset.x*a),Math.max(this._height,this._innerOffset.y*l)),e*=a,s*=l,this._outerScale.x/=a,this._outerScale.y/=l,e*=t.clamp(this._width/(this._innerOffset.x*a),1e-4,1),s*=t.clamp(this._height/(this._innerOffset.y*l),1e-4,1),this._meshInstance&&(this._outerScaleUniform[0]=this._outerScale.x,this._outerScaleUniform[1]=this._outerScale.y,this._meshInstance.setParameter("outerScale",this._outerScaleUniform))}this._node.setLocalScale(e,s,1),this._node.setLocalPosition(i,h,0)}_updateAabb(t){return t.center.set(0,0,0),t.halfExtents.set(.5*this._outerScale.x,.5*this._outerScale.y,.001),t.setFromTransformedAabb(t,this._node.getWorldTransform()),t}_tryAutoPlay(){if(!this._autoPlayClip)return;if(this.type!==p)return;const t=this._clips[this._autoPlayClip];!t||t.isPlaying||this._currentClip&&this._currentClip.isPlaying||this.enabled&&this.entity.enabled&&this.play(t.name)}_onLayersChanged(t,e){t.off("add",this.onLayerAdded,this),t.off("remove",this.onLayerRemoved,this),e.on("add",this.onLayerAdded,this),e.on("remove",this.onLayerRemoved,this),this.enabled&&this.entity.enabled&&this._showModel()}_onLayerAdded(t){this.layers.indexOf(t.id)<0||this._addedModel&&this.enabled&&this.entity.enabled&&this._meshInstance&&t.addMeshInstances([this._meshInstance])}_onLayerRemoved(t){if(!this._meshInstance)return;this.layers.indexOf(t.id)<0||t.removeMeshInstances([this._meshInstance])}removeModelFromLayers(){for(let t=0;t<this.layers.length;t++){const e=this.system.app.scene.layers.getLayerById(this.layers[t]);e&&e.removeMeshInstances([this._meshInstance])}}addClip(t){const e=new m(this,{name:t.name,fps:t.fps,loop:t.loop,spriteAsset:t.spriteAsset});return this._clips[t.name]=e,e.name&&e.name===this._autoPlayClip&&this._tryAutoPlay(),e}removeClip(t){delete this._clips[t]}clip(t){return this._clips[t]}play(t){const e=this._clips[t],s=this._currentClip;return s&&s!==e&&(s._playing=!1),this._currentClip=e,this._currentClip&&(this._currentClip=e,this._currentClip.play()),e}pause(){this._currentClip!==this._defaultClip&&this._currentClip.isPlaying&&this._currentClip.pause()}resume(){this._currentClip!==this._defaultClip&&this._currentClip.isPaused&&this._currentClip.resume()}stop(){this._currentClip!==this._defaultClip&&this._currentClip.stop()}}b.EVENT_PLAY="play",b.EVENT_PAUSE="pause",b.EVENT_RESUME="resume",b.EVENT_STOP="stop",b.EVENT_END="end",b.EVENT_LOOP="loop";export{b as SpriteComponent};