You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 lines
11 KiB
1 lines
11 KiB
!function(){class e extends THREE.Loader{constructor(e){super(e),this.debug=!1,this.group=null,this.position=0,this.materials=[],this.meshes=[],this.nodes=[]}load(e,t,s,i){const r=this,n=""===this.path?THREE.LoaderUtils.extractUrlBase(e):this.path,a=new THREE.FileLoader(this.manager);a.setPath(this.path),a.setResponseType("arraybuffer"),a.setRequestHeader(this.requestHeader),a.setWithCredentials(this.withCredentials),a.load(e,(function(s){try{t(r.parse(s,n))}catch(t){i?i(t):console.error(t),r.manager.itemError(e)}}),s,i)}parse(e,t){if(this.group=new THREE.Group,this.position=0,this.materials=[],this.meshes=[],this.nodes=[],this.readFile(e,t),0===this.nodes.length){for(var s=0;s<this.meshes.length;s++)this.group.add(this.meshes[s]);return this.group}for(let e=0;e<this.nodes.length;e++){const t=this.nodes[e],s=new THREE.Quaternion;s.setFromAxisAngle(new THREE.Vector3(t.rot.x,t.rot.y,t.rot.z),t.rot.w);let i=new THREE.Matrix4;if(i.compose(t.pos,s,t.scl),t.matrix=i,65535!==t.userId){const e=this.nodes.find((({id:e})=>e===t.userId));t.matrix=i.premultiply(e.matrix)}const r=this.meshes.find((({name:e})=>e===t.name));if(void 0===r)continue;const n=t.pivot;let a=t.matrix.clone();for(let e=0;e<3;e++)a.elements[12+e]+=a.elements[e]*-n.x+a.elements[4+e]*-n.y+a.elements[8+e]*-n.z;const o=new THREE.Matrix4;o.copy(r.matrix).invert(),a.multiply(o);let h=r.geometry.clone();h.applyMatrix4(a);let d=r.clone();d.geometry=h,this.group.add(d)}return this.group}readFile(e,n){const a=new DataView(e),o=this.readChunk(a);if(o.id===s||o.id===i||o.id===t){let e=this.nextChunk(a,o);for(;0!==e;){if(e===r){const e=this.readDWord(a);this.debugMessage("3DS file version: "+e)}else e===l?(this.resetPosition(a),this.readMeshData(a,n)):e===c?(this.resetPosition(a),this.readKeyFrameData(a)):this.debugMessage("Unknown main chunk: "+e.toString(16));e=this.nextChunk(a,o)}}this.debugMessage("Parsed "+this.meshes.length+" meshes")}readMeshData(e,t){const s=this.readChunk(e);let i=this.nextChunk(e,s);for(;0!==i;){if(i===g){const t=+this.readDWord(e);this.debugMessage("Mesh Version: "+t)}else if(i===H){const t=this.readFloat(e);this.debugMessage("Master scale: "+t),this.group.scale.set(t,t,t)}else i===Y?(this.debugMessage("Named Object"),this.resetPosition(e),this.readNamedObject(e)):i===F?(this.debugMessage("Material"),this.resetPosition(e),this.readMaterialEntry(e,t)):this.debugMessage("Unknown MDATA chunk: "+i.toString(16));i=this.nextChunk(e,s)}}readKeyFrameData(e){const t=this.readChunk(e);let s=this.nextChunk(e,t);for(;0!==s;)s===p||s===m||s===f||s===M||s===b||s===E||s===k?(this.debugMessage("Node"),this.resetPosition(e),this.readNode(e)):this.debugMessage("Unknown MDATA chunk: "+s.toString(16)),s=this.nextChunk(e,t)}readNode(e){const t=this.readChunk(e);let s=this.nextChunk(e,t),i={};for(;0!==s;){if(s===C){const t=this.readWord(e);i.id=t}else if(s===x){const t=this.readString(e,64);i.name=t,this.readWord(e),this.readWord(e);const s=this.readWord(e);i.userId=s}else if(s===T){const t=this.readVector(e);i.pivot=new THREE.Vector3(t[0],t[1],t[2])}else if(s===y){this.readTrack(e);const t=this.readVector(e);i.pos=new THREE.Vector3(t[0],t[1],t[2])}else if(s===w){this.readTrack(e);const t=-this.readFloat(e),s=this.readVector(e);i.rot=new THREE.Vector4(s[0],s[1],s[2],t)}else if(s===R){this.readTrack(e);const t=this.readVector(e);i.scl=new THREE.Vector3(t[0],t[1],t[2])}else this.debugMessage("Unknown named object chunk: "+s.toString(16));s=this.nextChunk(e,t)}this.endChunk(t),this.nodes.push(i)}readVector(e){return[this.readFloat(e),this.readFloat(e),this.readFloat(e)]}readTrack(e){this.readWord(e);this.readDWord(e),this.readDWord(e);this.readInt(e),this.readInt(e),this.readWord(e)}readNamedObject(e){const t=this.readChunk(e),s=this.readString(e,64);t.cur=this.position;let i=this.nextChunk(e,t);for(;0!==i;){if(i===Q){this.resetPosition(e);const t=this.readMesh(e);t.name=s,this.meshes.push(t)}else this.debugMessage("Unknown named object chunk: "+i.toString(16));i=this.nextChunk(e,t)}this.endChunk(t)}readMaterialEntry(e,t){const s=this.readChunk(e);let i=this.nextChunk(e,s);const r=new CLOUD.CloudStandardMaterial;for(;0!==i;){if(i===S)r.name=this.readString(e,64),this.debugMessage("\t Name: "+r.name);else if(i===B)this.debugMessage("\t Wireframe"),r.wireframe=!0;else if(i===O){const t=this.readByte(e);r.wireframeLinewidth=t,this.debugMessage("\t Wireframe Thickness: "+t)}else if(i===A)r.side=THREE.DoubleSide,this.debugMessage("\t DoubleSided");else if(i===v)this.debugMessage("\t Additive Blending"),r.blending=THREE.AdditiveBlending;else if(i===D)this.debugMessage("\t Diffuse THREE.Color"),r.color=this.readColor(e);else if(i===P)this.debugMessage("\t Specular THREE.Color"),r.specular=this.readColor(e);else if(i===W)this.debugMessage("\t Ambient color"),r.color=this.readColor(e);else if(i===U){const t=this.readPercentage(e);r.shininess=100*t,this.debugMessage("\t Shininess : "+t)}else if(i===V){const t=this.readPercentage(e);r.opacity=1-t,this.debugMessage("\tTransparency : "+t),r.transparent=r.opacity<1}else i===L?(this.debugMessage("\t ColorMap"),this.resetPosition(e),r.map=this.readMap(e,t)):i===N?(this.debugMessage("\t BumpMap"),this.resetPosition(e),r.bumpMap=this.readMap(e,t)):i===I?(this.debugMessage("\t OpacityMap"),this.resetPosition(e),r.alphaMap=this.readMap(e,t)):i===G?(this.debugMessage("\t SpecularMap"),this.resetPosition(e),r.specularMap=this.readMap(e,t)):this.debugMessage("\t Unknown material chunk: "+i.toString(16));i=this.nextChunk(e,s)}this.endChunk(s),r.side=THREE.DoubleSide,this.materials[r.name]=r}readMesh(e){const t=this.readChunk(e);let s=this.nextChunk(e,t);const i=new THREE.BufferGeometry,r=new CLOUD.CloudStandardMaterial,n=new THREE.Mesh(i,r);for(n.vertices=[],n.name="mesh";0!==s;){if(s===J){const t=this.readWord(e);this.debugMessage("\t Vertex: "+t);for(let s=0;s<t;s++){const t=this.readVector(e);let s=new THREE.Vector3(t[0],t[1],t[2]);n.vertices.push(s)}}else if(s===Z)this.resetPosition(e),this.readFaceArray(e,n);else if(s===_){const t=this.readWord(e);this.debugMessage("\t UV: "+t);const s=[];for(let i=0;i<t;i++)s.push(this.readFloat(e)),s.push(this.readFloat(e));i.setAttribute("uv",new THREE.Float32BufferAttribute(s,2))}else if(s===ee){this.debugMessage("\t Tranformation Matrix (TODO)");const t=[];for(let s=0;s<12;s++)t[s]=this.readFloat(e);const s=new THREE.Matrix4;s.elements[0]=t[0],s.elements[1]=t[3],s.elements[2]=t[6],s.elements[3]=t[9],s.elements[4]=t[1],s.elements[5]=t[4],s.elements[6]=t[7],s.elements[7]=t[10],s.elements[8]=t[2],s.elements[9]=t[5],s.elements[10]=t[8],s.elements[11]=t[11],s.elements[12]=0,s.elements[13]=0,s.elements[14]=0,s.elements[15]=1,s.transpose(),n.matrix=s}else this.debugMessage("\t Unknown mesh chunk: "+s.toString(16));s=this.nextChunk(e,t)}let a=!1,o=n.matrix.clone();if(o.determinant()<0){const e=new THREE.Matrix4;e.copy(o).invert(),o.scale(new THREE.Vector3(-1,1,1)),o.multiply(e),a=!0}let h=[];for(let e=0;e<n.vertices.length;e++){let t=n.vertices[e];a&&t.applyMatrix4(o),h.push(t.x),h.push(t.y),h.push(t.z)}return i.setAttribute("position",new THREE.Float32BufferAttribute(h,3)),this.endChunk(t),i.computeVertexNormals(),n}readFaceArray(e,t){const s=this.readChunk(e),i=this.readWord(e);this.debugMessage("\t Faces: "+i);const r=[];for(let t=0;t<i;++t)r.push(this.readWord(e),this.readWord(e),this.readWord(e)),this.readWord(e);t.geometry.setIndex(r);let n=0,a=0;for(;this.position<s.end;){const s=this.readChunk(e);if(s.id===$){this.debugMessage("\t\t\tMaterial THREE.Group"),this.resetPosition(e);const s=this.readMaterialGroup(e),i=3*s.index.length;t.geometry.addGroup(a,i,n),a+=i,n++;const r=this.materials[s.name];!1===Array.isArray(t.material)&&(t.material=[]),void 0!==r&&t.material.push(r)}else this.debugMessage("\t\t\tUnknown face array chunk: "+s.toString(16));this.endChunk(s)}1===t.material.length&&(t.material=t.material[0]),this.endChunk(s)}readMap(e,t){const s=this.readChunk(e);let i=this.nextChunk(e,s),r={};const n=new THREE.TextureLoader(this.manager);for(n.setPath(this.resourcePath||t).setCrossOrigin(this.crossOrigin);0!==i;){if(i===z){const s=this.readString(e,128);r=n.load(s,(e=>{e.image=CLOUD.MaterialUtil.ensurePowerOfTwo(e.image)})),this.debugMessage("\t\t\tFile: "+t+s)}else i===K?(r.offset.x=this.readFloat(e),this.debugMessage("\t\t\tOffsetX: "+r.offset.x)):i===X?(r.offset.y=this.readFloat(e),this.debugMessage("\t\t\tOffsetY: "+r.offset.y)):i===j?(r.repeat.x=this.readFloat(e),this.debugMessage("\t\t\tRepeatX: "+r.repeat.x)):i===q?(r.repeat.y=this.readFloat(e),this.debugMessage("\t\t\tRepeatY: "+r.repeat.y)):this.debugMessage("\t\t\tUnknown map chunk: "+i.toString(16));i=this.nextChunk(e,s)}return this.endChunk(s),r}readMaterialGroup(e){this.readChunk(e);const t=this.readString(e,64),s=this.readWord(e);this.debugMessage("\t\t\t\t Name: "+t),this.debugMessage("\t\t\t\t Faces: "+s);const i=[];for(let t=0;t<s;++t)i.push(this.readWord(e));return{name:t,index:i}}readColor(e){const t=this.readChunk(e),s=new THREE.Color;if(t.id===a||t.id===o){const t=this.readByte(e),i=this.readByte(e),r=this.readByte(e);s.setRGB(t/255,i/255,r/255),this.debugMessage("\t\t\tTHREE.Color: "+s.r+", "+s.g+", "+s.b)}else if(t.id===n||t.id===h){const t=this.readFloat(e),i=this.readFloat(e),r=this.readFloat(e);s.setRGB(t,i,r),this.debugMessage("\t\t\tTHREE.Color: "+s.r+", "+s.g+", "+s.b)}else this.debugMessage("\t\t\tUnknown color chunk: "+t.toString(16));return this.endChunk(t),s}readChunk(e){const t={};return t.cur=this.position,t.id=this.readWord(e),t.size=this.readDWord(e),t.end=t.cur+t.size,t.cur+=6,t}endChunk(e){this.position=e.end}nextChunk(e,t){if(t.cur>=t.end)return 0;this.position=t.cur;try{const s=this.readChunk(e);return t.cur+=s.size,s.id}catch(e){return this.debugMessage("Unable to read chunk at "+this.position),0}}resetPosition(){this.position-=6}readByte(e){const t=e.getUint8(this.position,!0);return this.position+=1,t}readFloat(e){try{const t=e.getFloat32(this.position,!0);return this.position+=4,t}catch(t){this.debugMessage(t+" "+this.position+" "+e.byteLength)}}readInt(e){const t=e.getInt32(this.position,!0);return this.position+=4,t}readShort(e){const t=e.getInt16(this.position,!0);return this.position+=2,t}readDWord(e){const t=e.getUint32(this.position,!0);return this.position+=4,t}readWord(e){const t=e.getUint16(this.position,!0);return this.position+=2,t}readString(e,t){let s="";for(let i=0;i<t;i++){const t=this.readByte(e);if(!t)break;s+=String.fromCharCode(t)}return s}setPath(e){return this.path=e,this}readPercentage(e){const t=this.readChunk(e);let s;switch(t.id){case d:s=this.readShort(e)/100;break;case u:s=this.readFloat(e);break;default:this.debugMessage("\t\t\tUnknown percentage chunk: "+t.toString(16))}return this.endChunk(t),s}debugMessage(e){this.debug&&console.log(e)}}const t=19789,s=15786,i=49725,r=2,n=16,a=17,o=18,h=19,d=48,u=49,l=15677,g=15678,c=45056,p=45057,m=45058,f=45059,M=45060,b=45061,k=45062,E=45063,C=45104,x=45072,T=45075,y=45088,w=45089,R=45090,H=256,F=45055,S=40960,W=40976,D=40992,P=41008,U=41024,V=41040,A=41089,v=41091,B=41093,O=41095,L=41472,I=41488,N=41520,G=41476,z=41728,j=41812,q=41814,K=41816,X=41818,Y=16384,Q=16640,J=16656,Z=16672,$=16688,_=16704,ee=16736;THREE.TDSLoader=e}(); |