UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 10.2 kB
import{RefCountedObject as e}from"../core/ref-counted-object.js";import{Vec3 as t}from"../core/math/vec3.js";import{BoundingBox as r}from"../core/shape/bounding-box.js";import{SEMANTIC_TANGENT as i,SEMANTIC_BLENDINDICES as s,TYPE_UINT8 as a,SEMANTIC_BLENDWEIGHT as n,SEMANTIC_POSITION as o,TYPE_UINT16 as h,TYPE_INT16 as m,TYPE_INT8 as f,BUFFER_STATIC as d,BUFFER_DYNAMIC as u,TYPE_FLOAT32 as x,SEMANTIC_NORMAL as c,SEMANTIC_TEXCOORD as g,SEMANTIC_COLOR as _,PRIMITIVE_TRIANGLES as y,PRIMITIVE_POINTS as l,typedArrayIndexFormats as D,PRIMITIVE_LINES as p,INDEXFORMAT_UINT32 as v,INDEXFORMAT_UINT16 as B}from"../platform/graphics/constants.js";import{IndexBuffer as S}from"../platform/graphics/index-buffer.js";import{VertexBuffer as b}from"../platform/graphics/vertex-buffer.js";import{VertexFormat as V}from"../platform/graphics/vertex-format.js";import{VertexIterator as C}from"../platform/graphics/vertex-iterator.js";import{RENDERSTYLE_WIREFRAME as U,RENDERSTYLE_POINTS as N,RENDERSTYLE_SOLID as O}from"./constants.js";let A=0;class I{constructor(){this.initDefaults()}initDefaults(){this.recreate=!1,this.verticesUsage=d,this.indicesUsage=d,this.maxVertices=0,this.maxIndices=0,this.vertexCount=0,this.indexCount=0,this.vertexStreamsUpdated=!1,this.indexStreamUpdated=!1,this.vertexStreamDictionary={},this.indices=null}_changeVertexCount(e,t){this.vertexCount||(this.vertexCount=e)}}I.DEFAULT_COMPONENTS_POSITION=3,I.DEFAULT_COMPONENTS_NORMAL=3,I.DEFAULT_COMPONENTS_UV=2,I.DEFAULT_COMPONENTS_COLORS=4;class T{constructor(e,t,r,i,s){this.data=e,this.componentCount=t,this.dataType=r,this.dataTypeNormalize=i,this.asInt=s}}class E extends e{constructor(e,t){super(),this._aabbVer=0,this._aabb=new r,this._storageVertex=!1,this._storageIndex=!1,this.id=A++,this.device=e,this._storageIndex=(null==t?void 0:t.storageIndex)||!1,this._storageVertex=(null==t?void 0:t.storageVertex)||!1,this.vertexBuffer=null,this.indexBuffer=[null],this.primitive=[{type:0,base:0,count:0}],this.skin=null,this._morph=null,this._geometryData=null,this.boneAabb=null}static fromGeometry(e,t,r={}){const o=new E(e,r),{positions:h,normals:m,tangents:f,colors:d,uvs:u,uvs1:x,blendIndices:c,blendWeights:g,indices:_}=t;return h&&o.setPositions(h),m&&o.setNormals(m),f&&o.setVertexStream(i,f,4),d&&o.setColors32(d),u&&o.setUvs(0,u),x&&o.setUvs(1,x),c&&o.setVertexStream(s,c,4,c.length/4,a),g&&o.setVertexStream(n,g,4),_&&o.setIndices(_),o.update(),o}set morph(e){e!==this._morph&&(this._morph&&this._morph.decRefCount(),this._morph=e,e&&e.incRefCount())}get morph(){return this._morph}set aabb(e){this._aabb=e,this._aabbVer++}get aabb(){return this._aabb}destroy(){const e=this.morph;e&&(this.morph=null,e.refCount<1&&e.destroy()),this.vertexBuffer&&(this.vertexBuffer.destroy(),this.vertexBuffer=null);for(let e=0;e<this.indexBuffer.length;e++)this._destroyIndexBuffer(e);this.indexBuffer.length=0,this._geometryData=null}_destroyIndexBuffer(e){this.indexBuffer[e]&&(this.indexBuffer[e].destroy(),this.indexBuffer[e]=null)}_initBoneAabbs(e){let i,d,u,x,c;this.boneAabb=[],this.boneUsed=[];const g=[],_=[],y=this.boneUsed,l=this.skin.boneNames.length;let D,p,v;for(let e=0;e<l;e++)g[e]=new t(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),_[e]=new t(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE);const B=new C(this.vertexBuffer),S=B.element[o],b=B.element[n],V=B.element[s],U=this.vertexBuffer.numVertices;for(let t=0;t<U;t++){for(let r=0;r<4;r++){if(b.array[b.index+r]>0){const s=V.array[V.index+r];if(y[s]=!0,i=S.array[S.index],d=S.array[S.index+1],u=S.array[S.index+2],x=_[s],c=g[s],c.x>i&&(c.x=i),c.y>d&&(c.y=d),c.z>u&&(c.z=u),x.x<i&&(x.x=i),x.y<d&&(x.y=d),x.z<u&&(x.z=u),e){let r=D=i,s=p=d,a=v=u;for(let i=0;i<e.length;i++){const n=e[i],o=n.deltaPositions[3*t],h=n.deltaPositions[3*t+1],m=n.deltaPositions[3*t+2];o<0?r+=o:D+=o,h<0?s+=h:p+=h,m<0?a+=m:v+=m}c.x>r&&(c.x=r),c.y>s&&(c.y=s),c.z>a&&(c.z=a),x.x<D&&(x.x=D),x.y<p&&(x.y=p),x.z<v&&(x.z=v)}}}B.next()}const N=this.vertexBuffer.getFormat().elements.find((e=>e.name===o));if(N&&N.normalize){const e=(()=>{switch(N.dataType){case f:return e=>Math.max(e/127,-1);case a:return e=>e/255;case m:return e=>Math.max(e/32767,-1);case h:return e=>e/65535;default:return e=>e}})();for(let t=0;t<l;t++)if(y[t]){const r=g[t],i=_[t];r.set(e(r.x),e(r.y),e(r.z)),i.set(e(i.x),e(i.y),e(i.z))}}for(let e=0;e<l;e++){const t=new r;t.setMinMax(g[e],_[e]),this.boneAabb.push(t)}}_initGeometryData(){this._geometryData||(this._geometryData=new I,this.vertexBuffer&&(this._geometryData.vertexCount=this.vertexBuffer.numVertices,this._geometryData.maxVertices=this.vertexBuffer.numVertices),this.indexBuffer.length>0&&this.indexBuffer[0]&&(this._geometryData.indexCount=this.indexBuffer[0].numIndices,this._geometryData.maxIndices=this.indexBuffer[0].numIndices))}clear(e,t,r=0,i=0){this._initGeometryData(),this._geometryData.initDefaults(),this._geometryData.recreate=!0,this._geometryData.maxVertices=r,this._geometryData.maxIndices=i,this._geometryData.verticesUsage=e?d:u,this._geometryData.indicesUsage=t?d:u}setVertexStream(e,t,r,i,s=x,a=!1,n=!1){this._initGeometryData();const o=i||t.length/r;this._geometryData._changeVertexCount(o,e),this._geometryData.vertexStreamsUpdated=!0,this._geometryData.vertexStreamDictionary[e]=new T(t,r,s,a,n)}getVertexStream(e,t){let r=0,i=!1;if(this._geometryData){const s=this._geometryData.vertexStreamDictionary[e];s&&(i=!0,r=this._geometryData.vertexCount,ArrayBuffer.isView(t)?t.set(s.data):(t.length=0,t.push(s.data)))}if(!i&&this.vertexBuffer){r=new C(this.vertexBuffer).readData(e,t)}return r}setPositions(e,t=I.DEFAULT_COMPONENTS_POSITION,r){this.setVertexStream(o,e,t,r,x,!1)}setNormals(e,t=I.DEFAULT_COMPONENTS_NORMAL,r){this.setVertexStream(c,e,t,r,x,!1)}setUvs(e,t,r=I.DEFAULT_COMPONENTS_UV,i){this.setVertexStream(g+e,t,r,i,x,!1)}setColors(e,t=I.DEFAULT_COMPONENTS_COLORS,r){this.setVertexStream(_,e,t,r,x,!1)}setColors32(e,t){this.setVertexStream(_,e,I.DEFAULT_COMPONENTS_COLORS,t,a,!0)}setIndices(e,t){this._initGeometryData(),this._geometryData.indexStreamUpdated=!0,this._geometryData.indices=e,this._geometryData.indexCount=t||e.length}getPositions(e){return this.getVertexStream(o,e)}getNormals(e){return this.getVertexStream(c,e)}getUvs(e,t){return this.getVertexStream(g+e,t)}getColors(e){return this.getVertexStream(_,e)}getIndices(e){let t=0;if(this._geometryData&&this._geometryData.indices){const r=this._geometryData.indices;if(t=this._geometryData.indexCount,ArrayBuffer.isView(e))e.set(r);else{e.length=0;for(let t=0,i=r.length;t<i;t++)e.push(r[t])}}else if(this.indexBuffer.length>0&&this.indexBuffer[0]){t=this.indexBuffer[0].readData(e)}return t}update(e=y,t=!0){if(this._geometryData){if(t){const e=this._geometryData.vertexStreamDictionary[o];e&&3===e.componentCount&&(this._aabb.compute(e.data,this._geometryData.vertexCount),this._aabbVer++)}let r=this._geometryData.recreate;this._geometryData.vertexCount>this._geometryData.maxVertices&&(r=!0,this._geometryData.maxVertices=this._geometryData.vertexCount),r&&this.vertexBuffer&&(this.vertexBuffer.destroy(),this.vertexBuffer=null);let i=this._geometryData.recreate;this._geometryData.indexCount>this._geometryData.maxIndices&&(i=!0,this._geometryData.maxIndices=this._geometryData.indexCount),i&&this.indexBuffer.length>0&&this.indexBuffer[0]&&(this.indexBuffer[0].destroy(),this.indexBuffer[0]=null),this._geometryData.vertexStreamsUpdated&&this._updateVertexBuffer(),this._geometryData.indexStreamUpdated&&this._updateIndexBuffer(),this.primitive[0].type=e,this.indexBuffer.length>0&&this.indexBuffer[0]?this._geometryData.indexStreamUpdated&&(this.primitive[0].count=this._geometryData.indexCount,this.primitive[0].indexed=!0):this._geometryData.vertexStreamsUpdated&&(this.primitive[0].count=this._geometryData.vertexCount,this.primitive[0].indexed=!1),this._geometryData.vertexCount=0,this._geometryData.indexCount=0,this._geometryData.vertexStreamsUpdated=!1,this._geometryData.indexStreamUpdated=!1,this._geometryData.recreate=!1,this.updateRenderStates()}}_buildVertexFormat(e){const t=[];for(const e in this._geometryData.vertexStreamDictionary){const r=this._geometryData.vertexStreamDictionary[e];t.push({semantic:e,components:r.componentCount,type:r.dataType,normalize:r.dataTypeNormalize,asInt:r.asInt})}return new V(this.device,t,e)}_updateVertexBuffer(){if(!this.vertexBuffer){const e=this._geometryData.maxVertices,t=this._buildVertexFormat(e);this.vertexBuffer=new b(this.device,t,e,{usage:this._geometryData.verticesUsage,storage:this._storageVertex})}const e=new C(this.vertexBuffer),t=this._geometryData.vertexCount;for(const r in this._geometryData.vertexStreamDictionary){const i=this._geometryData.vertexStreamDictionary[r];e.writeData(r,i.data,t),delete this._geometryData.vertexStreamDictionary[r]}e.end()}_updateIndexBuffer(){if(this.indexBuffer.length<=0||!this.indexBuffer[0]){const e=this._geometryData.maxVertices,t=e>65535||0===e?v:B,r=this._storageIndex?{storage:!0}:void 0;this.indexBuffer[0]=new S(this.device,t,this._geometryData.maxIndices,this._geometryData.indicesUsage,void 0,r)}const e=this._geometryData.indices;if(e){this.indexBuffer[0].writeData(e,this._geometryData.indexCount),this._geometryData.indices=null}}prepareRenderState(e){e===U?this.generateWireframe():e===N&&(this.primitive[N]={type:l,base:0,count:this.vertexBuffer?this.vertexBuffer.numVertices:0,indexed:!1})}updateRenderStates(){this.primitive[N]&&this.prepareRenderState(N),this.primitive[U]&&this.prepareRenderState(U)}generateWireframe(){this._destroyIndexBuffer(U);const e=this.vertexBuffer.numVertices,t=[];let r;if(this.indexBuffer.length>0&&this.indexBuffer[0]){const i=[[0,1],[1,2],[2,0]],s=this.primitive[O].base,a=this.primitive[O].count,n=this.indexBuffer[O],o=new D[n.format](n.storage),h=new Set;for(let r=s;r<s+a;r+=3)for(let s=0;s<3;s++){const a=o[r+i[s][0]],n=o[r+i[s][1]],m=a>n?n*e+a:a*e+n;h.has(m)||(h.add(m),t.push(a,n))}r=n.format}else{for(let r=0;r<e;r+=3)t.push(r,r+1,r+1,r+2,r+2,r);r=t.length>65535?v:B}const i=new S(this.vertexBuffer.device,r,t.length);new D[i.format](i.storage).set(t),i.unlock(),this.primitive[U]={type:p,base:0,count:t.length,indexed:!0},this.indexBuffer[U]=i}}export{E as Mesh};