vue-gl
Version:
Vue.js components rendering 3D graphics reactively via three.js
2 lines (1 loc) • 9.71 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("three"),require("vue-gl")):"function"==typeof define&&define.amd?define(["three","vue-gl"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).VueGL=t.VueGL||{},t.VueGL.VglObjLoader=e(t.THREE,t.VueGL))}(this,(function(t,e){"use strict";const s=/^[og]\s*(.+)?/,o=/^mtllib /,i=/^usemtl /,n=/^usemap /,r=new t.Vector3,a=new t.Vector3,l=new t.Vector3,c=new t.Vector3,h=new t.Vector3;function u(){const t={objects:[],object:{},vertices:[],normals:[],colors:[],uvs:[],materials:{},materialLibraries:[],startObject:function(t,e){if(this.object&&!1===this.object.fromDeclaration)return this.object.name=t,void(this.object.fromDeclaration=!1!==e);const s=this.object&&"function"==typeof this.object.currentMaterial?this.object.currentMaterial():void 0;if(this.object&&"function"==typeof this.object._finalize&&this.object._finalize(!0),this.object={name:t||"",fromDeclaration:!1!==e,geometry:{vertices:[],normals:[],colors:[],uvs:[],hasUVIndices:!1},materials:[],smooth:!0,startMaterial:function(t,e){const s=this._finalize(!1);s&&(s.inherited||s.groupCount<=0)&&this.materials.splice(s.index,1);const o={index:this.materials.length,name:t||"",mtllib:Array.isArray(e)&&e.length>0?e[e.length-1]:"",smooth:void 0!==s?s.smooth:this.smooth,groupStart:void 0!==s?s.groupEnd:0,groupEnd:-1,groupCount:-1,inherited:!1,clone:function(t){const e={index:"number"==typeof t?t:this.index,name:this.name,mtllib:this.mtllib,smooth:this.smooth,groupStart:0,groupEnd:-1,groupCount:-1,inherited:!1};return e.clone=this.clone.bind(e),e}};return this.materials.push(o),o},currentMaterial:function(){if(this.materials.length>0)return this.materials[this.materials.length-1]},_finalize:function(t){const e=this.currentMaterial();if(e&&-1===e.groupEnd&&(e.groupEnd=this.geometry.vertices.length/3,e.groupCount=e.groupEnd-e.groupStart,e.inherited=!1),t&&this.materials.length>1)for(let t=this.materials.length-1;t>=0;t--)this.materials[t].groupCount<=0&&this.materials.splice(t,1);return t&&0===this.materials.length&&this.materials.push({name:"",smooth:this.smooth}),e}},s&&s.name&&"function"==typeof s.clone){const t=s.clone(0);t.inherited=!0,this.object.materials.push(t)}this.objects.push(this.object)},finalize:function(){this.object&&"function"==typeof this.object._finalize&&this.object._finalize(!0)},parseVertexIndex:function(t,e){const s=parseInt(t,10);return 3*(s>=0?s-1:s+e/3)},parseNormalIndex:function(t,e){const s=parseInt(t,10);return 3*(s>=0?s-1:s+e/3)},parseUVIndex:function(t,e){const s=parseInt(t,10);return 2*(s>=0?s-1:s+e/2)},addVertex:function(t,e,s){const o=this.vertices,i=this.object.geometry.vertices;i.push(o[t+0],o[t+1],o[t+2]),i.push(o[e+0],o[e+1],o[e+2]),i.push(o[s+0],o[s+1],o[s+2])},addVertexPoint:function(t){const e=this.vertices;this.object.geometry.vertices.push(e[t+0],e[t+1],e[t+2])},addVertexLine:function(t){const e=this.vertices;this.object.geometry.vertices.push(e[t+0],e[t+1],e[t+2])},addNormal:function(t,e,s){const o=this.normals,i=this.object.geometry.normals;i.push(o[t+0],o[t+1],o[t+2]),i.push(o[e+0],o[e+1],o[e+2]),i.push(o[s+0],o[s+1],o[s+2])},addFaceNormal:function(t,e,s){const o=this.vertices,i=this.object.geometry.normals;r.fromArray(o,t),a.fromArray(o,e),l.fromArray(o,s),h.subVectors(l,a),c.subVectors(r,a),h.cross(c),h.normalize(),i.push(h.x,h.y,h.z),i.push(h.x,h.y,h.z),i.push(h.x,h.y,h.z)},addColor:function(t,e,s){const o=this.colors,i=this.object.geometry.colors;void 0!==o[t]&&i.push(o[t+0],o[t+1],o[t+2]),void 0!==o[e]&&i.push(o[e+0],o[e+1],o[e+2]),void 0!==o[s]&&i.push(o[s+0],o[s+1],o[s+2])},addUV:function(t,e,s){const o=this.uvs,i=this.object.geometry.uvs;i.push(o[t+0],o[t+1]),i.push(o[e+0],o[e+1]),i.push(o[s+0],o[s+1])},addDefaultUV:function(){const t=this.object.geometry.uvs;t.push(0,0),t.push(0,0),t.push(0,0)},addUVLine:function(t){const e=this.uvs;this.object.geometry.uvs.push(e[t+0],e[t+1])},addFace:function(t,e,s,o,i,n,r,a,l){const c=this.vertices.length;let h=this.parseVertexIndex(t,c),u=this.parseVertexIndex(e,c),d=this.parseVertexIndex(s,c);if(this.addVertex(h,u,d),this.addColor(h,u,d),void 0!==r&&""!==r){const t=this.normals.length;h=this.parseNormalIndex(r,t),u=this.parseNormalIndex(a,t),d=this.parseNormalIndex(l,t),this.addNormal(h,u,d)}else this.addFaceNormal(h,u,d);if(void 0!==o&&""!==o){const t=this.uvs.length;h=this.parseUVIndex(o,t),u=this.parseUVIndex(i,t),d=this.parseUVIndex(n,t),this.addUV(h,u,d),this.object.geometry.hasUVIndices=!0}else this.addDefaultUV()},addPointGeometry:function(t){this.object.geometry.type="Points";const e=this.vertices.length;for(let s=0,o=t.length;s<o;s++){const o=this.parseVertexIndex(t[s],e);this.addVertexPoint(o),this.addColor(o)}},addLineGeometry:function(t,e){this.object.geometry.type="Line";const s=this.vertices.length,o=this.uvs.length;for(let e=0,o=t.length;e<o;e++)this.addVertexLine(this.parseVertexIndex(t[e],s));for(let t=0,s=e.length;t<s;t++)this.addUVLine(this.parseUVIndex(e[t],o))}};return t.startObject("",!1),t}class d extends t.Loader{constructor(t){super(t),this.materials=null}load(e,s,o,i){const n=this,r=new t.FileLoader(this.manager);r.setPath(this.path),r.setRequestHeader(this.requestHeader),r.setWithCredentials(this.withCredentials),r.load(e,(function(t){try{s(n.parse(t))}catch(t){i?i(t):console.error(t),n.manager.itemError(e)}}),o,i)}setMaterials(t){return this.materials=t,this}parse(e){const r=new u;-1!==e.indexOf("\r\n")&&(e=e.replace(/\r\n/g,"\n")),-1!==e.indexOf("\\\n")&&(e=e.replace(/\\\n/g,""));const a=e.split("\n");let l="",c="",h=0,d=[];const f="function"==typeof"".trimLeft;for(let t=0,e=a.length;t<e;t++)if(l=a[t],l=f?l.trimLeft():l.trim(),h=l.length,0!==h&&(c=l.charAt(0),"#"!==c))if("v"===c){const t=l.split(/\s+/);switch(t[0]){case"v":r.vertices.push(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3])),t.length>=7?r.colors.push(parseFloat(t[4]),parseFloat(t[5]),parseFloat(t[6])):r.colors.push(void 0,void 0,void 0);break;case"vn":r.normals.push(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3]));break;case"vt":r.uvs.push(parseFloat(t[1]),parseFloat(t[2]))}}else if("f"===c){const t=l.substr(1).trim().split(/\s+/),e=[];for(let s=0,o=t.length;s<o;s++){const o=t[s];if(o.length>0){const t=o.split("/");e.push(t)}}const s=e[0];for(let t=1,o=e.length-1;t<o;t++){const o=e[t],i=e[t+1];r.addFace(s[0],o[0],i[0],s[1],o[1],i[1],s[2],o[2],i[2])}}else if("l"===c){const t=l.substring(1).trim().split(" ");let e=[];const s=[];if(-1===l.indexOf("/"))e=t;else for(let o=0,i=t.length;o<i;o++){const i=t[o].split("/");""!==i[0]&&e.push(i[0]),""!==i[1]&&s.push(i[1])}r.addLineGeometry(e,s)}else if("p"===c){const t=l.substr(1).trim().split(" ");r.addPointGeometry(t)}else if(null!==(d=s.exec(l))){const t=(" "+d[0].substr(1).trim()).substr(1);r.startObject(t)}else if(i.test(l))r.object.startMaterial(l.substring(7).trim(),r.materialLibraries);else if(o.test(l))r.materialLibraries.push(l.substring(7).trim());else if(n.test(l))console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');else if("s"===c){if(d=l.split(" "),d.length>1){const t=d[1].trim().toLowerCase();r.object.smooth="0"!==t&&"off"!==t}else r.object.smooth=!0;const t=r.object.currentMaterial();t&&(t.smooth=r.object.smooth)}else{if("\0"===l)continue;console.warn('THREE.OBJLoader: Unexpected line: "'+l+'"')}r.finalize();const p=new t.Group;p.materialLibraries=[].concat(r.materialLibraries);if(!0===!(1===r.objects.length&&0===r.objects[0].geometry.vertices.length))for(let e=0,s=r.objects.length;e<s;e++){const s=r.objects[e],o=s.geometry,i=s.materials,n="Line"===o.type,a="Points"===o.type;let l=!1;if(0===o.vertices.length)continue;const c=new t.BufferGeometry;c.setAttribute("position",new t.Float32BufferAttribute(o.vertices,3)),o.normals.length>0&&c.setAttribute("normal",new t.Float32BufferAttribute(o.normals,3)),o.colors.length>0&&(l=!0,c.setAttribute("color",new t.Float32BufferAttribute(o.colors,3))),!0===o.hasUVIndices&&c.setAttribute("uv",new t.Float32BufferAttribute(o.uvs,2));const h=[];for(let e=0,s=i.length;e<s;e++){const s=i[e],o=s.name+"_"+s.smooth+"_"+l;let c=r.materials[o];if(null!==this.materials)if(c=this.materials.create(s.name),!n||!c||c instanceof t.LineBasicMaterial){if(a&&c&&!(c instanceof t.PointsMaterial)){const e=new t.PointsMaterial({size:10,sizeAttenuation:!1});t.Material.prototype.copy.call(e,c),e.color.copy(c.color),e.map=c.map,c=e}}else{const e=new t.LineBasicMaterial;t.Material.prototype.copy.call(e,c),e.color.copy(c.color),c=e}void 0===c&&(c=n?new t.LineBasicMaterial:a?new t.PointsMaterial({size:1,sizeAttenuation:!1}):new t.MeshPhongMaterial,c.name=s.name,c.flatShading=!s.smooth,c.vertexColors=l,r.materials[o]=c),h.push(c)}let u;if(h.length>1){for(let t=0,e=i.length;t<e;t++){const e=i[t];c.addGroup(e.groupStart,e.groupCount,t)}u=n?new t.LineSegments(c,h):a?new t.Points(c,h):new t.Mesh(c,h)}else u=n?new t.LineSegments(c,h[0]):a?new t.Points(c,h[0]):new t.Mesh(c,h[0]);u.name=s.name,p.add(u)}else if(r.vertices.length>0){const e=new t.PointsMaterial({size:1,sizeAttenuation:!1}),s=new t.BufferGeometry;s.setAttribute("position",new t.Float32BufferAttribute(r.vertices,3)),r.colors.length>0&&void 0!==r.colors[0]&&(s.setAttribute("color",new t.Float32BufferAttribute(r.colors,3)),e.vertexColors=!0);const o=new t.Points(s,e);p.add(o)}return p}}var f;return{extends:e.VglObject3d,beforeCreate:function(){f||(f=new d)},data:function(){return{obj:null}},computed:{inst:function(){return this.obj?this.obj:e.VglObject3d.computed.inst.call(this)}},props:{src:{type:String,required:!0}},watch:{src:{handler:function(t){var e=this;f.load(t,(function(t){e.obj=t,e.change()}))},immediate:!0}}}}));