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
8.0 KiB
1 lines
8.0 KiB
!function(){class e extends THREE.Loader{constructor(e){super(e),this.debug=!1,this.group=null,this.materials=[],this.meshes=[]}load(e,s,t,a){const i=this,r=""===this.path?THREE.LoaderUtils.extractUrlBase(e):this.path,n=new THREE.FileLoader(this.manager);n.setPath(this.path),n.setResponseType("arraybuffer"),n.setRequestHeader(this.requestHeader),n.setWithCredentials(this.withCredentials),n.load(e,(function(t){try{s(i.parse(t,r))}catch(s){a?a(s):console.error(s),i.manager.itemError(e)}}),t,a)}parse(e,s){this.group=new THREE.Group,this.materials=[],this.meshes=[],this.readFile(e,s);for(let e=0;e<this.meshes.length;e++)this.group.add(this.meshes[e]);return this.group}readFile(e,n){const d=new DataView(e),o=new s(d,0,this.debugMessage);if(o.id===a||o.id===i||o.id===t){let e=o.readChunk();for(;e;){if(e.id===r){const s=e.readDWord();this.debugMessage("3DS file version: "+s)}else e.id===l?this.readMeshData(e,n):this.debugMessage("Unknown main chunk: "+e.hexId);e=o.readChunk()}}this.debugMessage("Parsed "+this.meshes.length+" meshes")}readMeshData(e,s){let t=e.readChunk();for(;t;){if(t.id===c){const e=+t.readDWord();this.debugMessage("Mesh Version: "+e)}else if(t.id===p){const e=t.readFloat();this.debugMessage("Master scale: "+e),this.group.scale.set(e,e,e)}else t.id===A?(this.debugMessage("Named Object"),this.readNamedObject(t)):t.id===M?(this.debugMessage("Material"),this.readMaterialEntry(t,s)):this.debugMessage("Unknown MDATA chunk: "+t.hexId);t=e.readChunk()}}readNamedObject(e){const s=e.readString();let t=e.readChunk();for(;t;){if(t.id===O){const e=this.readMesh(t);e.name=s,this.meshes.push(e)}else this.debugMessage("Unknown named object chunk: "+t.hexId);t=e.readChunk()}}readMaterialEntry(e,s){let t=e.readChunk();const a=new THREE.MeshPhongMaterial;for(;t;){if(t.id===f)a.name=t.readString(),this.debugMessage(" Name: "+a.name);else if(t.id===F)this.debugMessage(" Wireframe"),a.wireframe=!0;else if(t.id===x){const e=t.readByte();a.wireframeLinewidth=e,this.debugMessage(" Wireframe Thickness: "+e)}else if(t.id===C)a.side=THREE.DoubleSide,this.debugMessage(" DoubleSided");else if(t.id===w)this.debugMessage(" Additive Blending"),a.blending=THREE.AdditiveBlending;else if(t.id===m)this.debugMessage(" Diffuse Color"),a.color=this.readColor(t);else if(t.id===k)this.debugMessage(" Specular Color"),a.specular=this.readColor(t);else if(t.id===b)this.debugMessage(" Ambient color"),a.color=this.readColor(t);else if(t.id===E){const e=this.readPercentage(t);a.shininess=100*e,this.debugMessage(" Shininess : "+e)}else if(t.id===y){const e=this.readPercentage(t);a.opacity=1-e,this.debugMessage(" Transparency : "+e),a.transparent=a.opacity<1}else t.id===T?(this.debugMessage(" ColorMap"),a.map=this.readMap(t,s)):t.id===H?(this.debugMessage(" BumpMap"),a.bumpMap=this.readMap(t,s)):t.id===R?(this.debugMessage(" OpacityMap"),a.alphaMap=this.readMap(t,s)):t.id===W?(this.debugMessage(" SpecularMap"),a.specularMap=this.readMap(t,s)):this.debugMessage(" Unknown material chunk: "+t.hexId);t=e.readChunk()}this.materials[a.name]=a}readMesh(e){let s=e.readChunk();const t=new THREE.BufferGeometry,a=new THREE.MeshPhongMaterial,i=new THREE.Mesh(t,a);for(i.name="mesh";s;){if(s.id===P){const e=s.readWord();this.debugMessage(" Vertex: "+e);const a=[];for(let t=0;t<e;t++)a.push(s.readFloat()),a.push(s.readFloat()),a.push(s.readFloat());t.setAttribute("position",new THREE.Float32BufferAttribute(a,3))}else if(s.id===G)this.readFaceArray(s,i);else if(s.id===v){const e=s.readWord();this.debugMessage(" UV: "+e);const a=[];for(let t=0;t<e;t++)a.push(s.readFloat()),a.push(s.readFloat());t.setAttribute("uv",new THREE.Float32BufferAttribute(a,2))}else if(s.id===N){this.debugMessage(" Tranformation Matrix (TODO)");const e=[];for(let t=0;t<12;t++)e[t]=s.readFloat();const a=new THREE.Matrix4;a.elements[0]=e[0],a.elements[1]=e[6],a.elements[2]=e[3],a.elements[3]=e[9],a.elements[4]=e[2],a.elements[5]=e[8],a.elements[6]=e[5],a.elements[7]=e[11],a.elements[8]=e[1],a.elements[9]=e[7],a.elements[10]=e[4],a.elements[11]=e[10],a.elements[12]=0,a.elements[13]=0,a.elements[14]=0,a.elements[15]=1,a.transpose();const r=new THREE.Matrix4;r.copy(a).invert(),t.applyMatrix4(r),a.decompose(i.position,i.quaternion,i.scale)}else this.debugMessage(" Unknown mesh chunk: "+s.hexId);s=e.readChunk()}return t.computeVertexNormals(),i}readFaceArray(e,s){const t=e.readWord();this.debugMessage(" Faces: "+t);const a=[];for(let s=0;s<t;++s)a.push(e.readWord(),e.readWord(),e.readWord()),e.readWord();s.geometry.setIndex(a);let i=0,r=0;for(;!e.endOfChunk;){const t=e.readChunk();if(t.id===L){this.debugMessage(" Material Group");const e=this.readMaterialGroup(t),a=3*e.index.length;s.geometry.addGroup(r,a,i),r+=a,i++;const n=this.materials[e.name];!1===Array.isArray(s.material)&&(s.material=[]),void 0!==n&&s.material.push(n)}else this.debugMessage(" Unknown face array chunk: "+t.hexId)}1===s.material.length&&(s.material=s.material[0])}readMap(e,s){let t=e.readChunk(),a={};const i=new THREE.TextureLoader(this.manager);for(i.setPath(this.resourcePath||s).setCrossOrigin(this.crossOrigin);t;){if(t.id===B){const e=t.readString();a=i.load(e),this.debugMessage(" File: "+s+e)}else t.id===D?(a.offset.x=t.readFloat(),this.debugMessage(" OffsetX: "+a.offset.x)):t.id===I?(a.offset.y=t.readFloat(),this.debugMessage(" OffsetY: "+a.offset.y)):t.id===S?(a.repeat.x=t.readFloat(),this.debugMessage(" RepeatX: "+a.repeat.x)):t.id===U?(a.repeat.y=t.readFloat(),this.debugMessage(" RepeatY: "+a.repeat.y)):this.debugMessage(" Unknown map chunk: "+t.hexId);t=e.readChunk()}return a}readMaterialGroup(e){const s=e.readString(),t=e.readWord();this.debugMessage(" Name: "+s),this.debugMessage(" Faces: "+t);const a=[];for(let s=0;s<t;++s)a.push(e.readWord());return{name:s,index:a}}readColor(e){const s=e.readChunk(),t=new THREE.Color;if(s.id===d||s.id===o){const e=s.readByte(),a=s.readByte(),i=s.readByte();t.setRGB(e/255,a/255,i/255),this.debugMessage(" Color: "+t.r+", "+t.g+", "+t.b)}else if(s.id===n||s.id===h){const e=s.readFloat(),a=s.readFloat(),i=s.readFloat();t.setRGB(e,a,i),this.debugMessage(" Color: "+t.r+", "+t.g+", "+t.b)}else this.debugMessage(" Unknown color chunk: "+s.hexId);return t}readPercentage(e){const s=e.readChunk();switch(s.id){case u:return s.readShort()/100;case g:return s.readFloat();default:return this.debugMessage(" Unknown percentage chunk: "+s.hexId),0}}debugMessage(e){this.debug&&console.log(e)}}class s{constructor(e,s,t){this.data=e,this.offset=s,this.position=s,this.debugMessage=t,this.debugMessage instanceof Function&&(this.debugMessage=function(){}),this.id=this.readWord(),this.size=this.readDWord(),this.end=this.offset+this.size,this.end>e.byteLength&&this.debugMessage("Bad chunk size for chunk at "+s)}readChunk(){if(this.endOfChunk)return null;try{const e=new s(this.data,this.position,this.debugMessage);return this.position+=e.size,e}catch(e){return this.debugMessage("Unable to read chunk at "+this.position),null}}get hexId(){return this.id.toString(16)}get endOfChunk(){return this.position>=this.end}readByte(){const e=this.data.getUint8(this.position,!0);return this.position+=1,e}readFloat(){try{const e=this.data.getFloat32(this.position,!0);return this.position+=4,e}catch(e){return this.debugMessage(e+" "+this.position+" "+this.data.byteLength),0}}readInt(){const e=this.data.getInt32(this.position,!0);return this.position+=4,e}readShort(){const e=this.data.getInt16(this.position,!0);return this.position+=2,e}readDWord(){const e=this.data.getUint32(this.position,!0);return this.position+=4,e}readWord(){const e=this.data.getUint16(this.position,!0);return this.position+=2,e}readString(){let e="",s=this.readByte();for(;s;)e+=String.fromCharCode(s),s=this.readByte();return e}}const t=19789,a=15786,i=49725,r=2,n=16,d=17,o=18,h=19,u=48,g=49,l=15677,c=15678,p=256,M=45055,f=40960,b=40976,m=40992,k=41008,E=41024,y=41040,C=41089,w=41091,F=41093,x=41095,T=41472,R=41488,H=41520,W=41476,B=41728,S=41812,U=41814,D=41816,I=41818,A=16384,O=16640,P=16656,G=16672,L=16688,v=16704,N=16736;THREE.TDSLoader=e}(); |