UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 6.4 kB
import{Mat4 as e}from"../../core/math/mat4.js";import{Vec3 as s}from"../../core/math/vec3.js";import{BoundingBox as t}from"../../core/shape/bounding-box.js";import{SEMANTIC_COLOR as n,INDEXFORMAT_UINT32 as o,INDEXFORMAT_UINT16 as r,PRIMITIVE_POINTS as i,PRIMITIVE_LINES as a,PRIMITIVE_LINELOOP as c,PRIMITIVE_LINESTRIP as m,PRIMITIVE_TRIANGLES as l,PRIMITIVE_TRISTRIP as p,PRIMITIVE_TRIFAN as h,TYPE_INT8 as d,TYPE_UINT8 as f,TYPE_INT16 as u,TYPE_UINT16 as g,TYPE_INT32 as v,TYPE_UINT32 as x,TYPE_FLOAT32 as _,SEMANTIC_POSITION as b,SEMANTIC_NORMAL as w,SEMANTIC_TANGENT as k,SEMANTIC_BLENDWEIGHT as j,SEMANTIC_BLENDINDICES as M,SEMANTIC_TEXCOORD0 as C,SEMANTIC_TEXCOORD1 as I,SEMANTIC_TEXCOORD2 as y,SEMANTIC_TEXCOORD3 as B,SEMANTIC_TEXCOORD4 as N,SEMANTIC_TEXCOORD5 as V,SEMANTIC_TEXCOORD6 as A,SEMANTIC_TEXCOORD7 as P}from"../../platform/graphics/constants.js";import{IndexBuffer as L}from"../../platform/graphics/index-buffer.js";import{VertexBuffer as S}from"../../platform/graphics/vertex-buffer.js";import{VertexFormat as U}from"../../platform/graphics/vertex-format.js";import{VertexIterator as E}from"../../platform/graphics/vertex-iterator.js";import{GraphNode as O}from"../../scene/graph-node.js";import{Mesh as z}from"../../scene/mesh.js";import{MeshInstance as F}from"../../scene/mesh-instance.js";import{Model as G}from"../../scene/model.js";import{Morph as H}from"../../scene/morph.js";import{MorphInstance as J}from"../../scene/morph-instance.js";import{MorphTarget as T}from"../../scene/morph-target.js";import{Skin as W}from"../../scene/skin.js";import{SkinInstance as q}from"../../scene/skin-instance.js";const D={points:i,lines:a,lineloop:c,linestrip:m,triangles:l,trianglestrip:p,trianglefan:h},K={int8:d,uint8:f,int16:u,uint16:g,int32:v,uint32:x,float32:_};class Q{constructor(e){this._device=e.device,this._defaultMaterial=e.defaultMaterial}parse(e,s){const t=e.model;if(!t)return void s(null,null);if(t.version<=1)return void s("JsonModelParser#parse: Trying to parse unsupported model format.");const n=this._parseNodes(e),o=this._parseSkins(e,n),r=this._parseVertexBuffers(e),i=this._parseIndexBuffers(e,r),a=this._parseMorphs(e,n,r),c=this._parseMeshes(e,o.skins,a.morphs,r,i.buffer,i.data),m=this._parseMeshInstances(e,n,c,o.skins,o.instances,a.morphs,a.instances),l=new G;l.graph=n[0],l.meshInstances=m,l.skinInstances=o.instances,l.morphInstances=a.instances,l.getGraph().syncHierarchy(),s(null,l)}_parseNodes(e){const s=e.model,t=[];let n;for(n=0;n<s.nodes.length;n++){const e=s.nodes[n],o=new O(e.name);o.setLocalPosition(e.position[0],e.position[1],e.position[2]),o.setLocalEulerAngles(e.rotation[0],e.rotation[1],e.rotation[2]),o.setLocalScale(e.scale[0],e.scale[1],e.scale[2]),o.scaleCompensation=!!e.scaleCompensation,t.push(o)}for(n=1;n<s.parents.length;n++)t[s.parents[n]].addChild(t[n]);return t}_parseSkins(s,t){const n=s.model,o=[],r=[];let i,a;for(i=0;i<n.skins.length;i++){const s=n.skins[i],c=[];for(a=0;a<s.inverseBindMatrices.length;a++){const t=s.inverseBindMatrices[a];c[a]=(new e).set(t)}const m=new W(this._device,c,s.boneNames);o.push(m);const l=new q(m),p=[];for(a=0;a<m.boneNames.length;a++){const e=m.boneNames[a],s=t[0].findByName(e);p.push(s)}l.bones=p,r.push(l)}return{skins:o,instances:r}}_getMorphVertexCount(e,s,t){for(let n=0;n<e.meshes.length;n++){const o=e.meshes[n];if(o.morph===s){return t[o.vertices].numVertices}}}_parseMorphs(e,n,o){const r=e.model,i=[],a=[];let c,m,l,p,h,d;if(r.morphs){const e=function(e,s,t){const n=new Float32Array(3*t);for(let t=0;t<s.length;t++){const o=3*s[t];n[o]=e[3*t],n[o+1]=e[3*t+1],n[o+2]=e[3*t+2]}return n};for(c=0;c<r.morphs.length;c++){for(p=r.morphs[c].targets,d=[],l=this._getMorphVertexCount(r,c,o),m=0;m<p.length;m++){const n=p[m].aabb,o=n.min,r=n.max,i=new t(new s(.5*(r[0]+o[0]),.5*(r[1]+o[1]),.5*(r[2]+o[2])),new s(.5*(r[0]-o[0]),.5*(r[1]-o[1]),.5*(r[2]-o[2]))),a=p[m].indices;let c=p[m].deltaPositions,f=p[m].deltaNormals;a&&(c=e(c,a,l),f=e(f,a,l)),h=new T({deltaPositions:c,deltaNormals:f,name:p[m].name,aabb:i}),d.push(h)}const n=new H(d,this._device);i.push(n);const f=new J(n);a.push(f)}}return{morphs:i,instances:a}}_parseVertexBuffers(e){const s=e.model,t=[],o={position:b,normal:w,tangent:k,blendWeight:j,blendIndices:M,color:n,texCoord0:C,texCoord1:I,texCoord2:y,texCoord3:B,texCoord4:N,texCoord5:V,texCoord6:A,texCoord7:P};for(let e=0;e<s.vertices.length;e++){const r=s.vertices[e],i=[];for(const e in r){const s=r[e];i.push({semantic:o[e],components:s.components,type:K[s.type],normalize:o[e]===n})}const a=new U(this._device,i),c=r.position.data.length/r.position.components,m=new S(this._device,a,c),l=new E(m);for(let e=0;e<c;e++){for(const s in r){const t=r[s];switch(t.components){case 1:l.element[o[s]].set(t.data[e]);break;case 2:l.element[o[s]].set(t.data[2*e],1-t.data[2*e+1]);break;case 3:l.element[o[s]].set(t.data[3*e],t.data[3*e+1],t.data[3*e+2]);break;case 4:l.element[o[s]].set(t.data[4*e],t.data[4*e+1],t.data[4*e+2],t.data[4*e+3])}}l.next()}l.end(),t.push(m)}return t}_parseIndexBuffers(e,s){const t=e.model;let n,i=null,a=null,c=0;for(n=0;n<t.meshes.length;n++){const e=t.meshes[n];void 0!==e.indices&&(c+=e.indices.length)}let m=0;for(n=0;n<s.length;n++)m=Math.max(m,s[n].numVertices);return c>0&&(m>65535&&this._device.extUintElement?(i=new L(this._device,o,c),a=new Uint32Array(i.lock())):(i=new L(this._device,r,c),a=new Uint16Array(i.lock()))),{buffer:i,data:a}}_parseMeshes(e,n,o,r,i,a){const c=e.model,m=[];let l=0;for(let e=0;e<c.meshes.length;e++){const p=c.meshes[e],h=p.aabb,d=h.min,f=h.max,u=new t(new s(.5*(f[0]+d[0]),.5*(f[1]+d[1]),.5*(f[2]+d[2])),new s(.5*(f[0]-d[0]),.5*(f[1]-d[1]),.5*(f[2]-d[2]))),g=void 0!==p.indices,v=new z(this._device);v.vertexBuffer=r[p.vertices],v.indexBuffer[0]=g?i:null,v.primitive[0].type=D[p.type],v.primitive[0].base=g?p.base+l:p.base,v.primitive[0].count=p.count,v.primitive[0].indexed=g,v.skin=void 0!==p.skin?n[p.skin]:null,v.morph=void 0!==p.morph?o[p.morph]:null,v.aabb=u,g&&(a.set(p.indices,l),l+=p.indices.length),m.push(v)}return null!==i&&i.unlock(),m}_parseMeshInstances(e,s,t,n,o,r,i){const a=e.model,c=[];let m;for(m=0;m<a.meshInstances.length;m++){const e=a.meshInstances[m],l=s[e.node],p=t[e.mesh],h=new F(p,this._defaultMaterial,l);if(p.skin){const e=n.indexOf(p.skin);h.skinInstance=o[e]}if(p.morph){const e=r.indexOf(p.morph);h.morphInstance=i[e]}c.push(h)}return c}}export{Q as JsonModelParser};