diff --git a/build.js b/build.js index ce5cca6..0133545 100644 --- a/build.js +++ b/build.js @@ -1,120 +1,167 @@ +// # Build script using Node.js +// +// Single script build,used as a lightweight alternative +// when a build platform (grunt/gulp wtc.) feels like overkill +// +// - Dependencies: NPM/Node.js +// - Conventions: +// * code is in a lib/ folder with a main.js as the main context (closure) +// * a package.json on the root contains all the info about the lib: name, description, author, license +// * compiled files are saved in a build folder + // settings var FILE_ENCODING = 'utf-8', - EOL = '\n'; - + EOL = '\n'; + // Dependencies -var _cli = require('commander'), - _uglify = require("uglify-js2"), - _jshint = require('jshint'), - _handlebars = require('hbs'), - _fs = require('fs'); - - - // Logic - // - concatinate all files +var cli = require('commander'), + uglify = require("uglify-js"), + jshint = require('jshint'), + handlebars = require('hbs'), + fs = require('fs'), + zlib = require('zlib'); + + +// will generate a CSV if package info contains multiple licenses +handlebars.registerHelper('license', function(items){ + items = items.map(function(val){ + return val.type; + }); + return items.join(', '); +}); + + +// Logic +// - read module name from package file +var package = JSON.parse( fs.readFileSync('package.json', FILE_ENCODING) ); // condition the existance of package.json or component.json... +var name = package.name; +// - list files in the lib folder +//var src = libFiles(); +// - concatinate all files +var src = [ + 'lib/core.js', + 'lib/attributes.js', + 'lib/css.js', + 'lib/animations.js', + 'lib/effects.js', + 'lib/events.js', + 'lib/manipulation.js', + 'lib/markup.js', + 'lib/selectors.js', + 'lib/terrain.js', + 'lib/webgl.js', + 'lib/utils.js' +]; + +// - concatinate all files concat({ - src : [ - 'lib/_start.js', - 'lib/core.js', - 'lib/attributes.js', - 'lib/css.js', - 'lib/effects.js', - 'lib/events.js', - 'lib/manipulation.js', - 'lib/markup.js', - 'lib/selectors.js', - 'lib/three.js', - 'lib/utils.js', - 'lib/_end.js' - ], - dest : 'build/jquery.three.js' + src: src, + dest: 'build/'+ name +'.js' }); // - Validate js -lint('build/jquery.three.js', function(){ - +lint('build/'+ name +'.js', function(){ + // - Create / save minified file - uglify('build/jquery.three.js', 'build/jquery.three-min.js'); + minify('build/'+ name +'.js', 'build/'+ name +'-min.js'); }); - // // Methods function concat(opts) { - var fileList = opts.src; - var distPath = opts.dest; - + var fileList = opts.src; + var distPath = opts.dest; + var lib = fileList.map(function(filePath){ - return _fs.readFileSync(filePath, FILE_ENCODING); - }); - - var template = _handlebars.compile( lib.join(EOL) ); - + return fs.readFileSync(filePath, FILE_ENCODING); + }); + + var wrapper = fs.readFileSync('lib/main.js', FILE_ENCODING); + + var template = handlebars.compile( wrapper ); + //reuse package.json data and add build date - var data = JSON.parse( _fs.readFileSync('package.json', FILE_ENCODING) ); + var data = package; + data.lib = lib.join(EOL); data.build_date = (new Date()).toUTCString(); - + // Save uncompressed file - _fs.writeFileSync(distPath, template(data), FILE_ENCODING); - console.log(' '+ distPath +' built.'); - + fs.writeFileSync(distPath, template(data), FILE_ENCODING); + console.log(' '+ distPath +' built.'); + } -function uglify(srcPath, distPath) { +function minify(srcPath, distPath) { /* - var - jsp = uglyfyJS.parser, - pro = uglyfyJS.uglify, - ast = jsp.parse( _fs.readFileSync(srcPath, FILE_ENCODING) ); - - ast = pro.ast_mangle(ast); - ast = pro.ast_squeeze(ast); - */ - - var result = _uglify.minify(srcPath, { compressor: { - comments : true - } }); - - _fs.writeFileSync(distPath, result.code, FILE_ENCODING); - console.log(' '+ distPath +' built.'); + var + jsp = uglyfyJS.parser, + pro = uglyfyJS.uglify, + ast = jsp.parse( fs.readFileSync(srcPath, FILE_ENCODING) ); + + ast = pro.ast_mangle(ast); + ast = pro.ast_squeeze(ast); + */ + + var result = uglify.minify(srcPath, { + mangle: true, + output: { + comments : /@name|@author|@cc_on|@url|@license/ + } + }); + + fs.writeFileSync(distPath, result.code, FILE_ENCODING); + console.log(' '+ distPath +' built.'); + return; + + // gzip + zlib.gzip(result.code, function (error, bytes) { + if (error) throw error; + fs.writeFileSync(distPath, bytes, FILE_ENCODING); + console.log(' '+ distPath +' built.'); + }); + } - + function lint(path, callback) { - var buf = _fs.readFileSync(path, 'utf-8'); - // remove Byte Order Mark - buf = buf.replace(/^\uFEFF/, ''); - - _jshint.JSHINT(buf); - - var nErrors = _jshint.JSHINT.errors.length; - - if (nErrors) { + var buf = fs.readFileSync(path, 'utf-8'); + // remove Byte Order Mark + buf = buf.replace(/^\uFEFF/, ''); + + jshint.JSHINT(buf); + + var nErrors = jshint.JSHINT.errors.length; + + if (nErrors) { // ruff output of errors (for now) - console.log(_jshint.JSHINT.errors); - console.log(' Found %j lint errors on %s, do you want to continue?', nErrors, path); - - _cli.choose(['no', 'yes'], function(i){ - if (i) { - process.stdin.destroy(); - if(callback) callback(); - } else { - process.exit(0); - } - }); - } else if (callback) { - callback(); - } + console.log(jshint.JSHINT.errors); + console.log(' Found %j lint errors on %s, do you want to continue?', nErrors, path); + + cli.choose(['no', 'yes'], function(i){ + if (i) { + process.stdin.destroy(); + if(callback) callback(); + } else { + process.exit(0); + } + }); + } else if (callback) { + callback(); + } } - -// will generate a CSV if package.json contains multiple licenses -_handlebars.registerHelper('license', function(items){ - items = items.map(function(val){ - return val.type; - }); - return items.join(', '); -}); \ No newline at end of file +function libFiles(){ + var src = []; + var files = fs.readdirSync( "lib/" ); + // folter only javascript files + for( var i in files ){ + var file = files[i]; + // exclude certain files and main.js + if( file.substr(0, 1) == "." || file.substr(-3) !== ".js" || file == "main.js" ) continue; + src.push( "lib/"+ file ); + } + return src; +} diff --git a/build/jquery.three-min.js b/build/jquery.three-min.js index 52fbd92..13e8df7 100644 --- a/build/jquery.three-min.js +++ b/build/jquery.three-min.js @@ -1 +1,14 @@ -window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}(),function(e){"use strict";var t=t||!1,r=r||!1;t&&"function"==typeof t&&t.amd?t(["jquery"],e):e(r)}(function(){var e,t={self:function(){return this}},r={watch:!1,deps:{THREE:"https://raw.github.com/mrdoob/three.js/master/build/three.min.js"}};Three=function(e,t,a){var i=this;this.container=e,this.options=$.extend(!0,r,t),this.objects={},this.scenes={},this.cameras={},this.materials={},this.last=!1,this.parent=!1,this.dependencies(function(){i.init(),a instanceof Function&&a(i)})},Three.prototype={init:function(){var e=this;this.active={scene:!1,camera:!1,skybox:!1},this.properties=this.setProperties(),this.renderer=new THREE.WebGLRenderer,this.renderer.setSize(this.properties.width,this.properties.height),this.renderer.autoClear=!1,$(this.container).find(".fallback").remove();var t=$(this.container).html();$(this.container).html(""),this.parent=$(this.container).find("shadow-root"),this.html(t),$(this.renderer.domElement).appendTo(this.container),window.addEventListener("resize",function(){e.resize()},!1),this.options.watch&&this.watch(this.container),this.tick()},destroy:function(){return this.each(function(){var e=$(this);e.data("three"),e.removeData("three")})},self:function(e,t){var r=[];return this.each(function(){var a=$(this),i=a.data("three");i||(i=new Three(this,e,t),$(this).data("three",i)),r.push(i)}),1==r.length?r[0]:$(r)},tick:function(){var e=this;this.render(),requestAnimFrame(function(){e.tick()})},render:function(){$(this.container).trigger({type:"update",target:this}),this.active.scene&&this.active.camera&&(this.active.skybox&&(this.active.skybox.camera.rotation.copy(this.active.camera.rotation),this.renderer.render(this.active.skybox.scene,this.active.skybox.camera)),this.renderer.render(this.active.scene,this.active.camera))},show:function(){},hide:function(){},update:function(){},detect:function(){return{canvas:!!window.CanvasRenderingContext2D,webgl:function(){try{return!!window.WebGLRenderingContext&&!!document.createElement("canvas").getContext("experimental-webgl")}catch(e){return!1}}(),workers:!!window.Worker,fileapi:window.File&&window.FileReader&&window.FileList&&window.Blob,all:function(){return this.webgl&&this.canvas&&this.workers&&this.fileapi}}},resize:function(){this.properties=this.setProperties();for(var e in this.cameras)this.cameras[e].aspect=this.properties.aspect,this.cameras[e].updateProjectionMatrix(),this.active.skybox.aspect=this.properties.aspect,this.active.skybox.updateProjectionMatrix();this.renderer.setSize(this.properties.width,this.properties.height)},dependencies:function(e){var t=$.map(this.options.deps,function(e,t){return window[t]||window.THREE&&window.THREE[t]?void 0:e});t.length?this.loadScripts(t,e):e()},loadScripts:function(e,t){var r=this;$.when($.getScript(e.shift())).done(function(){e.length>0?r.loadScripts(e,t):t()})}},$.fn.three=function(e,t){return e||(e=!1),t||(t=function(e){return e}),Three.prototype.self.apply(this,arguments,e,t)},Three.prototype.getAttributes=function(e){var t={};return $(e).each(function(){var e=this.attributes;for(var r in e)if(e[r].name&&0===e[r].name.search("data-")){var a=e[r].name.replace("data-",""),i=e[r].value;t[a]=parseInt(i,10)?parseInt(i,10):i}else if(e[r].name&&0===e[r].name.search("class")){var n=e[r].value.split(" ");t["class"]=n}else e[r].name&&0===e[r].name.search("src")?t.src=e[r].value:e[r].name&&0===e[r].name.search("style")&&(t.style=e[r].value)}),t},Three.prototype.addClass=function(e){var t=this.last,r=$(this.container).find("[data-id='"+t.id+"']");r.addClass(e);var a=this.css(r);return this.fn.css.set.call(t,a),this},e=function(e){var t=document.styleSheets,r={};for(var i in t){var n=t[i].rules||t[i].cssRules;for(var s in n)n[s].selectorText&&n[s].selectorText.search(":hover")>-1||e.is(n[s].selectorText)&&(r=$.extend(r,a(n[s].style),a(e.attr("style"))))}return r},t.css={set:function(e,t){if(e)for(var r in t){var a=r.replace("-webkit-","").replace("-moz-","");switch(a){case"width":e.scale.x=parseInt(t[r],10);break;case"height":e.scale.y=parseInt(t[r],10);break;case"top":e.position.y=parseInt(t[r],10);break;case"left":e.position.x=parseInt(t[r],10);break;case"color":var i=this.colorToHex(t[r]);e.material.color.setHex(i);break;case"transform":var n;t[r].search("translate3d")>-1&&(n=this.fn.css.translate.call(this,t[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.position.set(n.x,n.y,n.z):e.position.set(n.x,n.y,n.z)),t[r].search("rotate3d")>-1&&(n=this.fn.css.rotate.call(this,t[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.rotation.set(n.x,n.y,n.z):e.rotation.set(n.x,n.y,n.z)),t[r].search("scale3d")>-1&&(n=this.fn.css.scale.call(this,t[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.scale.set(n.x,n.y,n.z):e.scale.set(n.x,n.y,n.z));break;case"animation-duration":console.log(a,t[r]);break;case"animation-timing":console.log(a,t[r]);break;case"animation-delay":console.log(a,t[r]);break;case"animation-iteration-count":console.log(a,t[r]);break;case"animation-direction":console.log(a,t[r]);break;case"animation-fill-mode":console.log(a,t[r]);break;case"animation-name":console.log(a,t[r]);break;case"display":break;case"background-image":e instanceof THREE.Scene&&this.fn.css.skybox.call(this,t[r]),"terrain"==e.type?this.fn.css.terrain.call(this,t[r]):e instanceof THREE.Mesh&&this.fn.css.texture.call(this,e,t[r])}}},rotate:function(e){var t={};if(e.search("rotate3d")>-1){var r=e.match(/rotate3d\(([\s\S]*?)\)/gi);r=r[0].replace(/rotate3d\(|deg|\)| /gi,"").split(","),t={x:parseInt(r[0],10)?parseInt(r[3],10)*Math.PI/180:0,y:parseInt(r[1],10)?parseInt(r[3],10)*Math.PI/180:0,z:parseInt(r[2],10)?parseInt(r[3],10)*Math.PI/180:0}}return t},translate:function(e){var t={};if(e.search("translate3d")>-1){var r=e.match(/translate3d\(([\s\S]*?)\)/gi);r=r[0].replace(/translate3d\(|px|\)| /gi,"").split(","),t={x:parseInt(r[0],10)||0,y:parseInt(r[1],10)||0,z:parseInt(r[2],10)||0}}return t},scale:function(e){var t={};if(e.search("scale3d")>-1){var r=e.match(/scale3d\(([\s\S]*?)\)/gi);r=r[0].replace(/scale3d\(|\)| /gi,"").split(","),t={x:parseInt(r[0],10)||0,y:parseInt(r[1],10)||0,z:parseInt(r[2],10)||0}}return t},texture:function(e,t){var r=t.replace(/\s|url\(|\)/g,""),a=this.webglMaterial({map:r});e.material=a},terrain:function(e){var t=this.last,r=e.replace(/\s|url\(|\)/g,"").split(",");if(r instanceof Array)for(var a in r){if(r[a].search("heightmap")>-1){var i=THREE.ImageUtils.loadTexture(r[a]);t.material.uniforms.tDisplacement.value=i,t.material.uniforms.uDisplacementScale.value=375;var n=i;n.wrapS=n.wrapT=THREE.RepeatWrapping,t.material.uniforms.tDiffuse2.value=n,t.material.uniforms.enableDiffuse2.value=!0}if(r[a].search("diffuse")>-1){var s=THREE.ImageUtils.loadTexture(r[a]);s.wrapS=s.wrapT=THREE.RepeatWrapping,t.material.uniforms.tDiffuse1.value=s,t.material.uniforms.enableDiffuse1.value=!0}if(r[a].search("specular")>-1){var o=THREE.ImageUtils.loadTexture(r[a]);o.wrapS=o.wrapT=THREE.RepeatWrapping,t.material.uniforms.tSpecular.value=o,t.material.uniforms.enableSpecular.value=!0}}},skybox:function(e){var t=e.replace(/\s|url\(|\)/g,"").split(",");t instanceof Array&&this.addSkybox(t)}};var a=function(e){var t={};if(!e)return t;if(e instanceof CSSStyleDeclaration)for(var r in e)e[r].toLowerCase&&(t[e[r].toLowerCase()]=e[e[r]]);else if("string"==typeof e){e=e.split("; ");for(var a in e){var i=e[a].split(": ");t[i[0].toLowerCase()]=i[1]}}return t};Three.prototype.animate=function(){},Three.prototype.watch=function(e){$(e).bind("DOMSubtreeModified",this.eventSubtree),e.onpropertychange?$(e).bind("propertychange",this.eventAttribute):$(e).bind("DOMAttrModified",this.eventAttribute)},Three.prototype.eventSubtree=function(e){e.target.innerHTML.length>0&&console.log(e.target.innerHTML)},Three.prototype.eventAttribute=function(e){console.log("attribute",e.target)},Three.prototype.add=function(e){var t,r={camera:"cameras",scene:"scenes",mesh:"objects",plane:"objects",cube:"objects",sphere:"objects",cylinder:"objects",material:"materials"};if(e===void 0||e.type===void 0)return this;var a=this.webgl(e);if(!a||a===void 0)return this;this.last=a;var i=r[e.type]||!1;"objects"==i?(t=new THREE.Object3D,t.add(a)):t=a,this.active[e.type]=t,i&&(this[i][t.id]=t),"scene"==e.type?this.active.scene=t:this.active.scene.add(t),e["data-id"]=t.id||!1;var n=this.createHTML(e),s=this.css(n);return this.fn.css.set.call(this,a,s),this},Three.prototype.addScene=function(e){var t=e||{};return t.type="scene",this.add(t),this},Three.prototype.addCamera=function(e){var t=e||{};return t.type="camera",this.add(t),this},Three.prototype.addMesh=function(e){var t=e||{};return t.type="mesh",this.add(t),this},Three.prototype.addPlane=function(e){var t=e||{};return t.type="plane",this.add(t),this},Three.prototype.addSphere=function(e){var t=e||{};return t.type="sphere",this.add(t),this},Three.prototype.addCube=function(e){var t=e||{};return t.type="cube",this.add(t),this},Three.prototype.addCylinder=function(e){var t=e||{};return t.type="cylinder",this.add(t),this},Three.prototype.addAsset=function(e){var t=e||{};return t.type="asset",this.add(t),this},Three.prototype.addSkybox=function(e){var t=new THREE.PerspectiveCamera(50,$(this.container).width()/$(this.container).height(),1,100),r=new THREE.Scene,a=THREE.ImageUtils.loadTextureCube(e);a.format=THREE.RGBFormat;var i=THREE.ShaderLib.cube;i.uniforms.tCube.value=a;var n=new THREE.ShaderMaterial({fragmentShader:i.fragmentShader,vertexShader:i.vertexShader,uniforms:i.uniforms,depthWrite:!1,side:THREE.BackSide});mesh=new THREE.Mesh(new THREE.CubeGeometry(100,100,100),n),r.add(mesh),this.active.skybox={scene:r,camera:t}},Three.prototype.addTerrain=function(e){var t=e||{};return t.type="terrain",this.add(t),this},Three.prototype.html=function(e){var t=this;$(e).filter("*").each(function(e,r){var a=r===void 0?!1:$(r);if(a){var i={};i.type=r.nodeName.toLowerCase(),i.id=a.attr("id");var n=t.getAttributes(r);i=$.extend(i,n),t.add(i),t.html(a.html())}})},Three.prototype.createHTML=function(e){var t=$("<"+e.type+">");if(e.id&&t.attr("id",e.id),e["data-id"]&&t.attr("data-id",e["data-id"]),e["class"]&&e["class"].length){var r=e["class"].join(" ");t.attr("class",r)}return e.style&&t.attr("style",e.style),t.appendTo(this.parent),("scene"==e.type||"asset"==e.type||"player"==e.type)&&(this.parent=t),t},Three.prototype.append=function(e){this.html(e)},Three.prototype.find=function(e){var t=$(this.container).find("shadow-root "+e).attr("data-id"),r=this.objects[t]||this.cameras[t]||this.scenes[t];return r},Three.prototype.webgl=function(e){var t;switch(e.type){case"scene":t=this.webglScene(e);break;case"camera":t=this.webglCamera(e);break;case"mesh":t=this.webglMesh(e);break;case"material":t=this.webglMaterial(e);break;case"light":t=this.webglLight(e);break;case"plane":t=this.webglPlane(e);break;case"sphere":t=this.webglSphere(e);break;case"cube":t=this.webglCube(e);break;case"cylinder":t=this.webglCylinder(e);break;case"terrain":t=this.webglTerrain(e);break;default:t=this.fn.webgl[e.type]!==void 0?this.fn.webgl[e.type].apply(this,[e]):!1}return t},t.webgl={},Three.prototype.webglScene=function(e){var t={id:!1};$.extend(t,e);var r=new THREE.Scene;return this.scenes[r.id]=r,r},Three.prototype.webglCamera=function(e){var t,r={fov:50,aspect:this.properties.aspect,near:1,far:1e3,scene:this.active.scene},a=$.extend(r,e);return a.orthographic||(t=new THREE.PerspectiveCamera(a.fov,a.aspect,a.near,a.far)),t},Three.prototype.webglMesh=function(e){var t,r={id:!1,wireframe:!1,scene:this.active.scene};return $.extend(r,e),t},Three.prototype.webglMaterial=function(e){var t,r,a={id:!1,color:0,wireframe:!1,map:!1,scene:this.active.scene},i=$.extend(a,e),n=window.Shaders||{};if(i.id&&n[i.id]){r={};var s=Shaders[i.id];s.uniforms&&(r.uniforms=THREE.UniformsUtils.clone(s.uniforms)),s.vertexShader&&(r.vertexShader=s.vertexShader),s.fragmentShader&&(r.fragmentShader=s.fragmentShader),i.map&&s.uniforms&&(r.uniforms.texture.texture=THREE.ImageUtils.loadTexture(i.map)),t=new THREE.ShaderMaterial(r)}else r={},i.map&&(r.map=THREE.ImageUtils.loadTexture(i.map)),i.color&&!i.map&&(r.color=i.color),i.wireframe&&(r.wireframe=i.wireframe),t=new THREE.MeshBasicMaterial(r);return t},Three.prototype.webglTexture=function(e){var t=new THREE.Texture,r=new THREE.ImageLoader;return r.addEventListener("load",function(e){t.image=e.content,t.needsUpdate=!0}),r.load(e),t},Three.prototype.webglLight=function(){},Three.prototype.webglPlane=function(e){var t={width:1,height:1,color:0,wireframe:!1,scene:this.active.scene},r=$.extend(t,e),a=new THREE.PlaneGeometry(r.width,r.height);a.dynamic=!0;var i=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),n=new THREE.Mesh(a,i);return r.id&&(n.name=r.id),n},Three.prototype.webglSphere=function(e){var t={id:!1,radius:1,segments:16,rings:16,color:0,wireframe:!1,map:!1,scene:this.active.scene},r=$.extend(t,e),a=new THREE.SphereGeometry(r.radius,r.segments,r.rings);a.dynamic=!0;var i=this.webglMaterial(r),n=new THREE.Mesh(a,i);return n.matrixAutoUpdate=!1,r.id&&(n.name=r.id),n},Three.prototype.webglCube=function(e){var t={id:!1,width:1,height:1,depth:1,color:0,wireframe:!1,scene:this.active.scene},r=$.extend(t,e),a=new THREE.CubeGeometry(r.width,r.height,r.depth);a.dynamic=!0;var i=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),n=new THREE.Mesh(a,i);return r.id&&(n.name=r.id),n},Three.prototype.webglCylinder=function(e){var t={id:!1,radiusTop:100,radiusBottom:100,segmentsRadius:400,segmentsHeight:50,openEnded:!1,color:0,wireframe:!1,scene:this.active.scene},r=$.extend(t,e),a=new THREE.CylinderGeometry(r.radiusTop,r.radiusBottom,r.segmentsRadius,r.segmentsHeight,r.openEnded,!1);a.dynamic=!0;var i=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),n=new THREE.Mesh(a,i);return r.id&&(n.name=r.id),n},Three.prototype.webglTerrain=function(){var e;this.active.scene.add(new THREE.AmbientLight(1118481)),directionalLight=new THREE.DirectionalLight(16777215,1.15),directionalLight.position.set(500,2e3,0),this.active.scene.add(directionalLight);var t=new THREE.PlaneGeometry(6e3,6e3,256,256);t.computeFaceNormals(),t.computeVertexNormals(),t.computeTangents();var r=THREE.ShaderTerrain.terrain;uniformsTerrain=THREE.UniformsUtils.clone(r.uniforms),uniformsTerrain.uDiffuseColor.value.setHex(16777215),uniformsTerrain.uSpecularColor.value.setHex(16777215),uniformsTerrain.uAmbientColor.value.setHex(1118481),uniformsTerrain.uRepeatOverlay.value.set(6,6);var a=new THREE.ShaderMaterial({uniforms:uniformsTerrain,vertexShader:r.vertexShader,fragmentShader:r.fragmentShader,lights:!0,fog:!1});return e=new THREE.Mesh(t,a),e.type="terrain",this.active.scene.add(e),e},Three.prototype.colorToHex=function(e){if("#"===e.substr(0,1))return e.replace("#","0x");var t=/(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(e),r=parseInt(t[2],10).toString(16),a=parseInt(t[3],10).toString(16),i=parseInt(t[4],10).toString(16);return 1==r.length&&(r="0"+r),1==a.length&&(a="0"+a),1==i.length&&(i="0"+i),"0x"+r+a+i},Three.prototype.setProperties=function(){return{width:$(this.container).width(),height:$(this.container).height(),aspect:$(this.container).width()/$(this.container).height()}},Three.prototype.css=e,Three.prototype.fn=t}); \ No newline at end of file +/** + * @name jquery.three + * jQuery Three() - jQuery extension with 3D methods (using Three.js) + * Version: 0.9.8 (Sun, 11 Dec 2016 13:05:25 GMT) + * + * @author makesites + * Created by: Makis Tracend (@tracend) + * + * Homepage: http://github.com/makesites/jquery-three + * @license MIT License + */ +window.requestAnimFrame=function(e){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}(),function(e,t){var a=e.$||e.jQuery||e.ender;"function"==typeof define&&define.amd?define(["jquery"],t):t(a)}(this,function(e){function t(e,t){if(e=e||{},e.material)if(e.material.materials)for(var a in e.material.materials)e.material.materials[a].color.setHex(t);else e.material.color.setHex(t)}function a(){for(var e in this._animations){var t=this._animations[e],a=t.keyframes;t.start=t.start||u.now(),t.end=t.end||t.start+t.duration,t.offset=t.offset||r(this),t.count=t.count||0;var i=u.now(),n=(i-t.start)/t.duration*100,s=!1,o=!1;for(var c in a)n>=c&&(s=a[c]),c>n&&!o&&(o=a[c]);s||(s=a[0]),o||(o=a[100]);var h={x:"undefined"!=typeof s.rotation.x&&"undefined"!=typeof o.rotation.x?(o.rotation.x-s.rotation.x)*(n/100):0,y:"undefined"!=typeof s.rotation.y&&"undefined"!=typeof o.rotation.y?(o.rotation.y-s.rotation.y)*(n/100):0,z:"undefined"!=typeof s.rotation.z&&"undefined"!=typeof o.rotation.z?(o.rotation.z-s.rotation.z)*(n/100):0};if(this.rotation.set(t.offset.rotation.x+h.x,t.offset.rotation.y+h.y,t.offset.rotation.z+h.z),this instanceof THREE.Sprite){var l={x:this.material.map.offset.x,y:this.material.map.offset.y},d=t.easing,p=100/d,f=parseInt(n,10)%p===0?parseInt(n,10)/100:0;f&&(f-=1/d,"undefined"!=typeof t.keyframes[0]["background-position"].x&&(l.x=(d-1)/d-f),"undefined"!=typeof t.keyframes[0]["background-position"].y&&(l.y=(d-1)/d-f),this.material.map.offset.set(l.x,l.y))}n>=100&&(delete t.start,delete t.end,delete t.offset,t.count++),t.count==t.repeat?delete this._animations[e]:this._animations[e]=t}}function r(e){return{position:{x:e.position.x,y:e.position.y,z:e.position.z},rotation:{x:e.rotation.x,y:e.rotation.y,z:e.rotation.z},scale:{x:e.scale.x,y:e.scale.y,z:e.scale.z}}}function i(e){for(var t=document.styleSheets,a=0;a"),this.parent=e(this.el).find("shadow-root"),this.target=this.parent,this.html(a),e(this.renderer.domElement).appendTo(this.el),window.addEventListener("resize",function(){t.resize()},!1),this.options.watch&&this.watch(this.parent),this.tick()},destroy:function(){return this.each(function(){var t=e(this);t.data("three");t.removeData("three")})},self:function(t,a){var r=[];return this.each(function(){var i=e(this),n=i.data("three");n||(n=new Three(this,t,a),e(this).data("three",n)),r.push(n)}),1==r.length?r[0]:e(r)},tick:function(){var e=this;this.options.paused||this.render();var t=new Date;this.frame.date.getSeconds()===t.getSeconds()?this.frame.current++:(this.frame.rate=this.frame.current,this.frame.current=1,this.frame.date=t),requestAnimFrame(function(){e.tick()})},render:function(){if(this.active.scene&&this.active.camera){if(this.active.skybox){var t=this.active.camera.far,a=this.active.skybox.scale;a.x!==t&&(a.x=a.y=a.z=t);var r=this.active.camera.position;this.active.skybox.position.set(r.x,r.y,r.z)}this.renderer.render(this.active.scene,this.active.camera)}this.fn.animate.update(),e(this.el).trigger({type:"update",target:this})},show:function(){},hide:function(){},update:function(e){},detect:function(){return{canvas:!!window.CanvasRenderingContext2D,webgl:function(){try{return!!window.WebGLRenderingContext&&!!document.createElement("canvas").getContext("experimental-webgl")}catch(e){return!1}}(),workers:!!window.Worker,fileapi:window.File&&window.FileReader&&window.FileList&&window.Blob,all:function(){return this.webgl&&this.canvas&&this.workers&&this.fileapi}}},resize:function(){this.properties=this.setProperties();for(var e in this.cameras)this.cameras[e].aspect=this.properties.aspect,this.cameras[e].updateProjectionMatrix();this.renderer.setSize(this.properties.width,this.properties.height)},dependencies:function(t){var a=e.map(this.options.deps,function(e,t){return window[t]||window.THREE&&window.THREE[t]?void 0:e});a.length?this.loadScripts(a,t):t()},loadScripts:function(t,a){var r=this;e.when(e.getScript(t.shift())).done(function(){t.length>0?r.loadScripts(t,a):a()})},setEl:function(t){var a=e(this).attr("id");return"undefined"!=typeof a&&a!==!1||e(t).addClass("3d-"+u.unid()),t}},e.fn.three=function(e,t){e||(e=!1),t||(t=function(e){return e});return Three.prototype.self.apply(this,arguments,e,t)},Three.prototype.getAttributes=function(t){var a={};return e(t).each(function(){var e=this.attributes;for(var t in e)if(e[t].name&&0===e[t].name.search("data-")){var r=e[t].name.replace("data-","");r=u.camelCase(r);var i=e[t].value;a[r]=parseInt(i,10)||"0"===i?parseInt(i,10):i,"false"!==a[r]&&"true"!==a[r]||(a[r]=JSON.parse(a[r]))}else if(e[t].name&&0===e[t].name.search("class")){var n=e[t].value.split(" ");a["class"]=n}else e[t].name&&0===e[t].name.search("src")?a.src=e[t].value:e[t].name&&0===e[t].name.search("style")&&(a.style=e[t].value)}),a},Three.prototype.addClass=function(t){var a=this.last,r=e(this.el).find("[data-id='"+a.id+"']");r.addClass(t);var i=this.fn.css.styles.call(this,r);return this.fn.css.set.call(this,a,i),this},n=function(e){return this.fn.css.set.call(this,this.last,e),this},c.css={styles:function(t){var a=document.styleSheets,r={};for(var i in a){var n=a[i],s=n.href&&0!==n.href.indexOf("/")&&0!==n.href.indexOf(o);if(!s&&null!==n.cssRules){var c=n.cssRules||n.rules;for(var h in c)if(!(c[h].selectorText&&c[h].selectorText.search(":hover")>-1||c[h].selectorText&&c[h].selectorText.search("::before")>-1||c[h].selectorText&&c[h].selectorText.search("::after")>-1))try{t.is(c[h].selectorText)&&(r=e.extend(r,l(c[h].style)))}catch(d){console.log(d)}}}return r=e.extend(r,l(t.attr("style")))},set:function(e,a){if(e&&e.id)for(var r in a){var i=r.replace("-webkit-","").replace("-moz-","");e._style=e._style||{},e._shaders=e._shaders||{};var n=!e._style[i]||e._style[i]!=a[r];if(e._style[i]=a[r],n)switch(i){case"width":e.scale.x=parseInt(a[r],10);break;case"height":e.scale.y=parseInt(a[r],10);break;case"top":e.position.y=parseInt(a[r],10);break;case"left":e.position.x=parseInt(a[r],10);break;case"color":var s=this.colorToHex(a[r]);e instanceof THREE.Scene?this.webglLight({color:s}):t(e,s);break;case"transform":var o;a[r].search("translate3d")>-1&&(o=this.fn.css.translate.call(this,a[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.position.set(o.x,o.y,o.z):e.position.set(o.x,o.y,o.z)),a[r].search("rotate3d")>-1&&(o=this.fn.css.rotate.call(this,a[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.rotation.set(o.x,o.y,o.z):e.rotation.set(o.x,o.y,o.z)),a[r].search("scale3d")>-1&&(o=this.fn.css.scale.call(this,a[r]),e instanceof THREE.Mesh&&"terrain"!=e.type?e.parent.scale.set(o.x,o.y,o.z):e.scale.set(o.x,o.y,o.z));break;case"animation-duration":this.fn.css.animation.duration=1e3*parseInt(a[r],10);break;case"animation-timing":this.fn.css.animation.easing=a[r];break;case"animation-delay":this.fn.css.animation.delay=a[r];break;case"animation-iteration-count":this.fn.css.animation.repeat=a[r];break;case"animation-direction":this.fn.css.animation.direction=a[r];break;case"animation-fill-mode":this.fn.css.animation.fill=a[r];break;case"animation-name":this.fn.css.animation.name=a[r],this.animate(this.fn.css.animation,e),this.fn.css.animation={};break;case"animation-timing-function":var c=a[r].match(/steps\((\d)/);this.fn.css.animation.easing=c?parseInt(c[1],10):a[r];break;case"animation-play-state":this.fn.css.animation.state=a[r];break;case"display":break;case"background-image":if(e instanceof THREE.Scene)this.fn.css.skybox.call(this,a[r]);else if("terrain"==e.type)this.fn.css.terrain.call(this,a[r]);else if(e instanceof THREE.Mesh)this.fn.css.texture.call(this,e,a[r]);else if(e instanceof THREE.Object3D&&e.children.length)try{var h=e.children[0];this.fn.css.texture.call(this,h,a[r])}catch(l){console.log(l)}else if(e instanceof THREE.Sprite){var d=a[r].replace(/\s|url\(|"|'|\)/g,"");e.material.map=u.textureLoader(d)}break;case"background-size":e instanceof THREE.Sprite&&this.fn.css.sprite.call(this,e,a[r]);break;case"background-position-x":e instanceof THREE.Sprite&&this.fn.css.sprite.call(this,e);break;case"background-position-y":e instanceof THREE.Sprite&&this.fn.css.sprite.call(this,e);break;case"filter":var p,f;e instanceof THREE.Mesh&&e.parent instanceof THREE.Object3D?(p=e.parent,f=e.parent.$el):(p=e,f=e.$el);var m=a[r].replace(/url\(|"|'|\)/g,"").split("|");if(!m.length)break;p._shaders=p._shaders||{};for(var g in m){var v=m[g].substring(m[g].lastIndexOf("/")+1);p._shaders[v]=u.getFile(m[g])}p.getShader=function(e){return this._shaders[e]||null},f.trigger("css-filter")}}},animation:{},rotate:function(e){var t,a={};return e.search("rotate3d")>-1?(t=e.match(/rotate3d\(([\s\S]*?)\)/gi),t=t[0].replace(/rotate3d\(|deg|\)| /gi,"").split(","),a={x:parseFloat(t[0],10)*parseFloat(t[3],10)*(Math.PI/180),y:parseFloat(t[1],10)*parseFloat(t[3],10)*(Math.PI/180),z:parseFloat(t[2],10)*parseFloat(t[3],10)*(Math.PI/180)}):e.search("rotateX")>-1?(t=e.match(/rotateX\(([\s\S]*?)\)/gi),t=t[0].replace(/rotateX\(|deg|\)| /gi,"").rot={x:parseFloat(t,10)*(Math.PI/180)}):e.search("rotateY")>-1?(t=e.match(/rotateY\(([\s\S]*?)\)/gi),t=t[0].replace(/rotateY\(|deg|\)| /gi,""),a={y:parseFloat(t,10)*(Math.PI/180)}):e.search("rotateZ")>-1?(t=e.match(/rotateZ\(([\s\S]*?)\)/gi),t=t[0].replace(/rotateZ\(|deg|\)| /gi,""),a={z:parseFloat(t,10)*(Math.PI/180)}):e.search("rotate")>-1&&(t=e.match(/rotate\(([\s\S]*?)\)/gi),t=t[0].replace(/rotate\(|deg|\)| /gi,""),a={z:parseFloat(t,10)*(Math.PI/180)}),a},translate:function(e){var t={};if(e.search("translate3d")>-1){var a=e.match(/translate3d\(([\s\S]*?)\)/gi);a=a[0].replace(/translate3d\(|px|\)| /gi,"").split(","),t={x:parseFloat(a[0],10)||0,y:parseFloat(a[1],10)||0,z:parseFloat(a[2],10)||0}}return t},scale:function(e){var t={};if(e.search("scale3d")>-1){var a=e.match(/scale3d\(([\s\S]*?)\)/gi);a=a[0].replace(/scale3d\(|\)| /gi,"").split(","),t={x:parseFloat(a[0],10)||0,y:parseFloat(a[1],10)||0,z:parseFloat(a[2],10)||0}}return t},texture:function(e,t){var a,r=t.replace(/\s|url\(|"|'|\)/g,"").split(",");if(r.length>1){var i={},n={},s=(new THREE.CubeTextureLoader).load(r);if(s.format=THREE.RGBFormat,i.tCube={type:"t",value:s},e._shaders)for(var o in e._shaders){var c=e._shaders[o];o.indexOf(".fs")>-1&&(n.fragmentShader=c),o.indexOf(".vs")>-1&&(n.vertexShader=c)}n.uniforms=i,n.needsUpdate=!0,a=new THREE.ShaderMaterial(n)}else a=this.webglMaterial({map:r[0]});e.material=a},terrain:function(e){var t=this.last,a=e.match(/url\(\s*[\'"]?(([^\\\\\'" \(\)]*(\\\\.)?)+)[\'"]?\s*\)/gim);if(a instanceof Array){var r,i,n;for(var s in a)a[s]=a[s].replace(/\s|url\(|"|'|\)/g,""),a[s].search("heightmap")>-1&&(r=t.updateTexture("heightmap",a[s])),a[s].search("diffuse")>-1&&(i=t.updateTexture("diffuse",a[s])),a[s].search("specular")>-1&&(n=t.updateTexture("specular",a[s]));!r&&a[0]&&t.updateTexture("heightmap",a[0]),!i&&a[1]&&t.updateTexture("diffuse",a[1]),!n&&a[2]&&t.updateTexture("specular",a[2])}else t.updateTexture("heightmap",a),t.updateTexture("diffuse",a)},skybox:function(e){var t=e.replace(/\s|url\(|"|'|\)/g,"").split(",");t instanceof Array&&this.addSkybox(t)},sprite:function(e,t){var a=setInterval(function(){if(e.material.map.image&&e.material.map.image.width){t=t||e._style["background-size"]||"0 0";var r=t.split(" "),i=parseFloat(r[0],10),n=parseFloat(r[1],10),s=parseFloat(e._style["background-position-x"]||0),o=parseFloat(e._style["background-position-y"]||0);if(i&&n){var c=e.material.map.image.width,h=e.material.map.image.height;e.material.map.offset.set((c-i-s)/c,(h-n-o)/h),e.material.map.repeat.set(i/c,n/h),clearInterval(a)}}},200)}};var l=function(e){var t={};if(!e)return t;if(e instanceof CSSStyleDeclaration)for(var a in e)e[a].toLowerCase&&(t[e[a].toLowerCase()]=e[e[a]]);else if("string"==typeof e){e=e.split("; ");for(var r in e){var i=e[r].split(": ");t[i[0].toLowerCase()]=i[1]}}return t};Three.prototype.animate=function(e,t){if(e=e||{},t=t||this.last||!1,t instanceof THREE.Mesh&&t.parent instanceof THREE.Object3D&&(t=t.parent),t&&e.name&&(t._animations=t._animations||{},t._update=t._update||a.bind(t),e.keyframes=this.fn.animate.getKeyframes.call(this,e.name),e.keyframes)){t._animations[e.name]=e;var r="undefined"!=typeof this.fn.animate.queue[t.uuid];r||(this.fn.animate.queue[t.uuid]=t._update)}},c.animate={queue:{},getKeyframes:function(e){var t={},a=i(e);if(a){for(var r in a.cssRules){var n=a.cssRules[r],s={};if(n.keyText){var o,c=parseInt(n.keyText,10);s.rotation=this.fn.css.rotate(n.cssText),s.translation=this.fn.css.translate(n.cssText),s.scale=this.fn.css.scale(n.cssText),n.cssText.search("background-position-x")>-1&&(s["background-position"]=s["background-position"]||{},o=n.cssText.match(/:[\d|\s|\w]+\;/),o&&(s["background-position"].x=parseFloat(o[0].substr(1),10))),n.cssText.search("background-position-y")>-1&&(s["background-position"]=s["background-position"]||{},o=n.cssText.match(/:[\d|\s|\w]+\;/),o&&(s["background-position"].y=parseFloat(o[0].substr(1),10))),t[c]=s}}return t}},update:function(e){for(var t in this.queue)this.queue[t]()}},Three.prototype.fx=function(){},Three.prototype.watch=function(t){function a(e){var t=e.target,a=e.attributeName,i=e.target.getAttribute(a);e.oldValue;if("style"==a){var n=r.objects[t.getAttribute("data-id")]||r.active.terrain,s=n.children[0]||n,o=l(i);r.last=s,r.fn.css.set.call(r,s,o)}}var r=this,i=e(t).selector||"shadow-root",n=(e(this.el).toSelector()+" "+i,document.getElementById("main").querySelector("shadow-root")),s=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,o={childList:!0,attributes:!0,subtree:!0,attributeOldValue:!0,attributeFilter:["class","style"]},c=new s(function(t){e.each(t,function(e,t){var a=t;"childList"===t.type?t.addedNodes.length>0?r.eventSubtree(a):t.removedNodes.length>0:"attributes"===t.type&&"class"===t.attributeName&&r.eventAttribute(a)})});c.observe(n,o);var h=new s(function(e){e.forEach(a)});h.observe(n,{childList:!1,attributes:!0,subtree:!0,attributeFilter:["class","style"]})},Three.prototype.eventSubtree=function(t){var a=e(e(this.el).toSelector()+" shadow-root").get(0),r=e(t.target).get(0);if(this.parent=a==r?e(t.target):e(t.target).parent(),this.target=e(t.target),0!==t.target.innerHTML.length){var i=e(t.target).html();this.append(i,{silent:!0,target:this.target,traverse:!1,watch:!0})}},Three.prototype.eventAttribute=function(e){console.log("attribute",e.target)},Three.prototype.add=function(e,t){var a=this;return t=t||{},"undefined"==typeof e||"undefined"==typeof e.type?this:(this.webgl(e,function(r){if(!r||"undefined"==typeof r)return this;var i;a.last=r;var n=a.groups[e.type]||!1;if("objects"==n&&r instanceof THREE.Mesh?(i=new THREE.Object3D,i.add(r),i.name=r.name):i=r,a.active[e.type]=i,e["data-id"]=i.id||!1,!e.el.data("id")){var s;t.silent&&e.el?(s=e.el,s.attr("data-id",e["data-id"])):(s=a.createHTML(e),a.target=s),i.$el=s;var o=a.fn.css.styles.call(a,s);a.fn.css.set.call(a,r,o),n&&(a[n][i.id]=i),"scene"==e.type?a.active.scene=i:a.active.scene&&a.active.scene.add(i)}}),this)},Three.prototype.addScene=function(e){var t=e||{};return t.type="scene",this.add(t),this},Three.prototype.addCamera=function(e){var t=e||{};return t.type="camera",this.add(t),this},Three.prototype.addMesh=function(e){var t=e||{};return t.type="mesh",this.add(t),this},Three.prototype.addPlane=function(e){var t=e||{};return t.type="plane",this.add(t),this},Three.prototype.addSphere=function(e){var t=e||{};return t.type="sphere",this.add(t),this},Three.prototype.addCube=function(e){var t=e||{};return t.type="cube",this.add(t),this},Three.prototype.addCylinder=function(e){var t=e||{};return t.type="cylinder",this.add(t),this},Three.prototype.addAsset=function(e){var t=e||{};return t.type="asset",this.add(t),this},Three.prototype.addSkybox=function(e){var t,a;if(1==e.length)t=new THREE.SphereGeometry(1,60,40),t.applyMatrix((new THREE.Matrix4).makeScale(-1,1,1)),a=new THREE.MeshBasicMaterial({map:u.textureLoader(e[0])});else{var r;if(THREE.REVISION<70)r=THREE.ImageUtils.loadTextureCube(e);else{var i=new THREE.CubeTextureLoader;r=i.load(e)}r.format=THREE.RGBFormat;var n=THREE.ShaderLib.cube,s=THREE.UniformsUtils.clone(n.uniforms);s.tCube.value=r,a=new THREE.ShaderMaterial({fragmentShader:n.fragmentShader,vertexShader:n.vertexShader,uniforms:s,depthWrite:!1,side:THREE.BackSide}),t=new THREE.BoxGeometry(1,1,1)}var o=new THREE.Mesh(t,a);this.active.scene.add(o),this.active.skybox=o},Three.prototype.addTerrain=function(e){var t=e||{};return t.type="terrain",this.add(t),this},Three.prototype.html=function(t,a){var r=this;return a=a||{},a.target=a.target||this.target,"undefined"==typeof a.traverse&&(a.traverse=!0),e(t).filter("*").each(function(t,i){var n="undefined"==typeof i?!1:e(i);if(n&&"undefined"==typeof n.attr("data-id")){var s={};s.type=i.nodeName.toLowerCase(),s.id=n.attr("id");var o=r.getAttributes(i);s=e.extend(s,o),s.el=a.target.children(":eq("+t+")"),a.watch&&!s.el.length||(r.add(s,a),""!==n.html()&&a.traverse&&r.html(n.html(),a))}}),this},Three.prototype.createHTML=function(t){var a=e("<"+t.type+">");if(t.id&&a.attr("id",t.id),t["data-id"]&&a.attr("data-id",t["data-id"]),t["class"]&&t["class"].length){var r=t["class"].join(" ");a.attr("class",r)}return t.style&&a.attr("style",t.style),a.appendTo(this.parent),"scene"!=t.type&&"asset"!=t.type&&"player"!=t.type||(this.parent=a),a},Three.prototype.append=function(e,t){return t=t||{},this.html(e,t),this},Three.prototype.get=function(e){var t=this.objects[e]||this.cameras[e]||this.scenes[e]||this.terrains[e]||null;return t},find=function(e){var t=this.fn.find.el.call(this,e);return this.last=t,this},c.find={el:function(t){var a=e(this.el).find("shadow-root "+t).attr("data-id"),r=this.objects[a]||this.cameras[a]||this.scenes[a]||this.terrains[a]||null;return r}},c.three=function(e,t){var a=this.last;try{a[e](t)}catch(r){console.log("Method not supported:",r)}return this};var d=function(e){this.options=e;var t=e.resolution,a=e.resolution,r=new THREE.PlaneBufferGeometry(e.width,e.height,t,a);r.computeFaceNormals(),r.computeVertexNormals(),u.computeTangents(r);var i=e.shader?this.shaderMaterial():this.basicMaterial(),n=new THREE.Mesh(r,i);return n.type="terrain",n._attributes=e,e.shader?n.updateTexture=this.shaderTexture.bind(n):(n.computeElevation=this.computeElevation.bind(n),n.updateTexture=this.basicTexture.bind(n)),this.terrain=n,this};d.prototype.shaderMaterial=function(){if(!THREE.ShaderTerrain)return console.log("THREE.ShaderTerrain not loaded. Use data-shader='false' to generate a poly terrain");var e=this.options,t=THREE.ShaderTerrain.terrain,a=THREE.UniformsUtils.clone(t.uniforms);THREE.REVISION<70?(a.uDiffuseColor.value.setHex(16777215),a.uSpecularColor.value.setHex(16777215),a.uAmbientColor.value.setHex(1118481)):(a.diffuse.value.setHex(16777215),a.specular.value.setHex(16777215)),a.uRepeatOverlay.value.set(e.repeat,e.repeat);var r=new THREE.ShaderMaterial({uniforms:a,vertexShader:t.vertexShader,fragmentShader:t.fragmentShader,lights:e.lights,fog:e.fog,needsUpdate:!0});return r},d.prototype.basicMaterial=function(){var e=new THREE.MeshBasicMaterial({map:u.pixel(),overdraw:.5});return e},d.prototype.computeElevation=function(e){if(!this._attributes.shader){var t=this,a=document.createElement("canvas"),r=a.getContext("2d"),i=e.image,n=t.geometry.parameters.widthSegments+1,s=t.geometry.parameters.heightSegments+1,o=t._attributes.scale,c=-t._attributes.scale/2,h=(t.geometry.parameters.width,t.geometry.attributes.position),l=[];a.width=n,a.height=s,r.drawImage(i,0,0,i.width,i.height,0,0,n,s);var d=r.getImageData(0,0,n,s).data;for(var u in d)if(!(u%4)){var p=d[u]/255*o+c;l.push(p),h.setZ(u/4,p)}t.geometry.attributes.position.needsUpdate=!0}},d.prototype.shaderTexture=function(e,t){var a=u.textureLoader(t);if("heightmap"==e){var r=this._attributes.scale;this.material.uniforms.tDisplacement.value=a,this.material.uniforms.uDisplacementScale.value=r,this.material.uniforms.uDisplacementBias.value=-r/2}return"diffuse"==e&&(a.wrapS=a.wrapT=THREE.RepeatWrapping,this.material.uniforms.tDiffuse1.value=a,this.material.uniforms.enableDiffuse1.value=!0),"specular"==e&&(this.material.uniforms.tSpecular.value=a,this.material.uniforms.enableSpecular.value=!0),a},d.prototype.basicTexture=function(e,t){var a;if("heightmap"==e){a=u.textureLoader(t,"heightmap-loaded");var r=this,i=function(e){r.computeElevation(a),r.$el.trigger("heightmap-updated")};document.removeEventListener("heightmap-loaded",i),document.addEventListener("heightmap-loaded",i,!1)}if("diffuse"==e){a=u.textureLoader(t);var n=this._attributes.repeat;a.wrapT=THREE.RepeatWrapping,a.wrapS=THREE.RepeatWrapping,a.repeat.set(n,n),a.needsUpdate=!0,this.material.map=a}return a},Three.prototype.webgl=function(e,t){var a;switch(e.type){case"scene":a=this.webglScene(e);break;case"camera":a=this.webglCamera(e);break;case"mesh":a=this.webglMesh(e);break;case"material":a=this.webglMaterial(e);break;case"light":a=this.webglLight(e);break;case"plane":a=this.webglPlane(e);break;case"sphere":a=this.webglSphere(e);break;case"cube":a=this.webglCube(e);break;case"cylinder":a=this.webglCylinder(e);break;case"sprite":a=this.webglSprite(e);break;case"terrain":a=this.webglTerrain(e);break;default:"undefined"!=typeof this.fn.webgl[e.type]&&this.fn.webgl[e.type].apply(this,[e,t])}return t(a)},c.webgl={},Three.prototype.webglScene=function(t){var a={id:!1},r=e.extend(a,t),i=new THREE.Scene;return this.scenes[i.id]=i,i._attributes=r,i},Three.prototype.webglCamera=function(t){var a,r={fov:50,aspect:this.properties.aspect,near:1,far:1e3,scene:this.active.scene},i=e.extend(r,t);return i.orthographic||(a=new THREE.PerspectiveCamera(i.fov,i.aspect,i.near,i.far)),a._attributes=i,a},Three.prototype.webglMesh=function(t){var a,r={id:!1,wireframe:!1,scene:this.active.scene};e.extend(r,t);return a},Three.prototype.webglMaterial=function(t){var a,r,i={id:!1,color:0,wireframe:!1,map:!1,scene:this.active.scene},n=e.extend(i,t),s=window.Shaders||{};if(n.id&&s[n.id]){r={};var o=Shaders[n.id];o.uniforms&&(r.uniforms=THREE.UniformsUtils.clone(o.uniforms)),o.vertexShader&&(r.vertexShader=o.vertexShader),o.fragmentShader&&(r.fragmentShader=o.fragmentShader),n.map&&o.uniforms&&(r.uniforms.texture.texture=u.textureLoader(n.map)),a=new THREE.ShaderMaterial(r)}else r={},n.map&&(r.map=u.textureLoader(n.map)),n.color&&!n.map&&(r.color=n.color),n.wireframe&&(r.wireframe=n.wireframe),a=new THREE.MeshBasicMaterial(r);return a},Three.prototype.webglTexture=function(e){var t=new THREE.Texture,a=new THREE.ImageLoader;return a.addEventListener("load",function(e){t.image=e.content,t.needsUpdate=!0}),a.load(e),t},Three.prototype.webglLight=function(e){this.active.scene.add(new THREE.AmbientLight(parseInt(e.color,16)))},Three.prototype.webglPlane=function(t){var a={width:1,height:1,color:0,wireframe:!1,scene:this.active.scene},r=e.extend(a,t),i=r.buffer?THREE.PlaneBufferGeometry:THREE.PlaneGeometry,n=new i(r.width,r.height);n.dynamic=!0;var s=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),o=new THREE.Mesh(n,s);return r.id&&(o.name=r.id),o._attributes=r,o},Three.prototype.webglSphere=function(t){var a={id:!1,radius:1,segments:16,rings:16,color:0,wireframe:!1,map:!1,scene:this.active.scene},r=e.extend(a,t),i=new THREE.SphereGeometry(r.radius,r.segments,r.rings);i.dynamic=!0;var n=this.webglMaterial(r),s=new THREE.Mesh(i,n);return s.matrixAutoUpdate=!1,r.id&&(s.name=r.id),s._attributes=r,s},Three.prototype.webglCube=function(t){var a={id:!1,width:1,height:1,depth:1,color:0,wireframe:!1,scene:this.active.scene},r=e.extend(a,t),i=new THREE.BoxGeometry(r.width,r.height,r.depth);i.dynamic=!0;var n=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),s=new THREE.Mesh(i,n);return r.id&&(s.name=r.id),s._attributes=r,s},Three.prototype.webglCylinder=function(t){var a={id:!1,radiusTop:1,radiusBottom:1,segmentsRadius:4,segmentsHeight:16,openEnded:!1,color:0,wireframe:!1,scene:this.active.scene},r=e.extend(a,t),i=new THREE.CylinderGeometry(r.radiusTop,r.radiusBottom,r.segmentsRadius,r.segmentsHeight,r.openEnded,!1);i.dynamic=!0;var n=new THREE.MeshBasicMaterial({color:r.color,wireframe:r.wireframe}),s=new THREE.Mesh(i,n);return r.id&&(s.name=r.id),s._attributes=r,s},Three.prototype.webglSprite=function(t){t=t||{};var a={map:!1,color:16777215,fog:!1,transparent:!0,opacity:1},r=e.extend(a,t);t.map?r.map=u.textureLoader(t.map):r.map=u.pixel();var i=r.id;delete r.id,delete r["class"],delete r.el,delete r.style;var n=new THREE.SpriteMaterial(r);n.scaleByViewport=!0,n.blending=THREE.AdditiveBlending;var s=new THREE.Sprite(n);return s.name=i,s._attributes=r,s},Three.prototype.webglTerrain=function(t){t=t||{};var a={lights:!0,fog:!0,scale:256,width:6e3,height:6e3,resolution:256,shader:!0,repeat:1},r=e.extend(a,t),i=new d(r).terrain;return this.active.scene.add(i),i},Three.prototype.colorToHex=function(e){if("#"===e.substr(0,1))return e.replace("#","0x");var t=/(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(e),a=parseInt(t[2],10).toString(16),r=parseInt(t[3],10).toString(16),i=parseInt(t[4],10).toString(16);return 1==a.length&&(a="0"+a),1==r.length&&(r="0"+r),1==i.length&&(i="0"+i),"0x"+a+r+i},Three.prototype.setProperties=function(){return{width:e(this.el).width(),height:e(this.el).height(),aspect:e(this.el).width()/e(this.el).height()}};var u={camelCase:function(e){return e.replace(/-([a-z])/g,function(e){return e[1].toUpperCase()})},delay:function(e,t){t=t||0;var a=Array.prototype.slice.call(arguments,2);return setTimeout(function(){return e.apply(null,a)},t)},unid:function(){return Math.round(Math.random()*(new Date).getTime())},now:function(){return performance&&performance.now?Math.floor(performance.now()):(new Date).getTime()},pixel:function(){var e=document.createElement("img"),t=new THREE.Texture(e);return e.addEventListener("load",function(e){t.needsUpdate=!0}),e.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",t},textureLoader:function(e,t){var a=this.pixel();return THREE.REVISION<70?(e.search(";base64,")>-1&&(e=e.replace(/data:image\/(png|jpg|jpeg);base64,/,"")),a=THREE.ImageUtils.loadTexture(e)):(new THREE.TextureLoader).load(e,function(e){if(a.image=e.image,a.needsUpdate=!0,t){var r=new Event(t);document.dispatchEvent(r)}}),a},getHeightData:function(e){var t=document.createElement("canvas");t.width=128,t.height=128;var a=t.getContext("2d"),r=16384,i=new Float32Array(r);a.drawImage(e,0,0);for(var n=0;r>n;n++)i[n]=0;for(var s=a.getImageData(0,0,128,128),o=s.data,c=0,h=0,l=o.length;l>h;h+=4){var d=o[h]+o[h+1]+o[h+2];i[c++]=d/30}return i},getFile:function(t){return s[t]?s[t]:(s[t]=e.ajax({type:"GET",url:t,dataType:"string",async:!1,success:function(e){s[t]=e}}).responseText,s[t])}, +// @author mrdoob / http://mrdoob.com/ +computeTangents:function(e){function t(e,t,a){v.fromArray(s,3*e),y.fromArray(s,3*t),w.fromArray(s,3*a),E.fromArray(c,2*e),T.fromArray(c,2*t),b.fromArray(c,2*a);var r=y.x-v.x,i=w.x-v.x,n=y.y-v.y,o=w.y-v.y,h=y.z-v.z,l=w.z-v.z,p=T.x-E.x,f=b.x-E.x,m=T.y-E.y,g=b.y-E.y,H=1/(p*g-f*m);x.set((g*r-m*i)*H,(g*n-m*o)*H,(g*h-m*l)*H),R.set((p*i-f*r)*H,(p*o-f*n)*H,(p*l-f*h)*H),d[e].add(x),d[t].add(x),d[a].add(x),u[e].add(R),u[t].add(R),u[a].add(R)}function a(e){C.fromArray(o,3*e),L.copy(C),z=d[e],I.copy(z),I.sub(C.multiplyScalar(C.dot(z))).normalize(),_.crossVectors(L,z),F=_.dot(u[e]),M=0>F?-1:1,l[4*e]=I.x,l[4*e+1]=I.y,l[4*e+2]=I.z,l[4*e+3]=M}var r=e.index,i=e.attributes;if(null===r||void 0===i.position||void 0===i.normal||void 0===i.uv)return void console.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");var n=r.array,s=i.position.array,o=i.normal.array,c=i.uv.array,h=s.length/3;void 0===i.tangent&&e.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*h),4));for(var l=i.tangent.array,d=[],u=[],p=0;h>p;p++)d[p]=new THREE.Vector3,u[p]=new THREE.Vector3;var f,m,g,v=new THREE.Vector3,y=new THREE.Vector3,w=new THREE.Vector3,E=new THREE.Vector2,T=new THREE.Vector2,b=new THREE.Vector2,x=new THREE.Vector3,R=new THREE.Vector3,H=e.groups;0===H.length&&(H=[{start:0,count:n.length}]);for(var S=0;Sk;k+=3)t(n[k+0],n[k+1],n[k+2])}for(var M,z,F,I=new THREE.Vector3,_=new THREE.Vector3,C=new THREE.Vector3,L=new THREE.Vector3,B=0;Bj;j+=3)a(n[j+0]),a(n[j+1]),a(n[j+2])}}};!function(e){e.fn.toSelector=function(){var t=e(this).get(0),a=t.tagName.toLowerCase(),r=e(this).attr("id"),i=t.className.split(/\s+/),n=a;return"undefined"!=typeof r&&(n+="#"+r),"undefined"!=typeof i&&(n+="."+i.join(".")),n}}(jQuery),Three.prototype.css=n,Three.prototype.find=find,Three.prototype.fn=c,Three.prototype.lookAt=function(){return this.fn.three.call(this,"lookAt",arguments)}}); \ No newline at end of file diff --git a/build/jquery.three.js b/build/jquery.three.js index e4dd8f7..4481811 100644 --- a/build/jquery.three.js +++ b/build/jquery.three.js @@ -1,11 +1,15 @@ /** -* jQuery Three() - jQuery extension with 3D methods (using Three.js) -* Created by: Makis Tracend (@tracend) -* -* Copyright © 2013 Makesites.org -* Licensed under the MIT license -* -**/ + * @name jquery.three + * jQuery Three() - jQuery extension with 3D methods (using Three.js) + * Version: 0.9.8 (Sun, 11 Dec 2016 13:05:25 GMT) + * + * @author makesites + * Created by: Makis Tracend (@tracend) + * + * Homepage: http://github.com/makesites/jquery-three + * @license MIT License + */ + // RequestAnimationFrame shim - Source: http://paulirish.com/2011/requestanimationframe-for-smart-animating/ window.requestAnimFrame = ( function( callback ) { @@ -19,181 +23,221 @@ window.requestAnimFrame = ( function( callback ) { }; })(); -(function (factory) { - - "use strict"; - - var define = define || false; - var jQuery = jQuery || false; - - if (define && typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals - factory( jQuery ); - } -}(function ( jQuery ) { +(function (root, factory) { + + //"use strict"; + + //var define = define || false; + var jquery = root.$ || root.jQuery || root.ender; + + if (typeof define === 'function' && define.amd){ + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory( jquery ); + } + +}(this, function ( $ ) { // Local variables var css, _css; +var files = {}; +var origin = location.origin || location.protocol + "//" + location.hostname + (location.port ? ":" + location.port: ""); // Create a fn container for internal methods var fn = { - self : function(){ return this; } - }; + self : function(){ return this; } +}; + var defaults = { - watch : false, + alpha: true, + clock: true, + watch: false, //deps : { "THREE" : "http://cdnjs.cloudflare.com/ajax/libs/three.js/r54/three.min.js" } - deps : { + deps: { "THREE" : "https://raw.github.com/mrdoob/three.js/master/build/three.min.js" //"FresnelShader" : "" - } - + }, + paused: false }; - - Three = function( obj, options, callback ){ - + + Three = function( element, options, callback ){ + var self = this; - this.container = obj; - this.options = $.extend(true, defaults, options); + this.el = this.setEl( element ); + this.options = $.extend(true, {}, defaults, options); // main buckets this.objects = {}; this.scenes = {}; this.cameras = {}; + this.terrains = {}; this.materials = {}; + // defining types (extandable) + this.groups = { + "camera" : "cameras", "scene" : "scenes", "terrain" : "terrains", "mesh" : "objects", "plane" : "objects", "cube" : "objects", "sphere" : "objects", "cylinder" : "objects", "material" : "materials" + }; + + // init clock + if( this.options.clock ) this.clock = new THREE.Clock(); + // #43 - calculating 'actual' framerate (use clock?) + this.frame = { + current: 0, + rate: 0, + date: new Date() + }; // pointers for objects this.last = false; this.parent = false; - + // Dependencies (replace with AMD module?) this.dependencies( function () { self.init(); // execute callback if( callback instanceof Function ) callback( self ); - + }); }; Three.prototype = { init : function() { - + var self = this; // create active object this.active = { scene: false, - camera: false, + camera: false, skybox: false }; // set properties this.properties = this.setProperties(); - + // init renderer - this.renderer = new THREE.WebGLRenderer(); + this.renderer = new THREE.WebGLRenderer({ alpha: this.options.alpha }); this.renderer.setSize( this.properties.width, this.properties.height); // condition this! this.renderer.autoClear = false; - + // #23 - remove fallback message - $(this.container).find(".fallback").remove(); + $(this.el).find(".fallback").remove(); // check if the container has (existing) markup - var html = $(this.container).html(); + var html = $(this.el).html(); // clear it off... - $(this.container).html(""); - this.parent = $(this.container).find("shadow-root"); + $(this.el).html(""); + this.parent = $(this.el).find("shadow-root"); + this.target = this.parent; this.html( html ); - + //document.body.appendChild( this.renderer.domElement ); - $( this.renderer.domElement ).appendTo( this.container ); - + $( this.renderer.domElement ).appendTo( this.el ); + // set first as active (refactor later) //this.active.scene = this.scenes[0]; //this.active.camera = this.cameras[0]; // don't set as active if it's 'hidden' //if( css.display == "none" ) return; - + // resize event listener window.addEventListener( 'resize', function(){ self.resize(); }, false ); - + // #31 - live watching DOM updates - if( this.options.watch ) this.watch(this.container); - + if( this.options.watch ) this.watch(this.parent); + this.tick(); - + }, destroy : function( ) { - + return this.each(function(){ - + var $this = $(this), three = $this.data('three'); $this.removeData('three'); - + }); - + }, - // check if the obj has a Three() class attached to it + // check if the element has a Three() class attached to it self: function(options, callback){ - + var list = []; - + this.each(function(){ - - var $this = $(this), + + var $this = $(this), three = $this.data('three'); - + // check if three has initialized for the ocntainer if ( ! three ) { three = new Three( this, options, callback); $(this).data('three', three); } - + // push the lib down the display list list.push( three ); - + }); - - // return as a jQuery object + + // return as a jQuery object // collapse the array if only one item return (list.length == 1) ? list[0] : $(list); - - }, + + }, // one cycle in an infinite loop tick : function() { - + var self = this; // update vars for objects - // - this.render(); + // + // skip render if paused + if( !this.options.paused ) this.render(); + // #43 - calculate framerate + var now = new Date(); + if( this.frame.date.getSeconds() === now.getSeconds() ){ + this.frame.current++; + } else { + // new frame, new count + this.frame.rate = this.frame.current; + this.frame.current = 1; //start from 1 to include running frame ;) + this.frame.date = now; + } // loop on the next click requestAnimFrame(function(){ self.tick(); }); - - }, + + }, render : function() { - // apply transformations - $(this.container).trigger({ - type: "update", - target: this - }); - // - + // init render if( this.active.scene && this.active.camera ){ - // render the skybox as a first pass + // resize skybox to the limits of the active camera (far attribute) if( this.active.skybox ){ - this.active.skybox.camera.rotation.copy( this.active.camera.rotation ); - this.renderer.render( this.active.skybox.scene, this.active.skybox.camera ); - + //if( this.active.skybox.camera ) this.active.skybox.camera.rotation.copy( this.active.camera.rotation ); + //this.renderer.render( this.active.skybox.scene, this.active.skybox.camera ); + var horizon = this.active.camera.far; + var scale = this.active.skybox.scale; + if( scale.x !== horizon ) + scale.x = scale.y = scale.z = horizon; + // always center around camera... + var position = this.active.camera.position; + this.active.skybox.position.set( position.x, position.y, position.z ); } + this.renderer.render( this.active.scene, this.active.camera ); } - - }, - + + // update internal animation queue + this.fn.animate.update(); + // trigger update event regardlesss + $(this.el).trigger({ + type: "update", + target: this + }); + }, + show : function( ) { }, hide : function( ) { }, update : function( content ) { }, @@ -202,58 +246,56 @@ Three.prototype = { * Inspired by Three's Detect.js * https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js */ - detect: function(){ - + detect: function(){ + return { canvas: !! window.CanvasRenderingContext2D, webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), workers: !! window.Worker, fileapi: window.File && window.FileReader && window.FileList && window.Blob, - + all: function () { return ( this.webgl && this.canvas && this.workers && this.fileapi ); } }; - }, + }, // trigger when the window is resized resize: function(){ - + // update properties this.properties = this.setProperties(); - // loop through cameras for( var i in this.cameras ){ - this.cameras[i].aspect = this.properties.aspect; this.cameras[i].updateProjectionMatrix(); - // better way of targeting skybox??? - this.active.skybox.aspect = this.properties.aspect; - this.active.skybox.updateProjectionMatrix(); - } - + // better way of targeting skybox??? + //if( this.active.skybox ){ + // this.active.skybox.camera.aspect = this.properties.aspect; + // this.active.skybox.camera.updateProjectionMatrix(); + //} this.renderer.setSize( this.properties.width, this.properties.height ); - }, - + }, + dependencies : function( callback ){ - + var scripts = $.map( this.options.deps , function (item, index) { // checking if the namespace is available if( window[index] || ( window.THREE && window.THREE[index] ) ) return; - return item; - }); - - // replace this with a proper dependency loader... + return item; + }); + + // replace this with a proper dependency loader... if( scripts.length ){ this.loadScripts(scripts, callback); } else { callback(); } - }, + }, loadScripts : function(scripts, callback){ var self = this; - + $.when( $.getScript( scripts.shift() ) ).done(function(){ if( scripts.length > 0 ){ self.loadScripts(scripts, callback); @@ -262,8 +304,18 @@ Three.prototype = { callback(); } }); + }, + + setEl: function( el ){ + // add an id if not available + var id = $(this).attr('id'); + // For some browsers, `attr` is undefined; for others `attr` is false. Check for both. + if (typeof id === "undefined" || id === false) { + $(el).addClass("3d-" + utils.unid() ); + } + return el; } - + }; @@ -272,8 +324,8 @@ $.fn.three = function( options, callback ) { // fallbacks var a = options || ( options = false ); var b = callback || ( callback = function(i){ return i; } ); - - return Three.prototype.self.apply( this, arguments, options, callback ); + + return Three.prototype.self.apply( this, arguments, options, callback ); /* if( !options) { @@ -283,7 +335,7 @@ return this.each(function(){ new Three( options ); } -} +} if ( Three[method] ) { return Three[method].apply( this, Array.prototype.slice.call( arguments, 1 )); @@ -291,26 +343,30 @@ return Three[method].apply( this, Array.prototype.slice.call( arguments, 1 )); return Three.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.Three' ); -} +} */ }; // get attributes from tags Three.prototype.getAttributes = function( html ){ - // + // var data={}; // filter only the ones with the data- prefix $(html).each(function(){ - + var attr = this.attributes; - + for( var i in attr ){ if( attr[i].name && attr[i].name.search("data-") === 0 ){ var key = attr[i].name.replace("data-", ""); + // #47 convert dashed to camelCase + key = utils.camelCase( key ); var val = attr[i].value; // check if it's a number... - data[key] = ( parseInt(val, 10) ) ? parseInt(val, 10) : val; + data[key] = ( parseInt(val, 10) || val === "0" ) ? parseInt(val, 10) : val; + // convert boolean + if( data[key] === "false" || data[key] === "true" ) data[key] = JSON.parse( data[key] ); } else if( attr[i].name && attr[i].name.search("class") === 0 ){ // add classes var classes = attr[i].value.split(" "); @@ -323,22 +379,22 @@ Three.prototype.getAttributes = function( html ){ data.style = attr[i].value; } } - + }); - + return data; }; - + // add a class Three.prototype.addClass = function( name ){ var object = this.last; - // add the class to the markup - var $el = $(this.container).find("[data-id='"+ object.id +"']"); + // add the class to the markup + var $el = $(this.el).find("[data-id='"+ object.id +"']"); $el.addClass(name); - - var options = this.css( $el ); - this.fn.css.set.call( object, options ); - + // update 3d object + var options = this.fn.css.styles.call(this, $el ); + this.fn.css.set.call(this, object, options ); + return this; }; @@ -346,32 +402,61 @@ Three.prototype.addClass = function( name ){ // CSS // Public Methods -css = function (a){ +css = function ( styles ){ + // support more than one formats? + // for now expecting a straighforward object... + this.fn.css.set.call(this, this.last , styles); + // preserve chainability + return this; + }; + +// Internal functions +fn.css = { + styles: function (a){ var sheets = document.styleSheets, o = {}; - for(var i in sheets) { - var rules = sheets[i].rules || sheets[i].cssRules; + + // loop through stylesheets + for( var i in sheets ){ + var sheet = sheets[i]; + var isOutsideOfDomain = sheet.href && sheet.href.indexOf("/") !== 0 && sheet.href.indexOf(origin) !== 0; + // ignore sheets out-of-domain or without CSS rules + if(isOutsideOfDomain || sheet.cssRules === null) continue; + // + var rules = sheet.cssRules || sheet.rules; for(var r in rules) { // #21 - excluding :hover styles from parsing if( rules[r].selectorText && rules[r].selectorText.search(":hover") > -1) continue; - if(a.is(rules[r].selectorText)) { - o = $.extend(o, css2json(rules[r].style), css2json(a.attr('style'))); + // excluding other pseudo elements + if( rules[r].selectorText && rules[r].selectorText.search("::before") > -1) continue; + if( rules[r].selectorText && rules[r].selectorText.search("::after") > -1) continue; + try{ + if(a.is(rules[r].selectorText)) { + o = $.extend(o, css2json(rules[r].style)); + } + } catch( e ) { + console.log( e ); } } } + // add inline styles + o = $.extend(o, css2json(a.attr('style'))); + // return o; - }; - - -// Internal functions -fn.css = { - + }, set: function( object, css ){ - - if( !object ) return; - + // if the object is not valid quit... + if( !object || !object.id ) return; + for( var attr in css ){ // remove prefixes var key = attr.replace('-webkit-','').replace('-moz-',''); + // save attribute reference in the object + object._style = object._style || {}; + object._shaders = object._shaders || {}; + var changed = ( object._style[key] && object._style[key] == css[attr] ) ? false : true; // save old value? + object._style[key] = css[attr]; + // parse only changed atrributes + if( !changed ) continue; // supported attributes switch(key){ // - width @@ -399,12 +484,17 @@ fn.css = { // - color case "color": var color = this.colorToHex(css[attr]); - object.material.color.setHex(color); + if( object instanceof THREE.Scene){ + //this.fn.css.skybox.call(this, css[attr]); + this.webglLight({color : color}); + } else { + setColor( object, color ); + } break; // - transforms case "transform": var pos; - if(css[attr].search("translate3d") > -1 ){ + if(css[attr].search("translate3d") > -1 ){ pos = this.fn.css.translate.call( this, css[attr] ); // condition the position for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -413,7 +503,7 @@ fn.css = { object.position.set( pos.x, pos.y, pos.z ); } } - if(css[attr].search("rotate3d") > -1 ){ + if(css[attr].search("rotate3d") > -1 ){ pos = this.fn.css.rotate.call( this, css[attr] ); // condition the rotation for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -422,7 +512,7 @@ fn.css = { object.rotation.set( pos.x, pos.y, pos.z ); } } - if(css[attr].search("scale3d") > -1 ){ + if(css[attr].search("scale3d") > -1 ){ pos = this.fn.css.scale.call( this, css[attr] ); // condition the position for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -434,25 +524,38 @@ fn.css = { break; // - animation case "animation-duration": - console.log( key, css[attr]); + this.fn.css.animation.duration = parseInt( css[attr], 10) * 1000; // convert seconds to milliseconds break; case "animation-timing": - console.log( key, css[attr]); + this.fn.css.animation.easing = css[attr]; break; case "animation-delay": - console.log( key, css[attr]); + this.fn.css.animation.delay = css[attr]; break; case "animation-iteration-count": - console.log( key, css[attr]); + this.fn.css.animation.repeat = css[attr]; break; case "animation-direction": - console.log( key, css[attr]); + this.fn.css.animation.direction = css[attr]; break; case "animation-fill-mode": - console.log( key, css[attr]); + this.fn.css.animation.fill = css[attr]; break; case "animation-name": - console.log( key, css[attr]); + //console.log( key, css[attr]); + // assumption: name is the last animation attribute processed + this.fn.css.animation.name = css[attr]; + this.animate( this.fn.css.animation, object ); + this.fn.css.animation = {}; + break; + case "animation-timing-function": + // duplicate of animation-timing? + // if counting steps, save the number + var steps = css[attr].match(/steps\((\d)/); // not closed.. + this.fn.css.animation.easing = ( steps ) ? parseInt(steps[1], 10) : css[attr]; + break; + case "animation-play-state": + this.fn.css.animation.state = css[attr]; break; case "display": // set it as the active one... @@ -461,43 +564,134 @@ fn.css = { // background of a scene is a skydome... if( object instanceof THREE.Scene){ this.fn.css.skybox.call(this, css[attr]); - } - if( object.type == "terrain" ){ + } else if( object.type == "terrain" ){ + // make sure this get's processed on the next tick + //utils.delay( this.fn.css.terrain.bind(this), 100, css[attr] ); this.fn.css.terrain.call(this, css[attr]); - } else if ( object instanceof THREE.Mesh ) { + } else if ( object instanceof THREE.Mesh ) { this.fn.css.texture.call(this, object, css[attr]); + } else if ( object instanceof THREE.Object3D && object.children.length) { + // potentially the above condition can be removed if the ids are assigned properly in the markup... + try { + // find the child... + var mesh = object.children[0]; + this.fn.css.texture.call(this, mesh, css[attr]); + } catch( e ){ + console.log(e); + } + } else if( object instanceof THREE.Sprite ){ + var src = css[attr].replace(/\s|url\(|"|'|\)/g, ""); + object.material.map = utils.textureLoader( src ); + } + break; + case "background-size": + if( object instanceof THREE.Sprite ){ + // + this.fn.css.sprite.call(this, object, css[attr]); + } + break; + // "background-position" arrives split in axis + case "background-position-x": + if( object instanceof THREE.Sprite ){ + // update sprite + this.fn.css.sprite.call(this, object); + } + break; + case "background-position-y": + if( object instanceof THREE.Sprite ){ + // update sprite + this.fn.css.sprite.call(this, object); + } + break; + case "filter": + // variables + // - find element + var el, $el; + if( object instanceof THREE.Mesh && object.parent instanceof THREE.Object3D ){ + // parent is always an object...? + el = object.parent; + $el = object.parent.$el; + } else { + el = object; + $el = object.$el; + } + // get URLs + var urls = css[attr].replace(/url\(|"|'|\)/g, "").split('|'); // all shaders in one url? + // prerequisite + if( !urls.length ) break; + // get shaders + el._shaders = el._shaders || {}; + for( var i in urls ){ + var name = urls[i].substring(urls[i].lastIndexOf('/')+1); + el._shaders[name] = utils.getFile( urls[i] ); } + // add helper method + el.getShader = function( name ){ + return this._shaders[name] || null; + }; + // trigger event + $el.trigger('css-filter'); break; } - + } - + }, - + + // temporary container for parsed (animation) attributes... + animation: {}, + rotate: function( attr ){ - + var rot = {}; - // only supporting rotate3d for now... + var val; + // if( attr.search("rotate3d") > -1 ){ // replace all the bits we don't need - var val = attr.match(/rotate3d\(([\s\S]*?)\)/gi); + val = attr.match(/rotate3d\(([\s\S]*?)\)/gi); // match returns array... val = val[0].replace(/rotate3d\(|deg|\)| /gi, "").split(","); // first three numbers toggle axis application - fourth is the degrees rot = { - x: ( parseInt( val[0], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0, - y: ( parseInt( val[1], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0, - z: ( parseInt( val[2], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0 + x: parseFloat( val[0], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180), + y: parseFloat( val[1], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180), + z: parseFloat( val[2], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180) + }; + + } else if( attr.search("rotateX") > -1 ){ + // axis based rotation + val = attr.match(/rotateX\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateX\(|deg|\)| /gi, ""). + rot = { + x: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotateY") > -1 ){ + val = attr.match(/rotateY\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateY\(|deg|\)| /gi, ""); + rot = { + y: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotateZ") > -1 ){ + val = attr.match(/rotateZ\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateZ\(|deg|\)| /gi, ""); + rot = { + z: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotate") > -1 ){ + val = attr.match(/rotate\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotate\(|deg|\)| /gi, ""); + // if no axis is set assume Z? + rot = { + z: parseFloat( val, 10 ) * (Math.PI/180) }; - } - + return rot; - - }, - + + }, + translate: function( attr ){ - + var pos = {}; // only supporting translate3d for now... if( attr.search("translate3d") > -1 ){ @@ -507,21 +701,21 @@ fn.css = { val = val[0].replace(/translate3d\(|px|\)| /gi, "").split(","); // add the right keys pos = { - x: parseInt( val[0], 10 ) || 0, - y: parseInt( val[1], 10 ) || 0, - z: parseInt( val[2], 10 ) || 0 + x: parseFloat( val[0], 10 ) || 0, + y: parseFloat( val[1], 10 ) || 0, + z: parseFloat( val[2], 10 ) || 0 }; - + } - + return pos; - - }, - + + }, + scale: function( attr ){ - + var size = {}; - // only supporting rotate3d for now... + // only supporting scale3d for now... if( attr.search("scale3d") > -1 ){ // replace all the bits we don't need var val = attr.match(/scale3d\(([\s\S]*?)\)/gi); @@ -529,101 +723,138 @@ fn.css = { val = val[0].replace(/scale3d\(|\)| /gi, "").split(","); // first three numbers toggle axis application - fourth is the degrees size = { - x: parseInt( val[0], 10 ) || 0, - y: parseInt( val[1], 10 ) || 0, - z: parseInt( val[2], 10 ) || 0 + x: parseFloat( val[0], 10 ) || 0, + y: parseFloat( val[1], 10 ) || 0, + z: parseFloat( val[2], 10 ) || 0 }; - + } - + return size; - - }, - + + }, + texture: function( el, attr ){ - var map = attr.replace(/\s|url\(|\)/g, ""); - var material = this.webglMaterial({ map : map }); + var material; + var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); + if( img.length > 1 ){ + // shader material + // add available shaders + var uniforms = {}; + var params = {}; + var textureCube = new THREE.CubeTextureLoader().load( img ); + //var textureCube = app.layout.views.get('back').$3d.active.skybox.material.uniforms.tCube.value ); + textureCube.format = THREE.RGBFormat; + + uniforms.tCube = { + type: "t", + value: textureCube + }; + // add shaders if available + if(el._shaders){ + for( var i in el._shaders ){ + var shader = el._shaders[i]; + if( i.indexOf('.fs') > -1 ){ + params.fragmentShader = shader; + } + if( i.indexOf('.vs') > -1 ){ + params.vertexShader = shader; + } + } + } + + params.uniforms = uniforms; + params.needsUpdate = true; + + material = new THREE.ShaderMaterial( params ); + + } else { + // basic map material + material = this.webglMaterial({ map : img[0] }); + } el.material = material; - }, - + }, + terrain: function( attr ){ - var object = this.last; - - var img = attr.replace(/\s|url\(|\)/g, "").split(','); + var terrain = this.last; + //var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); + var img = attr.match(/url\(\s*[\'"]?(([^\\\\\'" \(\)]*(\\\\.)?)+)[\'"]?\s*\)/img); + // if(img instanceof Array){ + var heightmap, diffuse, specular; for( var i in img ){ - - if( img[i].search("heightmap") > -1 ){ - - var heightmapTexture = THREE.ImageUtils.loadTexture( img[i] ); - //var heightmapTexture = this.webglTexture( img[i] ); - object.material.uniforms.tDisplacement.value = heightmapTexture; - object.material.uniforms.uDisplacementScale.value = 375; - // heightmap also the second diffuse map? - var diffuseTexture2 = heightmapTexture; - diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tDiffuse2.value = diffuseTexture2; - object.material.uniforms.enableDiffuse2.value = true; - - } - if( img[i].search("diffuse") > -1 ){ - - var diffuseTexture1 = THREE.ImageUtils.loadTexture( img[i] ); - //var diffuseTexture1 = this.webglTexture( img[i] ); - diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tDiffuse1.value = diffuseTexture1; - object.material.uniforms.enableDiffuse1.value = true; - - } - if( img[i].search("specular") > -1 ){ - - var specularMap = THREE.ImageUtils.loadTexture( img[i] ); - //var specularMap = this.webglTexture( img[i] ); - specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tSpecular.value = specularMap; - object.material.uniforms.enableSpecular.value = true; - - } + // clean url(...) content + img[i] = img[i].replace(/\s|url\(|"|'|\)/g, ""); + + if( img[i].search("heightmap") > -1 ) heightmap = terrain.updateTexture('heightmap', img[i]); + + if( img[i].search("diffuse") > -1 ) diffuse = terrain.updateTexture('diffuse', img[i]); + + if( img[i].search("specular") > -1 ) specular = terrain.updateTexture('specular', img[i]); + } + // fallbacks + if(!heightmap && img[0]) terrain.updateTexture('heightmap', img[0]); + if(!diffuse && img[1]) terrain.updateTexture('diffuse', img[1]); + if(!specular && img[2]) terrain.updateTexture('specular', img[2]); + } else { - // one image... which texture is it?... + // one image... assume it's both heightmap and texture + terrain.updateTexture('heightmap', img); + terrain.updateTexture('diffuse', img); } - - /* - - leftovers ( normal and detail textures) - - //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; - - //uniformsTerrain[ "tNormal" ].value = heightmapTexture; - //uniformsTerrain[ "uNormalScale" ].value = 1; - - //uniformsTerrain[ "tDetail" ].value = detailTexture; - - //uniformsTerrain[ "uShininess" ].value = 30; - - */ - }, - - + + }, + + skybox: function( attr ){ - + // remove any whitespace, the url(..) and // attempt to break it into an array - var img = attr.replace(/\s|url\(|\)/g, "").split(','); + var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); if(img instanceof Array){ - // expext a six-pack of images + // expect a six-pack of images this.addSkybox( img ); - + } else { // this is one image... not implemented yet } - + + }, + + sprite: function( el, attr ){ + // wait for the image to load + var loaded = setInterval(function(){ + // assume map is available... + if( !el.material.map.image || !el.material.map.image.width ) return; + // fallbacks + attr = attr || el._style["background-size"] || "0 0"; + var size = attr.split(" "); + var width = parseFloat(size[0], 10); + var height = parseFloat(size[1], 10); + // get position from style + var x = parseFloat( el._style["background-position-x"] || 0 ); + var y = parseFloat( el._style["background-position-y"] || 0 ); + + if( !width || !height ) return; + + // image dimensions + var imgWidth = el.material.map.image.width; + var imgHeight = el.material.map.image.height; + // + //el.material.uvOffset.set(1 / 5, 0); + //el.material.uvScale.set(1 / 5, 1); + el.material.map.offset.set( (imgWidth - width - x) / imgWidth, (imgHeight - height - y) / imgHeight ); // start from top left... + el.material.map.repeat.set(width / imgWidth, height / imgHeight); + //el.scale.set( width, height, 1 ); + //console.log("sprite loaded"); + // stop loop + clearInterval(loaded); + }, 200); + + } - + }; /* @@ -632,10 +863,10 @@ fn.css = { for( var attr in css ){ // supported attributes switch(attr){ - + } } - }, + }, */ @@ -655,7 +886,7 @@ var css2json = function (css){ } } } else if(typeof css == "string") { - css = css.split("; "); + css = css.split("; "); for (var j in css) { var l = css[j].split(": "); s[l[0].toLowerCase()] = (l[1]); @@ -664,318 +895,729 @@ var css2json = function (css){ return s; }; +function setColor( object, color ){ + object = object || {}; + // prerequisite + if( !object.material ) return; // create material instead? + // in case we have more than one materials + if( object.material.materials ){ + // check it it's an array first? + for(var i in object.material.materials ){ + object.material.materials[i].color.setHex(color); + } + } else { + object.material.color.setHex(color); + } +} -Three.prototype.animate = function(){ - //this.mesh.rotation.z = Date.now() / 1000; - - }; +Three.prototype.animate = function( options, el ){ + //this.mesh.rotation.z = Date.now() / 1000; -// watch an element for changes -Three.prototype.watch = function( el ) { - // monitor new elements - $( el ).bind('DOMSubtreeModified', this.eventSubtree); - // monitor attribute changes - if (el.onpropertychange){ - $( el ).bind( 'propertychange', this.eventAttribute ); + // fallbacks + options = options || {}; + el = el || this.last || false; // last processed object + // FIX: we are checking the type of the element to attach to Object3D? + if( el instanceof THREE.Mesh && el.parent instanceof THREE.Object3D ){ + el = el.parent; } - else { - $( el ).bind( 'DOMAttrModified', this.eventAttribute ); + // prerequisites + if( !el || !options.name ) return; + // create the necessary object containers + // should we be checking the type of the element to attach to Object3D? + el._animations = el._animations || {}; + el._update = el._update || updateAnimations.bind( el ); + + // pickup animation keyframes + options.keyframes = this.fn.animate.getKeyframes.call( this, options.name ); + // exit now... + if( !options.keyframes ) return; + // set the new animation + el._animations[ options.name ] = options; + // add to animate queue (once...) + var inQueue = ( typeof this.fn.animate.queue[el.uuid] !== "undefined" ); + if( !inQueue){ + this.fn.animate.queue[el.uuid] = el._update; // using uuid to be able to remove from queue later } - // monitor css style changes - - }; -// - new element -Three.prototype.eventSubtree = function(e) { - - if (e.target.innerHTML.length > 0) { - // Handle new content - console.log( e.target.innerHTML ); +// Internal + +fn.animate = { + // container for all methods to be updated + queue: {}, + + getKeyframes: function( name ){ + var keyframes = {}; + // first find the rules + var animation = findKeyframesRule( name ); + + if(!animation) return; + // parse each one of them + for(var i in animation.cssRules){ + var rule = animation.cssRules[i]; + var frame = {}; + // FIX: only rules parsed + if( !rule.keyText ) continue; + // convert percent to 1-100 number + var key = parseInt( rule.keyText, 10 ), val; + // find rotation values + frame.rotation = this.fn.css.rotate( rule.cssText ); + // find translate values + frame.translation = this.fn.css.translate( rule.cssText ); + // find scale values + frame.scale = this.fn.css.scale( rule.cssText ); + // other attributes + if( rule.cssText.search("background-position-x") > -1 ){ + frame["background-position"] = frame["background-position"] || {}; + val = rule.cssText.match(/:[\d|\s|\w]+\;/); // capture everything between : ; + if( val ) frame["background-position"].x = parseFloat(val[0].substr(1), 10); + } + if( rule.cssText.search("background-position-y") > -1 ){ + frame["background-position"] = frame["background-position"] || {}; + val = rule.cssText.match(/:[\d|\s|\w]+\;/); // capture everything between : ; + if( val ) frame["background-position"].y = parseFloat(val[0].substr(1), 10); + } + // add to the keyframes + keyframes[ key ] = frame; + } + return keyframes; + }, + + // loop through the object's animations and update the object's properties + update: function( el ){ + //console.log( this.queue ); + // loop through the queue + for( var i in this.queue ){ + // execute + this.queue[i](); + } } -}; -// - updated attribute -Three.prototype.eventAttribute = function(e) { - - console.log("attribute", e.target ); - }; -// - updated style(s) - - +// Helpers -// generic method to add an element -Three.prototype.add = function( options ){ - // use the active scene if not specified - //var parent = scene || this.active.scene; - // get the type from the tag name - //var type = html.nodeName.toLowerCase(); - // list of containers (we'll be using) - var groups = { - "camera" : "cameras", "scene" : "scenes", "mesh" : "objects", "plane" : "objects", "cube" : "objects", "sphere" : "objects", "cylinder" : "objects", "material" : "materials" +function updateAnimations(){ + // context is the individual object + //console.log( this ); + // loop through animations + for( var i in this._animations){ + var animation = this._animations[i]; + var keyframes = animation.keyframes; + // get current params + animation.start = animation.start || utils.now(); + animation.end = animation.end || ( animation.start + animation.duration ); + animation.offset = animation.offset || registerState( this ); + animation.count = animation.count || 0; + // find the right stage in the animation + var now = utils.now(); + var percent = ( ( now - animation.start) / animation.duration ) * 100; + var start = false, + end = false; + for( var key in keyframes ){ + if( key <= percent ){ + start = keyframes[ key ]; + } + if( key > percent && !end ){ + end = keyframes[ key ]; + } + } + // fallbacks + if( !start ) start = keyframes[ 0 ]; + if( !end ) end = keyframes[ 100 ]; + // apply updates + // NOTE: only linear supported for now... + // - rotate + var rot = { + x: ( typeof start.rotation.x != "undefined" && typeof end.rotation.x != "undefined" ) ? (end.rotation.x - start.rotation.x )*(percent/100) : 0, + y: ( typeof start.rotation.y != "undefined" && typeof end.rotation.y != "undefined" ) ? (end.rotation.y - start.rotation.y )*(percent/100) : 0, + z: ( typeof start.rotation.z != "undefined" && typeof end.rotation.z != "undefined" ) ? (end.rotation.z - start.rotation.z )*(percent/100) : 0 }; - var object; - - // exit if no type is specified - if( typeof options == "undefined" || typeof options.type == "undefined" ) return this; - - // create 3d element - var webgl = this.webgl( options ); - // exit now if no webgl object was created (undefined condition should be removed) - if( !webgl || typeof webgl == "undefined") return this; - // add a new tag (if necessary) - //if ( options.html ){ - - // set a reference to the last el (for later) - this.last = webgl; - - // add to the relevant bucket - var container = groups[ options.type ] || false; - // create object container only for primitives... - if( container == "objects" ){ - // create new object - object = new THREE.Object3D(); - object.add(webgl); - } else { - object = webgl; + this.rotation.set( animation.offset.rotation.x+rot.x, animation.offset.rotation.y+rot.y, animation.offset.rotation.z+ rot.z); + // TBA... + // - translate + + // - scale + + // - sprites + if( this instanceof THREE.Sprite ){ + // get current sprite index + var offset = { + x: this.material.map.offset.x, + y: this.material.map.offset.y + }; + // increment + var steps = animation.easing; + var step = 100/steps; + var nextStep = ( (parseInt( percent, 10) % step) === 0 ) ? parseInt( percent, 10) / 100 : 0; // every time we return to zero we have a new step + if( nextStep ){ + // FIX: start index of steps from zero + nextStep -= 1/steps; + // find the right axis + if( typeof animation.keyframes[0]["background-position"].x !== "undefined" ){ + // - numbers go in reverse order (steps-1 to 0) + offset.x = ((steps-1)/steps)-nextStep; + } + if( typeof animation.keyframes[0]["background-position"].y !== "undefined" ){ + // - numbers go in reverse order (steps-1 to 0) + offset.y = ((steps-1)/steps)-nextStep; + } + // update sprite + this.material.map.offset.set( offset.x, offset.y ); + } + } - //this[ options.type+"s" ][0] = webgl; - // condition which elements have an active flag? - this.active[ options.type ] = object; - // - if( container ){ - // save in the objects bucket - this[container][object.id] = object; + // reset if reached completion + if( percent >= 100 ){ + delete animation.start; + delete animation.end; + delete animation.offset; + animation.count++; } - // add to scene - if( options.type == "scene"){ - this.active.scene = object; + // + if( animation.count == animation.repeat ){ + delete this._animations[i]; } else { - this.active.scene.add( object ); + // save animation updates + this._animations[i] = animation; + } + } +} + +// register element state +function registerState( el ){ + return { + position: { + x: el.position.x, + y: el.position.y, + z: el.position.z + }, + rotation: { + x: el.rotation.x, + y: el.rotation.y, + z: el.rotation.z + }, + scale: { + x: el.scale.x, + y: el.scale.y, + z: el.scale.z } - // keep a reference of the object id - options["data-id"] = object.id || false; - // create the tag in the shadow dom - var $html = this.createHTML( options ); - - // apply css - var css = this.css( $html ); - this.fn.css.set.call(this, webgl, css ); - - return this; - - }; - -Three.prototype.addScene = function( obj ){ - - var options = obj ||{}; - - options.type = "scene"; - - this.add(options); - - return this; - - }; - -// add camera(s) -Three.prototype.addCamera = function( obj ){ - - var options = obj ||{}; - - options.type = "camera"; - - this.add(options); - - return this; - - }; - -// add meshes -Three.prototype.addMesh = function( obj ){ - - var options = obj ||{}; - - options.type = "mesh"; - - this.add(options); - - return this; - }; - -// add a plane -Three.prototype.addPlane = function( obj ){ - +} + +/* + * Access and modify CSS animations @keyFrames with Javascript + * Based on : http://jsfiddle.net/russelluresti/RHhBz/2/ + * Issue : http://stackoverflow.com/questions/10342494/set-webkit-keyframes-values-using-javascript-variable + */ + + // search the CSSOM for a specific -webkit-keyframe rule +function findKeyframesRule(rule){ + // gather all stylesheets into an array + var ss = document.styleSheets; + + // loop through the stylesheets + for (var i = 0; i < ss.length; ++i) { + + // loop through all the rules + for (var j = 0; j < ss[i].cssRules.length; ++j) { + + // find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule + if (ss[i].cssRules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && ss[i].cssRules[j].name == rule) + return ss[i].cssRules[j]; + } + } + + // rule not found + return null; +} + +// remove old keyframes and add new ones +function changeAnimationKeyframes(anim){ + // find our -webkit-keyframe rule + var keyframes = findKeyframesRule(anim); + + // remove the existing 0% and 100% rules + keyframes.deleteRule("0%"); + keyframes.deleteRule("100%"); + + // create new 0% and 100% rules with random numbers + keyframes.insertRule("0% { -webkit-transform: rotate("+randomFromTo(-360,360)+"deg); }"); + keyframes.insertRule("100% { -webkit-transform: rotate("+randomFromTo(-360,360)+"deg); }"); + + // assign the animation to our element (which will cause the animation to run) + document.getElementById('box').style.webkitAnimationName = anim; +} + +Three.prototype.fx = function(){ + //this.mesh.rotation.z = Date.now() / 1000; + + }; + +// watch an element for changes +Three.prototype.watch = function( el ) { + var self = this; + var selector = $( el ).selector || "shadow-root"; // fallback to main root + var element = $(this.el).toSelector() +" "+ selector; + + var node = document.getElementById("main").querySelector("shadow-root"), //$(this.el)[0], //$(element)[0], + bubbles = false; + + // shim + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + + var whatToObserve = { childList: true, attributes: true, subtree: true, attributeOldValue: true, attributeFilter: ['class', 'style']}; + //var whatToObserve = { childList: true, attributes: false, subtree: true }; + var attrObserver = new MutationObserver(function(mutationRecords) { + $.each(mutationRecords, function(index, mutationRecord) { + var e = mutationRecord; + if (mutationRecord.type === 'childList') { + if (mutationRecord.addedNodes.length > 0) { + //DOM node added, do something + //console.log("execute", mutationRecord ); + //console.log('DOMSubtreeModified', e.target.innerHTML.length, e.target ); + self.eventSubtree(e); + } else if (mutationRecord.removedNodes.length > 0) { + //DOM node removed, do something + } + } + else if (mutationRecord.type === 'attributes') { + if (mutationRecord.attributeName === 'class') { + //class changed, do something + self.eventAttribute(e); + } + } + }); + }); + + attrObserver.observe(node, whatToObserve); + + // monitor new elements + /* + $('body').on('DOMSubtreeModified', element, function(e){ + console.log(e); + self.eventSubtree(e); + }); + // monitor attribute changes + if (el.onpropertychange){ + $('body').on('propertychange', element, function(e){ + self.eventAttribute(e); + }); + } + else { + $('body').on('DOMAttrModified', element, function(e){ + self.eventAttribute(e); + }); + } + */ + + var observeStyles = new MutationObserver(function (mutations) { + mutations.forEach(stylesModified); + }); + observeStyles.observe(node, { childList: false, attributes: true, subtree: true, attributeFilter: ['class', 'style'] }); + + + // monitor css style changes + function stylesModified(mutation) { + var el = mutation.target, + name = mutation.attributeName, + newValue = mutation.target.getAttribute(name), + oldValue = mutation.oldValue; + // skip all id, data-id updates (not editable from the user) + //if( name == 'id' || name == 'data-id' ) return; + // styling updates + if( name == 'style' ){ + var object = self.objects[ el.getAttribute('data-id') ] || self.active.terrain; + var webgl = object.children[0] || object; + var css = css2json(newValue); // validate? + // HACK: why is terrain using this.last? + self.last = webgl; + self.fn.css.set.call(self, webgl, css ); + } + //console.log(name, newValue, oldValue); + } + +}; + +// - new element +Three.prototype.eventSubtree = function(e) { + //e.stopPropagation(); // mutation event doesn't propagate? + + // variables + var $root = $( $(this.el).toSelector() +" shadow-root" ).get(0); + var $target = $(e.target).get(0); + + // don't go above the root + this.parent = ( $root == $target ) ? $(e.target) : $(e.target).parent(); + this.target = $(e.target); + + // exclude shadow-root + //if( $root == $target ) return; + // exclude empty targets + if(e.target.innerHTML.length === 0) return; + // Handle new content + //var html = e.target.innerHTML; + var html = $(e.target).html(); + //var wrapper = $(html).eq(0)[0]; + // FIX: exclude empty div tags (dead-ends) + //if( wrapper.tagName == "DIV" && + //if( wrapper.toString().substr(0, 5).toLowerCase() == "
" ) return; + // html = wrapper.childNodes[0].toString().trim(); + //this.newEl = $(e.target).children().last(); + // #46 parsing one tag at a time + //html = $(html).html("").get(0); + //this.newEl = $(html).last(); + this.append( html, { silent : true, target: this.target, traverse: false, watch: true }); + +}; + +// - updated attribute +Three.prototype.eventAttribute = function(e) { + //e.stopPropagation(); + + console.log("attribute", e.target ); + +}; + +// - updated style(s) + + +// generic method to add an element +Three.prototype.add = function( attributes, options ){ + var self = this; + // fallbacks + options = options || {}; + // use the active scene if not specified + //var parent = scene || this.active.scene; + // get the type from the tag name + //var type = html.nodeName.toLowerCase(); + // list of containers (we'll be using) + + // exit if no type is specified + if( typeof attributes == "undefined" || typeof attributes.type == "undefined" ) return this; + + // create 3d element + this.webgl( attributes, function( webgl ){ + + // exit now if no webgl object was created (undefined condition should be removed) + if( !webgl || typeof webgl == "undefined") return this; + // add a new tag (if necessary) + //if ( attributes.html ){ + var object; + + // set a reference to the last el (for later) + self.last = webgl; + + // add to the relevant bucket + var container = self.groups[ attributes.type ] || false; + // create object container only for primitives... + if( container == "objects" && webgl instanceof THREE.Mesh ){ + // create new object + object = new THREE.Object3D(); + object.add(webgl); + // #40 copy name from mesh + object.name = webgl.name; + } else { + object = webgl; + } + //this[ attributes.type+"s" ][0] = webgl; + + // condition which elements have an active flag? + self.active[ attributes.type ] = object; + + // keep a reference of the object id + attributes["data-id"] = object.id || false; + + // FIX: stop now if duplicate id was generated (why?) + if( attributes.el.data('id') ) return; + + // create the tag in the shadow dom + var $html; + if( options.silent && attributes.el){ + // target should be already set? + //$html = $(self.target).find( attributes.type ); + // add data-id to existing containers + $html = attributes.el; + $html.attr("data-id" , attributes["data-id"]); + } else { + $html = self.createHTML( attributes ); + self.target = $html; + } + + // save reference of html tag in object + object.$el = $html; + + // apply css + var css = self.fn.css.styles.call(self, $html ); + self.fn.css.set.call(self, webgl, css ); + + // save in the objects bucket + if( container ){ + self[container][object.id] = object; + } + + // add to scene + if( attributes.type == "scene"){ + self.active.scene = object; + } else if( self.active.scene ){ + self.active.scene.add( object ); + } + + }); + + return this; + }; + +Three.prototype.addScene = function( obj ){ + var options = obj ||{}; - + + options.type = "scene"; + + this.add(options); + + return this; + + }; + +// add camera(s) +Three.prototype.addCamera = function( obj ){ + + var options = obj ||{}; + + options.type = "camera"; + + this.add(options); + + return this; + + }; + +// add meshes +Three.prototype.addMesh = function( obj ){ + + var options = obj ||{}; + + options.type = "mesh"; + + this.add(options); + + return this; + + }; + +// add a plane +Three.prototype.addPlane = function( obj ){ + + var options = obj ||{}; + options.type = "plane"; - + this.add(options); - + return this; - + }; - + // add a sphere Three.prototype.addSphere = function( obj ){ - + var options = obj ||{}; - + options.type = "sphere"; - + this.add(options); - + return this; - + }; - + // add a cube Three.prototype.addCube = function( obj ){ - + var options = obj ||{}; - + options.type = "cube"; - + this.add(options); - + return this; - + }; - + // add a cylinder Three.prototype.addCylinder = function( obj ){ - + var options = obj ||{}; - + options.type = "cylinder"; - + this.add(options); - + return this; - + }; - + // add asset Three.prototype.addAsset = function( obj ){ - + var options = obj ||{}; - + options.type = "asset"; - + this.add(options); - + return this; - - }; - + + }; + Three.prototype.addSkybox = function( img ){ - - // does this camera have set values?? - var camera = new THREE.PerspectiveCamera( 50, $(this.container).width() / $(this.container).height(), 1, 100 ); - var scene = new THREE.Scene(); + //var scene = new THREE.Scene(); + var camera, geometry, material; + + if( img.length == 1){ + + //camera = new THREE.PerspectiveCamera( 50, $(this.el).width() / $(this.el).height(), 1, 1100 ); + //camera.target = new THREE.Vector3( 0, 0, 0 ); + + // skysphere + geometry = new THREE.SphereGeometry( 1, 60, 40 ); + geometry.applyMatrix( new THREE.Matrix4().makeScale( -1, 1, 1 ) ); + material = new THREE.MeshBasicMaterial({ + map: utils.textureLoader( img[0] ) + }); + + } else { + // + var reflectionCube; + // skybox (with legacy support) + if(THREE.REVISION < 70){ + reflectionCube = THREE.ImageUtils.loadTextureCube( img ); + } else { + var cubeTextureLoader = new THREE.CubeTextureLoader(); + reflectionCube = cubeTextureLoader.load( img ); + } + reflectionCube.format = THREE.RGBFormat; + + // does this camera have set values?? + //camera = new THREE.PerspectiveCamera( 50, $(this.el).width() / $(this.el).height(), 1, 100 ); - var reflectionCube = THREE.ImageUtils.loadTextureCube( img ); - reflectionCube.format = THREE.RGBFormat; + //var shader = THREE.ShaderUtils.lib.cube; + var shader = THREE.ShaderLib.cube; + var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + uniforms.tCube.value = reflectionCube; - //var shader = THREE.ShaderUtils.lib.cube; - var shader = THREE.ShaderLib.cube; - shader.uniforms.tCube.value = reflectionCube; + material = new THREE.ShaderMaterial( { - var material = new THREE.ShaderMaterial( { + fragmentShader: shader.fragmentShader, + vertexShader: shader.vertexShader, + uniforms: uniforms, + depthWrite: false, + side: THREE.BackSide - fragmentShader: shader.fragmentShader, - vertexShader: shader.vertexShader, - uniforms: shader.uniforms, - depthWrite: false, - side: THREE.BackSide + }); + // the dimensions of the skybox will be resized to the limits of the active camera (far) + geometry = new THREE.BoxGeometry( 1, 1, 1 ); + } - }); + var mesh = new THREE.Mesh( geometry, material ); + /* + var object = new THREE.Object3D(); + object.add( mesh ); + // #40 copy name from mesh + object.name = mesh.name = "skybox"; + */ + this.active.scene.add( mesh ); - mesh = new THREE.Mesh( new THREE.CubeGeometry( 100, 100, 100 ), material ); - - scene.add( mesh ); - // save as active - this.active.skybox = { - scene : scene, - camera : camera - }; - + this.active.skybox = mesh; + //this.active.skybox = { + // scene : scene, + // camera : camera + //}; }; - + Three.prototype.addTerrain = function( obj ){ - + var options = obj ||{}; - + options.type = "terrain"; - + this.add(options); - + return this; - + }; // generic method to create an element -Three.prototype.html = function(html){ +Three.prototype.html = function(html, options){ var self = this; - + // fallbacks + options = options || {}; + options.target = options.target || this.target; + if( typeof options.traverse === "undefined") options.traverse = true; + // loop throught the elements of the dom $(html).filter('*').each(function(i, el){ - // is this a jQuery bug? + // is this a jQuery bug? var $el = (typeof el == "undefined") ? false : $(el); - + // exit if there is no parent set if( !$el ) return; - - - var options = {}; + // if there's a data id this is an attribute change we don't want to monitor + if( typeof $el.attr("data-id") !== "undefined" ) return; + + var attr = {}; // use the active scene if not specified //var parent = scene || this.active.scene; // get the type from the tag name - options.type = el.nodeName.toLowerCase(); - options.id = $el.attr("id"); - + attr.type = el.nodeName.toLowerCase(); + attr.id = $el.attr("id"); + // the set of attributes var attributes = self.getAttributes( el ); // - options = $.extend(options, attributes); - - self.add( options ); - - // loop throught the children - self.html( $el.html() ); - + attr = $.extend(attr, attributes); + + attr.el = options.target.children(":eq("+i+")"); + // if we can't find the new element quit + if( options.watch && !attr.el.length ) return; + self.add( attr, options ); + + // loop through the children (only if el not empty) + if( $el.html() !== "" && options.traverse) + self.html( $el.html(), options ); + }); - + + return this; + }; /* htmlScene : function( html ){ - + var self = this; var $scene = $(html); - //make this optional? + //make this optional? var id = $scene.attr("id"); // create a new scene this.scenes[id] = this.addScene( options ); // get css attributes var css = this.css( $scene ); this.cssScene( css ); - - // render all supported objects - - - }, + + // render all supported objects + + + }, htmlCamera : function( html ){ - + this.cameras[id] = this.addCamera( options ); - - }, + + }, */ Three.prototype.createHTML = function( options ){ // create markup @@ -989,54 +1631,364 @@ Three.prototype.createHTML = function( options ){ $tag.attr("data-id", options["data-id"] ); } // add classes - if(options["class"] && options["class"].length) { + if(options["class"] && options["class"].length) { var classes = options["class"].join(" "); $tag.attr("class", classes ); } // add inline styles - if( options.style ){ + if( options.style ){ $tag.attr("style", options.style ); } // append to the dom $tag.appendTo(this.parent); - + // set as the new parent under certain conditions (for nesting)... if(options.type == "scene" || options.type == "asset" || options.type == "player"){ - this.parent = $tag; + this.parent = $tag; } - + // add listening events (if enabled) //if(this.options.watch) this.watch($tag); - + return $tag; }; -Three.prototype.append = function(html){ - - // pickup active scene - //var scene = this.active.scene; - // add the submitted markup (validation?) - //$(this.container).find("[data-id='"+ scene.id +"']").append( html ); - this.html( html ); - +Three.prototype.append = function(html, options){ + options = options || {}; + // pickup active scene + //var scene = this.active.scene; + // add the submitted markup (validation?) + //$(this.el).find("[data-id='"+ scene.id +"']").append( html ); + this.html( html, options ); + // #38 preserve chainability... + return this; +}; +// return an object using its id +Three.prototype.get = function( id ){ + + // find the element in the containers + var el = this.objects[id] || this.cameras[id] || this.scenes[id] || this.terrains[id] || null; + + return el; + +}; + + +find = function( query ){ + + // find the element in the containers + var el = this.fn.find.el.call(this, query); + // save element + this.last = el; + // preserve chainability + return this; + + }; + + +// Internal + +fn.find = { + el : function( query ){ + + var id = $(this.el).find("shadow-root "+ query).attr("data-id"); + // find the element in the containers + var el = this.objects[id] || this.cameras[id] || this.scenes[id] || this.terrains[id] || null; + + return el; + } +}; + + +// #39 Wildcard extension to the Three.js namespace +fn.three = function(fn, query ){ + var object = this.last; + try{ + object[fn]( query ); + } catch( e ){ + console.log("Method not supported:", e ); + } + return this; +}; + + +// internal constructor for Terrain +var Terrain = function( options ){ + // prerequisites? + + // reference to the options + this.options = options; + + // binding resolution across axis + var resX = options.resolution, + resY = options.resolution; + + // in both cases the geometry is Buffer + var plane = new THREE.PlaneBufferGeometry( options.width, options.height, resX, resY ); + + // update normals after images are loaded? + plane.computeFaceNormals(); + plane.computeVertexNormals(); + //plane.computeTangents( plane ); + //THREE.BufferGeometryUtils.computeTangents( plane ); + utils.computeTangents( plane ); + + // look if we're rendering using a shader + var material = ( options.shader ) ? this.shaderMaterial() : this.basicMaterial(); + + // exit now id we didn't generate a material? + + // generate mesh + var terrain = new THREE.Mesh( plane, material ); + // needsUpdate as attribute + //terrain.geometry.attributes.normal.needsUpdate = true; + + // save type as part of the mesh + terrain.type = "terrain"; + + // save attributes + terrain._attributes = options; + + // helper methods + if( options.shader ){ + terrain.updateTexture = this.shaderTexture.bind(terrain); + } else { + terrain.computeElevation = this.computeElevation.bind(terrain); + terrain.updateTexture = this.basicTexture.bind(terrain); + } + + // save reference + this.terrain = terrain; + + return this; +}; + + +Terrain.prototype.shaderMaterial = function(){ + // prerequisites + if( !THREE.ShaderTerrain ) + return console.log("THREE.ShaderTerrain not loaded. Use data-shader='false' to generate a poly terrain"); + + var options = this.options; + var terrainShader = THREE.ShaderTerrain.terrain; + + var uniformsTerrain = THREE.UniformsUtils.clone( terrainShader.uniforms ); + + /* these are all moved to the css styling... + var heightmapTexture = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); + var diffuseTexture1 = THREE.ImageUtils.loadTexture( "assets/img/terrain/diffuse.jpg" ); + var diffuseTexture2 = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); + var specularMap = THREE.ImageUtils.loadTexture( "assets/img/terrain/specular.png"); + + diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; + diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; + //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; + specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; + + //uniformsTerrain[ "tNormal" ].value = heightmapTexture; + //uniformsTerrain[ "uNormalScale" ].value = 1; + + uniformsTerrain[ "tDisplacement" ].value = heightmapTexture; + uniformsTerrain[ "uDisplacementScale" ].value = 375; + + uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture1; + uniformsTerrain[ "tDiffuse2" ].value = diffuseTexture2; + uniformsTerrain[ "tSpecular" ].value = specularMap; + //uniformsTerrain[ "tDetail" ].value = diffuseTexture1; + + uniformsTerrain[ "enableDiffuse1" ].value = true; + uniformsTerrain[ "enableDiffuse2" ].value = true; + uniformsTerrain[ "enableSpecular" ].value = true; + + uniformsTerrain[ "uDiffuseColor" ].value.setHex( 0xffffff ); + uniformsTerrain[ "uSpecularColor" ].value.setHex( 0xffffff ); + uniformsTerrain[ "uAmbientColor" ].value.setHex( 0x111111 ); + + //uniformsTerrain[ "uShininess" ].value = 30; + */ + + // allow the terrain to emit ambient light from the scene + if( THREE.REVISION < 70 ){ + uniformsTerrain.uDiffuseColor.value.setHex( 0xffffff ); + uniformsTerrain.uSpecularColor.value.setHex( 0xffffff ); + uniformsTerrain.uAmbientColor.value.setHex( 0x111111 ); + } else { + uniformsTerrain.diffuse.value.setHex( 0xffffff ); + uniformsTerrain.specular.value.setHex( 0xffffff ); + //uniformsTerrain.ambient.value.setHex( 0x111111 ); + } + + // this should also be accessible by a background-size value (with percentage conversion) + uniformsTerrain.uRepeatOverlay.value.set( options.repeat, options.repeat ); + // + + var material = new THREE.ShaderMaterial( { + uniforms : uniformsTerrain, + vertexShader : terrainShader.vertexShader, + fragmentShader : terrainShader.fragmentShader, + lights : options.lights, + fog : options.fog, + needsUpdate: true + }); + + return material; + +}; + +Terrain.prototype.basicMaterial = function(){ + + var material = new THREE.MeshBasicMaterial( { map: utils.pixel(), overdraw: 0.5 } ); + // + return material; +}; + +// Helpers + +// Terrain helper to compute elevation from heightmap +Terrain.prototype.computeElevation = function( texture ){ + // prerequisite + if( this._attributes.shader ) return; + var terrain = this; // method binded to terrain object + + // canvas for image processing + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext("2d"); + var img = texture.image; + // canvas takes the polygon dimensions | vertices = faces +1 for every side + var width = terrain.geometry.parameters.widthSegments + 1; + var height = terrain.geometry.parameters.heightSegments + 1; + var terrainScale = terrain._attributes.scale; //terrain.material.uniforms.uDisplacementScale.value; + var terrainBias = - terrain._attributes.scale/2; //terrain.material.uniforms.uDisplacementBias.value; + var size = terrain.geometry.parameters.width; // option? + //var scale = size / width; + // - main data + var vertices = terrain.geometry.attributes.position; + var d = []; + + canvas.width = width; + canvas.height = height; + + ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height); + // scale image to polygons + //ctx.scale(width/img.width, height/img.height); // already resized from drawImage + // loop through image data + var data = ctx.getImageData(0,0, width, height).data; + + for( var i in data ){ + if ( i % 4 ) continue; // pick only every forth - item size 4: RGBA + // OLD method: calculating the whole vector + //var z = ( Math.floor(i/width) ) - (size/2); + //var x = (i - ( Math.floor(i/width)*width)) - (size/2); + //var y = (data[i]/255 * terrainScale) + terrainBias; // normalize height to a fraction + //vertices.push( new THREE.Vector3(x, y, z) ); + //vertices.push( (data[i]/255 * terrainScale) + terrainBias ); + + // updating the z axis of the vertices directly + var z = ( (data[i]/255 * terrainScale) + terrainBias ); // terrain has z axis up... + // instead combine all colors? + //var decimal = (data[i]+data[i+1]+data[i+2])/(3*255); + d.push( z ); + vertices.setZ( i/4, z ); + } + + // update the vertices in the terrain object + terrain.geometry.attributes.position.needsUpdate = true; +}; + +Terrain.prototype.shaderTexture = function(type, img){ + + var texture = utils.textureLoader( img ); //this.webglTexture( img ); + + if( type == 'heightmap' ){ + var terrainScale = this._attributes.scale; // modified through an option + + this.material.uniforms.tDisplacement.value = texture; + this.material.uniforms.uDisplacementScale.value = terrainScale; + this.material.uniforms.uDisplacementBias.value = - terrainScale/2; + // heightmap also the second diffuse map? + //var diffuseTexture2 = texture; + //diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; + //this.material.uniforms.tDiffuse2.value = diffuseTexture2; + //this.material.uniforms.enableDiffuse2.value = true; + } + if( type == 'diffuse' ){ + + texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + + this.material.uniforms.tDiffuse1.value = texture; + this.material.uniforms.enableDiffuse1.value = true; + + } + if( type == 'specular' ){ + //var texture = this.webglTexture( img ); + //texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + + this.material.uniforms.tSpecular.value = texture; + this.material.uniforms.enableSpecular.value = true; + + } + // always update vertices... + // why don't these work with ShaderTerrain? + //this.geometry.attributes.position.needsUpdate = true; + //this.geometry.verticesNeedUpdate = true; + + /* + leftovers ( normal and detail textures) + + //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; + //uniformsTerrain[ "tNormal" ].value = heightmapTexture; + //uniformsTerrain[ "uNormalScale" ].value = 1; + //uniformsTerrain[ "tDetail" ].value = detailTexture; + //uniformsTerrain[ "uShininess" ].value = 30; + */ + + return texture; +}; + + +Terrain.prototype.basicTexture = function(type, img){ + var texture; + + if( type == 'heightmap' ){ + texture = utils.textureLoader( img, 'heightmap-loaded' ); + // texture isn't loaded in material, just used in computeElevation + // monitoring event + var self = this; + // remove pre-existing event... + var cb = function(e){ + self.computeElevation( texture ); + // trigger element event + self.$el.trigger('heightmap-updated'); + }; + document.removeEventListener('heightmap-loaded', cb); + document.addEventListener('heightmap-loaded', cb, false); + } + if( type == 'diffuse' ){ + texture = utils.textureLoader( img ); + var repeat = this._attributes.repeat; + // dirty re-write + texture.wrapT = THREE.RepeatWrapping; + texture.wrapS = THREE.RepeatWrapping; + texture.repeat.set( repeat, repeat ); + //texture.offset.set( 1, 1 ); + texture.needsUpdate = true; + + this.material.map = texture; + } + if( type == 'specular' ){ + // not supported? + } + + return texture; }; -Three.prototype.find = function( query ){ - - var id = $(this.container).find("shadow-root "+ query).attr("data-id"); - // find the element in the containers - var el = this.objects[id] || this.cameras[id] || this.scenes[id]; - - return el; - }; - // generic method to create an element -Three.prototype.webgl = function( options ){ +Three.prototype.webgl = function( options, callback ){ // get the type from the tag name //var type = html.nodeName.toLowerCase(); var el; - // + // switch( options.type ){ case "scene": el = this.webglScene( options ); @@ -1053,200 +2005,217 @@ Three.prototype.webgl = function( options ){ case "light": el = this.webglLight( options ); break; - case "plane": + case "plane": el = this.webglPlane( options ); break; - case "sphere": + case "sphere": el = this.webglSphere( options ); break; - case "cube": + case "cube": el = this.webglCube( options ); break; - case "cylinder": + case "cylinder": el = this.webglCylinder( options ); break; - case "terrain": + case "sprite": + el = this.webglSprite( options ); + break; + case "terrain": el = this.webglTerrain( options ); break; - default: + default: // a generic lookup in the internal methods... - el = (typeof this.fn.webgl[options.type] != "undefined" ) ? this.fn.webgl[options.type].apply(this, [options] ) : false; + if(typeof this.fn.webgl[options.type] != "undefined" ) this.fn.webgl[options.type].apply(this, [options, callback] ); break; } - - return el; - + + return callback(el); + }; - + // move all internal methods here... fn.webgl = { - + }; -Three.prototype.webglScene = function( options ){ - +Three.prototype.webglScene = function( attributes ){ + var defaults = { id : false }; - - var settings = $.extend(defaults, options); - + + var options = $.extend(defaults, attributes); + var scene = new THREE.Scene(); - - // save in the objects bucket + + // save in the objects bucket this.scenes[scene.id] = scene; - + + // save attributes + scene._attributes = options; + return scene; - + }; - + Three.prototype.webglCamera = function( attributes ){ - // + // var camera; - + var defaults = { - fov: 50, - aspect: this.properties.aspect, - near: 1, - far: 1000, + fov: 50, + aspect: this.properties.aspect, + near: 1, + far: 1000, scene: this.active.scene }; // use the active scene if not specified //var parent = scene || this.active.scene; var options = $.extend(defaults, attributes); - + if( options.orthographic){ // add orthographic camera - } else { + } else { camera = new THREE.PerspectiveCamera( options.fov, options.aspect, options.near, options.far ); } - + + // save attributes + camera._attributes = options; + return camera; }; - + Three.prototype.webglMesh = function( attributes ){ var mesh; var defaults = { - id : false, - wireframe: false, + id : false, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + //var material = new THREE.MeshBasicMaterial( { color: options.color } ); //var mash = new THREE.Mesh( geometry, material ); // wireframe toggle? new THREE.MeshBasicMaterial( {color: Math.random() * 0xffffff, wireframe: true }); - + return mesh; }; - + Three.prototype.webglMaterial = function( attributes ){ - + var material, settings; - + var defaults = { - id : false, - color: 0x000000, - wireframe: false, - map: false, + id : false, + color: 0x000000, + wireframe: false, + map: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); // grab the shaders from the global space var shaders = window.Shaders || {}; - + // check if there is a shader with the id name - if( options.id && shaders[ options.id ] ){ + if( options.id && shaders[ options.id ] ){ settings = {}; - + var shader = Shaders[ options.id ]; if( shader.uniforms ) settings.uniforms = THREE.UniformsUtils.clone(shader.uniforms); if( shader.vertexShader ) settings.vertexShader = shader.vertexShader; if( shader.fragmentShader ) settings.fragmentShader = shader.fragmentShader; - if( options.map && shader.uniforms) settings.uniforms.texture.texture= THREE.ImageUtils.loadTexture( options.map ); + if( options.map && shader.uniforms) settings.uniforms.texture.texture= utils.textureLoader( options.map ); material = new THREE.ShaderMaterial( settings ); - + } else { // create a basic material settings = {}; - if( options.map ) settings.map = THREE.ImageUtils.loadTexture( options.map ); + if( options.map ) settings.map = utils.textureLoader( options.map ); if( options.color && !options.map ) settings.color = options.color; if( options.wireframe ) settings.wireframe = options.wireframe; material = new THREE.MeshBasicMaterial( settings ); - + } - - return material; + + return material; }; - + Three.prototype.webglTexture = function( src ){ - + // texture - + var texture = new THREE.Texture(); - + var loader = new THREE.ImageLoader(); loader.addEventListener( 'load', function ( event ) { - + texture.image = event.content; texture.needsUpdate = true; - + } ); loader.load( src ); return texture; - + }; Three.prototype.webglLight = function( attributes ){ - //var light + + this.active.scene.add( new THREE.AmbientLight( parseInt( attributes.color, 16 ) ) ); + + //var light //return light; }; - + Three.prototype.webglPlane = function( attributes ){ // plane - by default a 1x1 square var defaults = { width: 1, height: 1, - color: 0x000000, - wireframe: false, + color: 0x000000, + wireframe: false, scene: this.active.scene }; - + var options = $.extend(defaults, attributes); - - var geometry = new THREE.PlaneGeometry( options.width, options.height ); + + var Constructor = ( options.buffer ) ? THREE.PlaneBufferGeometry : THREE.PlaneGeometry; + + var geometry = new Constructor( options.width, options.height ); // make this optional? geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; - + }; - + Three.prototype.webglSphere = function( attributes ){ - + var defaults = { - id : false, + id : false, radius : 1, segments : 16, - rings : 16, - color: 0x000000, - wireframe: false, - map: false, + rings : 16, + color: 0x000000, + wireframe: false, + map: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + var geometry = new THREE.SphereGeometry( options.radius, options.segments, options.rings); // make this optional? //geometry.overdraw = true; @@ -1256,154 +2225,149 @@ Three.prototype.webglSphere = function( attributes ){ mesh.matrixAutoUpdate = false; // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; }; - + Three.prototype.webglCube = function( attributes ){ - + var defaults = { - id : false, - width : 1, - height : 1, - depth : 1, - color: 0x000000, - wireframe: false, + id : false, + width : 1, + height : 1, + depth : 1, + color: 0x000000, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - - var geometry = new THREE.CubeGeometry( options.width, options.height, options.depth); + + var geometry = new THREE.BoxGeometry( options.width, options.height, options.depth); // make this optional? geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; }; - + Three.prototype.webglCylinder = function( attributes ){ - + var defaults = { - id : false, - radiusTop : 100, - radiusBottom : 100, - segmentsRadius : 400, - segmentsHeight : 50, - openEnded : false, - color: 0x000000, - wireframe: false, + id : false, + radiusTop : 1, + radiusBottom : 1, + segmentsRadius : 4, + segmentsHeight : 16, + openEnded : false, + color: 0x000000, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + var geometry = new THREE.CylinderGeometry( options.radiusTop, options.radiusBottom, options.segmentsRadius, options.segmentsHeight, options.openEnded, false); // make this optional? //geometry.overdraw = true; - geometry.dynamic = true; + geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; - - }; - -Three.prototype.webglTerrain = function( attributes ){ - // assuming that terrain is generated from a heightmap - support class="mesh" in the future? - var terrain; - + + }; + +Three.prototype.webglSprite = function( attributes ){ + + // sprite + + attributes = attributes || {}; + var defaults = { - + map : false, + color: 0xffffff, + fog: false, + transparent: true, + opacity: 1 + //alignment: THREE.SpriteAlignment.topLeft + //useScreenCoordinates: true + //scene: this.active.scene }; - - - this.active.scene.add( new THREE.AmbientLight( 0x111111 ) ); - directionalLight = new THREE.DirectionalLight( 0xffffff, 1.15 ); - directionalLight.position.set( 500, 2000, 0 ); - this.active.scene.add( directionalLight ); - - - var plane = new THREE.PlaneGeometry( 6000, 6000, 256, 256 ); + var options = $.extend(defaults, attributes); + // FIX map + if ( attributes.map ) { + options.map = utils.textureLoader( attributes.map ); + } else { + //placeholder pixel + options.map = utils.pixel(); + } + // save id (name) for later + var name = options.id; + // FIX: delete unsupported options (why not define the options supported?) + delete options.id; + delete options['class']; + delete options.el; + delete options.style; - plane.computeFaceNormals(); - plane.computeVertexNormals(); - plane.computeTangents(); + var material = new THREE.SpriteMaterial( options ); + material.scaleByViewport = true; + material.blending = THREE.AdditiveBlending; - // - - var terrainShader = THREE.ShaderTerrain.terrain; - - uniformsTerrain = THREE.UniformsUtils.clone( terrainShader.uniforms ); - /* - var heightmapTexture = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); - var diffuseTexture1 = THREE.ImageUtils.loadTexture( "assets/img/terrain/diffuse.jpg" ); - var diffuseTexture2 = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); - var specularMap = THREE.ImageUtils.loadTexture( "assets/img/terrain/specular.png"); - - diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; - diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; - //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; - specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; - - //uniformsTerrain[ "tNormal" ].value = heightmapTexture; - //uniformsTerrain[ "uNormalScale" ].value = 1; - - uniformsTerrain[ "tDisplacement" ].value = heightmapTexture; - uniformsTerrain[ "uDisplacementScale" ].value = 375; - - uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture1; - uniformsTerrain[ "tDiffuse2" ].value = diffuseTexture2; - uniformsTerrain[ "tSpecular" ].value = specularMap; - //uniformsTerrain[ "tDetail" ].value = diffuseTexture1; - - uniformsTerrain[ "enableDiffuse1" ].value = true; - uniformsTerrain[ "enableDiffuse2" ].value = true; - uniformsTerrain[ "enableSpecular" ].value = true; - - uniformsTerrain[ "uDiffuseColor" ].value.setHex( 0xffffff ); - uniformsTerrain[ "uSpecularColor" ].value.setHex( 0xffffff ); - uniformsTerrain[ "uAmbientColor" ].value.setHex( 0x111111 ); - - //uniformsTerrain[ "uShininess" ].value = 30; - - uniformsTerrain[ "uRepeatOverlay" ].value.set( 6, 6 ); - */ + var sprite = new THREE.Sprite( material ); + // save name (id) back to the object + sprite.name = name; - uniformsTerrain.uDiffuseColor.value.setHex( 0xffffff ); - uniformsTerrain.uSpecularColor.value.setHex( 0xffffff ); - uniformsTerrain.uAmbientColor.value.setHex( 0x111111 ); + // save attributes + sprite._attributes = options; - uniformsTerrain.uRepeatOverlay.value.set( 6, 6 ); - // + return sprite; - // fog is expensive - disable for now... - var material = new THREE.ShaderMaterial( { - uniforms : uniformsTerrain, - vertexShader : terrainShader.vertexShader, - fragmentShader : terrainShader.fragmentShader, - lights : true, - fog : false - }); + }; + +Three.prototype.webglTerrain = function( attributes ){ + // fallbacks + attributes = attributes || {}; + + var defaults = { + lights: true, + fog: true, + scale: 256, + width: 6000, + height: 6000, + resolution: 256, + shader: true, + repeat: 1 // diffuse map repeat + }; + + var options = $.extend(defaults, attributes); - terrain = new THREE.Mesh( plane, material ); + // logic contained + // assuming that terrain is generated from a heightmap - support class="mesh" in the future? + var terrain = (new Terrain( options )).terrain; - // save type as part of the mesh - terrain.type = "terrain"; - //terrain.visible=false; this.active.scene.add( terrain ); - + return terrain; - + }; Three.prototype.colorToHex = function (color) { @@ -1411,37 +2375,361 @@ Three.prototype.colorToHex = function (color) { return color.replace("#", "0x"); } var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color); - + var red = parseInt(digits[2], 10).toString(16); var green = parseInt(digits[3], 10).toString(16); var blue = parseInt(digits[4], 10).toString(16); - + // add leading zeros if necessary - + if(red.length == 1) red = "0"+red; if(green.length == 1) green = "0"+green; if(blue.length == 1) blue = "0"+blue; - + return '0x' + red + green + blue; }; - + Three.prototype.setProperties = function() { return { - width: $(this.container).width(), - height: $(this.container).height(), - aspect: ( $(this.container).width() / $(this.container).height() ) + width: $(this.el).width(), + height: $(this.el).height(), + aspect: ( $(this.el).width() / $(this.el).height() ) }; }; - + + +// internal object of utilities +var utils = { + // Convert Dashed to CamelCase + // based on: https://gist.github.com/tracend/5530356 + camelCase : function( string ){ + return string.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); + }, + + // Based on undercore _.delay + delay: function (fn, timeout) { + timeout = timeout || 0; + var args = Array.prototype.slice.call(arguments, 2); + return setTimeout(function () { return fn.apply(null, args); }, timeout); + }, + + // unique (but not universal) id generator + unid: function(){ + return Math.round( Math.random() * (new Date()).getTime() ); + }, + + now: function(){ + if( !performance || !performance.now ) return new Date().getTime(); + return Math.floor( performance.now() ); // are the fractions of a millisecond significant? + }, + // returns a 1x1 invisible texture + // used when we have no texture data + pixel: function(){ + var image = document.createElement( 'img' ); + var texture = new THREE.Texture( image ); + // not neeeded? + image.addEventListener( 'load', function ( event ) { + texture.needsUpdate = true; + } ); + image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; + return texture; + }, + // texture loader (support legacy) + textureLoader: function( image, eventName ){ + var map = this.pixel(); + + if( THREE.REVISION < 70 ){ + // FIX: support base64 images + if( image.search(";base64,") > -1 ) image = image.replace(/data:image\/(png|jpg|jpeg);base64,/, ""); + map = THREE.ImageUtils.loadTexture( image ); + } else { + (new THREE.TextureLoader()).load(image, function( texture ){ + // update image source on the original map + map.image = texture.image; + map.needsUpdate = true; + // trigger event + if( eventName ){ + var event = new Event(eventName); + document.dispatchEvent( event ); + } + }); + } + // return immediantely (update asychronously) + return map; + }, + + // Convert the color information of an image to height data + // source: http://oos.moxiecode.com/js_webgl/terrain/index.html + getHeightData: function(img) { + var canvas = document.createElement( 'canvas' ); + canvas.width = 128; + canvas.height = 128; + var context = canvas.getContext( '2d' ); + + var size = 128 * 128, data = new Float32Array( size ); + + context.drawImage(img,0,0); + + for ( var i = 0; i < size; i ++ ) { + data[i] = 0; + } + + var imgd = context.getImageData(0, 0, 128, 128); + var pix = imgd.data; + + var j=0; + for (var k = 0, n = pix.length; k < n; k += (4)) { + var all = pix[k]+pix[k+1]+pix[k+2]; + data[j++] = all/30; + } + + return data; + }, + + getFile: function (url) { + // if already downloaded return the same content + if( files[url] ) return files[url]; + files[url] = $.ajax({ + type : "GET", + url : url, + dataType : "string", + async : false, + success : function(data) { + files[url] = data; + } + }).responseText; + return files[url]; + }, + + //THREE.BufferGeometryUtils + // @author mrdoob / http://mrdoob.com/ + computeTangents: function ( geometry ) { + + var index = geometry.index; + var attributes = geometry.attributes; + + // based on http://www.terathon.com/code/tangent.html + // (per vertex tangents) + + if ( index === null || + attributes.position === undefined || + attributes.normal === undefined || + attributes.uv === undefined ) { + + console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + return; + + } + + var indices = index.array; + var positions = attributes.position.array; + var normals = attributes.normal.array; + var uvs = attributes.uv.array; + + var nVertices = positions.length / 3; + + if ( attributes.tangent === undefined ) { + + geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); + + } + + var tangents = attributes.tangent.array; + + var tan1 = [], tan2 = []; + + for ( var k = 0; k < nVertices; k ++ ) { + + tan1[ k ] = new THREE.Vector3(); + tan2[ k ] = new THREE.Vector3(); + + } + + var vA = new THREE.Vector3(), + vB = new THREE.Vector3(), + vC = new THREE.Vector3(), + + uvA = new THREE.Vector2(), + uvB = new THREE.Vector2(), + uvC = new THREE.Vector2(), + + sdir = new THREE.Vector3(), + tdir = new THREE.Vector3(); + + function handleTriangle( a, b, c ) { + + vA.fromArray( positions, a * 3 ); + vB.fromArray( positions, b * 3 ); + vC.fromArray( positions, c * 3 ); + + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); + + var x1 = vB.x - vA.x; + var x2 = vC.x - vA.x; + + var y1 = vB.y - vA.y; + var y2 = vC.y - vA.y; + + var z1 = vB.z - vA.z; + var z2 = vC.z - vA.z; + + var s1 = uvB.x - uvA.x; + var s2 = uvC.x - uvA.x; + + var t1 = uvB.y - uvA.y; + var t2 = uvC.y - uvA.y; + + var r = 1.0 / ( s1 * t2 - s2 * t1 ); + + sdir.set( + ( t2 * x1 - t1 * x2 ) * r, + ( t2 * y1 - t1 * y2 ) * r, + ( t2 * z1 - t1 * z2 ) * r + ); + + tdir.set( + ( s1 * x2 - s2 * x1 ) * r, + ( s1 * y2 - s2 * y1 ) * r, + ( s1 * z2 - s2 * z1 ) * r + ); + + tan1[ a ].add( sdir ); + tan1[ b ].add( sdir ); + tan1[ c ].add( sdir ); + + tan2[ a ].add( tdir ); + tan2[ b ].add( tdir ); + tan2[ c ].add( tdir ); + + } + + var groups = geometry.groups; + var group, start, count; + + if ( groups.length === 0 ) { + + groups = [ { + start: 0, + count: indices.length + } ]; + + } + + for ( var j = 0; j < groups.length; ++ j ) { + + group = groups[ j ]; + + start = group.start; + count = group.count; + + for ( var g = start, gl = start + count; g < gl; g += 3 ) { + + handleTriangle( + indices[ g + 0 ], + indices[ g + 1 ], + indices[ g + 2 ] + ); + + } + + } + + var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(); + var n = new THREE.Vector3(), n2 = new THREE.Vector3(); + var w, t, test; + + function handleVertex( v ) { + + n.fromArray( normals, v * 3 ); + n2.copy( n ); + + t = tan1[ v ]; + + // Gram-Schmidt orthogonalize + + tmp.copy( t ); + tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + + // Calculate handedness + + tmp2.crossVectors( n2, t ); + test = tmp2.dot( tan2[ v ] ); + w = ( test < 0.0 ) ? - 1.0 : 1.0; + + tangents[ v * 4 ] = tmp.x; + tangents[ v * 4 + 1 ] = tmp.y; + tangents[ v * 4 + 2 ] = tmp.z; + tangents[ v * 4 + 3 ] = w; + + } + + for ( var l = 0; l < groups.length; ++ l ) { + + group = groups[ l ]; + + start = group.start; + count = group.count; + + for ( var i = start, il = start + count; i < il; i += 3 ) { + + handleVertex( indices[ i + 0 ] ); + handleVertex( indices[ i + 1 ] ); + handleVertex( indices[ i + 2 ] ); + + } + + } + + } + +}; + + +/** + * jQuery.toSelector - get the selector text of a jQuery object + * https://gist.github.com/tracend/6402299 + * + * Created by Makis Tracend ( @tracend ) + * Released under the MIT license + * http://makesites.org/licenses/MIT + */ +(function( $ ) { + + $.fn.toSelector = function() { + + var node = $(this).get(0); + var tag = node.tagName.toLowerCase(); + var id = $(this).attr("id"); + var classes = node.className.split(/\s+/); + + var selector = tag; + if(typeof id !== "undefined"){ + selector += "#"+id; + } + if(typeof classes !== "undefined"){ + selector += "."+classes.join("."); + } + + return selector; + }; + +}( jQuery )); + + // Prototype Three.prototype.css = css; +Three.prototype.find = find; Three.prototype.fn = fn; //Three.prototype.fn.webgl = fn.webgl; - //Three.prototype.utils = utils; -//Three.prototype.cssSet = cssSet; -//Three.prototype.cssSkybox = cssSkybox; +// #39 Wildcard extension - replace this hardcoding list with a proper wildcard method, once available (Proxy) +//Three.prototype.__noSuchMethod__ = fn.three; +Three.prototype.lookAt = function(){ + return this.fn.three.call(this, "lookAt", arguments); +}; -})); \ No newline at end of file +})); diff --git a/component.json b/component.json index 0cfcf41..1bc1532 100644 --- a/component.json +++ b/component.json @@ -1,8 +1,8 @@ { - "name": "jQuery Three", - "version": "0.6.0", + "name": "jquery-three", + "version": "0.9.8", "main": ["./build/jquery.three-min.js"], "dependencies": { - "jquery": "~1.8.2" + "jquery": "~2.0.3" } } diff --git a/examples/assets/3d/dreampalm/palm.mtl b/examples/assets/3d/dreampalm/palm.mtl deleted file mode 100644 index b824bca..0000000 --- a/examples/assets/3d/dreampalm/palm.mtl +++ /dev/null @@ -1,31 +0,0 @@ -newmtl trunk -ka 0.117647 0.117647 0.117647 -kd 1 1 1 -ks 1 1 1 -illum 2 -ns 8 -map_kd palm_bark.JPG -map_bump -bump -map_opacity -map_d -refl -map_ks -map_ka -map_ns - -newmtl branches -ka 0.117647 0.117647 0.117647 -kd 1 1 1 -ks 1 1 1 -illum 2 -ns 8 -map_kd palm_leafs.JPG -map_bump -bump -map_opacity -map_d -refl -map_ks -map_ka -map_ns diff --git a/examples/assets/3d/dreampalm/palm.obj b/examples/assets/3d/dreampalm/palm.obj deleted file mode 100644 index 533117d..0000000 --- a/examples/assets/3d/dreampalm/palm.obj +++ /dev/null @@ -1,1588 +0,0 @@ -# -# Wavefront OBJ file -# Converted by the DEEP Exploration Deep Exploration 5.5 5.5.4.2708 Release -# Right Hemisphere, LTD -# http://www.righthemisphere.com/ -# -mtllib palm.mtl -# object trunk -g trunk -v -8.74182 -3.19179 -4.95403 -v -11.68221 -3.19179 -4.95403 -v -12.59086 -3.19179 -2.15752 -v -10.21204 -3.19179 -0.42922 -v -7.83320 -3.19179 -2.15752 -v -10.21204 80.53148 -2.93047 -v -11.58909 6.56042 -4.82582 -v -8.83495 6.56042 -4.82582 -v -7.98390 6.56045 -2.20649 -v -10.21204 6.56045 -0.58765 -v -12.44017 6.56045 -2.20649 -v -11.43121 23.09310 -4.60851 -v -8.99282 23.09310 -4.60851 -v -8.23934 23.09310 -2.28949 -v -10.21204 23.09310 -0.85625 -v -12.18472 23.09310 -2.28949 -v -11.27573 39.37548 -4.39451 -v -9.14831 39.37548 -4.39451 -v -8.49092 39.37548 -2.37123 -v -10.21204 39.37548 -1.12079 -v -11.93314 39.37548 -2.37123 -v -11.11975 55.70899 -4.17982 -v -9.30432 55.70899 -4.17982 -v -8.74332 55.70899 -2.45323 -v -10.21204 55.70899 -1.38616 -v -11.68077 55.70899 -2.45323 -v -11.01142 70.82254 -4.03070 -v -9.41267 70.82251 -4.03070 -v -8.91861 70.82251 -2.51020 -v -10.21204 70.82254 -1.57046 -v -11.50546 70.82251 -2.51020 -v -11.39955 79.11594 -2.54462 -v -10.94596 79.11594 -3.94060 -v -9.47813 79.11594 -3.94060 -v -9.02454 79.11594 -2.54462 -v -10.21204 79.11594 -1.68184 -v -10.90572 79.95095 -2.70508 -v -10.64075 79.95095 -3.52052 -v -9.78334 79.95095 -3.52052 -v -9.51837 79.95095 -2.70508 -v -10.21204 79.95095 -2.20107 -# 41 verticies -vt 0.00882 0.00248 -vt 0.20816 0.00248 -vt 0.20837 0.25885 -vt 0.00960 0.25885 -vt 0.40766 0.00248 -vt 0.40730 0.25885 -vt 0.60721 0.00248 -vt 0.60629 0.25885 -vt 0.80675 0.00248 -vt 0.80525 0.25885 -vt 0.99610 0.00248 -vt 0.99417 0.25885 -vt 0.20874 0.69230 -vt 0.01093 0.69230 -vt 0.99090 0.69230 -vt 0.80271 0.69230 -vt 0.60471 0.69230 -vt 0.40669 0.69230 -vt 0.20874 0.25885 -vt 0.40669 0.25885 -vt 0.40610 0.69230 -vt 0.20909 0.69230 -vt 0.01093 0.25885 -vt 0.01224 0.69230 -vt 0.80271 0.25885 -vt 0.99090 0.25885 -vt 0.98769 0.69230 -vt 0.80021 0.69230 -vt 0.60471 0.25885 -vt 0.60316 0.69230 -vt 0.20909 0.25885 -vt 0.40610 0.25885 -vt 0.40550 0.69230 -vt 0.20945 0.69230 -vt 0.01224 0.25885 -vt 0.01355 0.69230 -vt 0.80021 0.25885 -vt 0.98769 0.25885 -vt 0.98446 0.69230 -vt 0.79770 0.69230 -vt 0.60316 0.25885 -vt 0.60161 0.69230 -vt 0.20945 0.25885 -vt 0.40550 0.25885 -vt 0.40508 0.69230 -vt 0.20969 0.69230 -vt 0.01355 0.25885 -vt 0.01446 0.69230 -vt 0.79770 0.25885 -vt 0.98446 0.25885 -vt 0.98222 0.69230 -vt 0.79596 0.69230 -vt 0.60161 0.25885 -vt 0.60053 0.69230 -vt 0.40483 0.95418 -vt 0.20985 0.95418 -vt 0.01501 0.95418 -vt 0.98087 0.95418 -vt 0.79491 0.95418 -vt 0.59988 0.95418 -vt 0.59981 0.98055 -vt 0.40481 0.98055 -vt 0.20986 0.98055 -vt 0.01506 0.98055 -vt 0.98073 0.98055 -vt 0.79480 0.98055 -vt 0.50228 0.99888 -vt 0.30732 0.99888 -vt 0.11246 0.99888 -vt 0.89217 0.99888 -vt 0.69726 0.99888 -# 71 texture verticies -vn 0.58771 0.01624 -0.80891 -vn -0.58771 0.01624 -0.80891 -vn -0.95093 0.01624 0.30898 -vn 0.00000 0.01624 0.99987 -vn 0.95093 0.01624 0.30898 -vn -0.95096 0.01422 0.30899 -vn -0.58773 0.01422 -0.80893 -vn 0.58773 0.01422 -0.80893 -vn 0.95096 0.01422 0.30899 -vn 0.00000 0.01422 0.99990 -vn -0.95098 0.01281 0.30899 -vn -0.58774 0.01281 -0.80895 -vn 0.58774 0.01281 -0.80895 -vn 0.95098 0.01281 0.30899 -vn 0.00000 0.01281 0.99992 -vn -0.91082 0.28780 0.29594 -vn -0.56292 0.28780 -0.77479 -vn 0.56292 0.28780 -0.77479 -vn 0.91082 0.28780 0.29594 -vn 0.00000 0.28780 0.95769 -vn 0.00000 0.66934 0.74296 -vn -0.70659 0.66934 0.22959 -vn -0.43670 0.66934 -0.60106 -vn 0.43670 0.66934 -0.60107 -vn 0.70659 0.66934 0.22959 -vn 0.00000 1.00000 0.00000 -# 26 normals -usemtl trunk -f 1/1/1 2/2/2 7/3/2 8/4/1 -f 2/2/2 3/5/3 11/6/3 7/3/2 -f 3/5/3 4/7/4 10/8/4 11/6/3 -f 4/7/4 5/9/5 9/10/5 10/8/4 -f 5/9/5 1/11/1 8/12/1 9/10/5 -f 8/4/1 7/3/2 12/13/2 13/14/1 -f 9/10/5 8/12/1 13/15/1 14/16/5 -f 10/8/4 9/10/5 14/16/5 15/17/4 -f 11/6/3 10/8/4 15/17/4 16/18/3 -f 7/3/2 11/6/3 16/18/3 12/13/2 -f 12/19/2 16/20/3 21/21/3 17/22/2 -f 13/23/1 12/19/2 17/22/2 18/24/1 -f 14/25/5 13/26/1 18/27/1 19/28/5 -f 15/29/4 14/25/5 19/28/5 20/30/4 -f 16/20/3 15/29/4 20/30/4 21/21/3 -f 17/31/2 21/32/3 26/33/6 22/34/7 -f 18/35/1 17/31/2 22/34/7 23/36/8 -f 19/37/5 18/38/1 23/39/8 24/40/9 -f 20/41/4 19/37/5 24/40/9 25/42/10 -f 21/32/3 20/41/4 25/42/10 26/33/6 -f 22/43/7 26/44/6 31/45/11 27/46/12 -f 23/47/8 22/43/7 27/46/12 28/48/13 -f 24/49/9 23/50/8 28/51/13 29/52/14 -f 25/53/10 24/49/9 29/52/14 30/54/15 -f 26/44/6 25/53/10 30/54/15 31/45/11 -f 27/46/12 31/45/11 32/55/16 33/56/17 -f 28/48/13 27/46/12 33/56/17 34/57/18 -f 29/52/14 28/51/13 34/58/18 35/59/19 -f 30/54/15 29/52/14 35/59/19 36/60/20 -f 31/45/11 30/54/15 36/60/20 32/55/16 -f 32/55/16 36/60/20 41/61/21 37/62/22 -f 33/56/17 32/55/16 37/62/22 38/63/23 -f 34/57/18 33/56/17 38/63/23 39/64/24 -f 35/59/19 34/58/18 39/65/24 40/66/25 -f 36/60/20 35/59/19 40/66/25 41/61/21 -f 37/62/22 41/61/21 6/67/26 -f 38/63/23 37/62/22 6/68/26 -f 39/64/24 38/63/23 6/69/26 -f 40/66/25 39/65/24 6/70/26 -f 41/61/21 40/66/25 6/71/26 -# object branches -g branches -v -11.05663 77.74021 -2.10114 -v -11.26176 77.74021 -3.47744 -v -10.01621 77.74021 -4.09785 -v -9.04127 77.74021 -3.10496 -v -9.68429 77.74021 -1.87091 -v -9.23841 75.59010 -0.97575 -v -11.77021 75.59010 -1.40044 -v -12.14866 75.59010 -3.93958 -v -9.85076 75.59010 -5.08413 -v -8.05212 75.59010 -3.25240 -v -10.83597 75.93787 -4.03160 -v -9.35760 75.93785 -3.86412 -v -9.06002 75.93785 -2.40637 -v -10.35448 75.93785 -1.67287 -v -11.45209 75.93787 -2.67733 -v -12.77567 73.63890 -2.40713 -v -11.50195 73.63890 -5.20690 -v -8.44564 73.63890 -4.86069 -v -7.83038 73.63890 -1.84698 -v -10.50652 73.63890 -0.33060 -v -10.83439 74.31125 -4.02879 -v -9.35978 74.31125 -3.86176 -v -9.06296 74.31125 -2.40771 -v -10.35411 74.31125 -1.67608 -v -11.44891 74.31125 -2.67796 -v -13.33074 71.17724 -2.29380 -v -11.78126 71.17724 -5.69980 -v -8.06316 71.17724 -5.27864 -v -7.31473 71.17724 -1.61238 -v -10.57029 71.17724 0.23234 -v -11.33779 72.94446 -2.56466 -v -10.90780 72.94446 -3.88808 -v -9.51626 72.94446 -3.88808 -v -9.08626 72.94446 -2.56466 -v -10.21204 72.94446 -1.74675 -v -10.21204 70.79429 -0.93680 -v -12.10811 70.79429 -2.31437 -v -11.38387 70.79429 -4.54336 -v -9.04019 70.79429 -4.54336 -v -8.31593 70.79429 -2.31437 -v -9.11367 80.43781 -8.40148 -v -10.41826 80.10879 -2.29146 -v -8.04930 79.71304 1.76858 -v 4.51683 105.92171 -2.48684 -v 0.37867 99.75526 2.31485 -v -1.41593 101.47883 -2.07057 -v -0.68567 100.48005 -7.85521 -v -4.34154 93.96910 2.39651 -v -5.40588 94.69389 -7.77355 -v -7.91483 91.56149 -1.91627 -v -8.10608 87.81622 -7.98110 -v -7.04174 87.09143 2.18895 -v -11.98434 77.51724 -9.10888 -v -10.45024 79.35303 -2.18030 -v -6.92884 77.79002 1.78223 -v 15.85508 75.23794 -14.89268 -v 12.95666 79.67103 -7.49546 -v 11.44113 81.37733 -12.85399 -v 7.90118 79.39826 -18.38657 -v 6.60249 83.02436 -4.62991 -v 1.54695 82.75159 -15.52102 -v 0.52206 84.59418 -7.63416 -v -5.62169 81.81547 -12.16999 -v -0.56619 82.08826 -1.27888 -v -17.02436 78.03161 -5.03824 -v -10.44911 79.59388 -2.20034 -v -5.18215 78.14430 -3.03877 -v -6.07297 78.77526 -31.36686 -v -1.62672 82.46600 -24.33968 -v -6.91461 84.33246 -25.91336 -v -13.46893 82.35331 -26.33915 -v -2.86593 85.02013 -17.14436 -v -14.70811 84.90747 -19.14384 -v -8.78627 86.17479 -13.66906 -v -15.98310 83.09277 -11.49033 -v -4.14090 83.20547 -9.49081 -v -10.81806 77.63146 4.93402 -v -10.44750 79.35308 -2.18124 -v -12.69193 77.63146 -6.92923 -v -39.08638 74.40070 2.89772 -v -34.41140 78.87335 -3.49851 -v -34.48272 80.67763 2.03878 -v -32.53751 78.87335 8.36474 -v -27.62609 82.42902 -4.57029 -v -25.75223 82.42902 7.29295 -v -22.65945 84.24153 -0.04170 -v -17.91231 81.72346 6.05461 -v -19.78623 81.72346 -5.80863 -v -3.68979 77.50339 -4.32905 -v -10.45000 79.35324 -2.18279 -v -14.26733 77.50339 1.35988 -v 3.53422 71.75230 22.66019 -v -3.84187 76.72159 20.74406 -v 1.48446 78.43244 19.12390 -v 6.73569 76.72159 15.05510 -v -6.92739 80.89281 15.00713 -v 3.65018 80.89284 9.31815 -v -4.20728 83.08314 8.98512 -v -0.12423 80.91883 2.30043 -v -10.70176 80.91881 7.98937 -v -10.60846 79.90497 1.23941 -v -6.86051 79.97896 -6.80915 -v -10.48453 80.20817 -2.78929 -v 5.14176 93.45529 4.20633 -v -8.26459 86.71403 -1.80671 -v -2.43025 91.49276 5.15420 -v 1.31765 91.56674 -2.89436 -v -8.62495 85.88551 2.21804 -v -4.87702 85.95950 -5.83051 -v -1.37437 92.90131 1.29285 -v -13.98663 80.00150 -4.80289 -v -8.70345 80.36693 2.32350 -v -10.48842 80.20848 -2.78860 -v -22.83237 95.65346 6.02545 -v -11.81802 86.98116 -2.02487 -v -20.25218 92.70101 -0.80912 -v -14.96897 93.06645 6.31727 -v -15.24785 86.22156 -4.18684 -v -9.96464 86.58700 2.93954 -v -17.24301 94.13455 1.81742 -v -6.59875 80.34489 -4.54704 -v -15.95678 80.84172 -4.33749 -v -10.48666 80.20905 -2.79334 -v -10.09485 99.81196 -14.53510 -v -10.20166 87.53377 -2.68154 -v -5.90981 95.20588 -9.01531 -v -15.26786 95.70271 -8.80575 -v -6.23921 87.06605 -4.42649 -v -15.59727 87.56287 -4.21693 -v -9.99668 96.51910 -7.73255 -v -3.41593 78.63473 -0.24334 -v -10.44784 79.35353 -2.18343 -v -15.16517 76.53673 -1.58572 -v -11.26426 69.32049 25.55064 -v -17.14397 73.70178 20.16502 -v -12.22412 76.22914 21.98966 -v -5.39473 75.79981 21.50738 -v -17.28167 78.40235 14.02356 -v -5.53244 80.50040 15.36594 -v -12.16268 81.84328 10.79603 -v -4.76883 81.27479 7.47208 -v -16.51807 79.17680 6.12973 -v -3.62709 76.47528 -1.23117 -v -10.44834 78.98860 -2.17059 -v -15.48086 76.90851 -3.11501 -v -13.17132 53.71509 12.64775 -v -18.17725 61.08748 10.21307 -v -13.06983 61.53149 12.97697 -v -6.32350 60.65422 12.09693 -v -17.59756 68.39125 8.24513 -v -5.74381 67.95802 10.12896 -v -12.11844 72.99809 8.28681 -v -4.84470 74.12721 5.89032 -v -16.69846 74.56046 4.00646 -v -14.71226 76.47528 3.24138 -v -10.44516 78.98860 -2.16265 -v -7.08030 76.90851 -6.02219 -v -21.83902 53.71509 -12.02053 -v -17.20296 61.08748 -15.10186 -v -22.17426 61.53149 -12.09993 -v -24.83495 60.65419 -5.83827 -v -15.80035 68.39125 -13.60471 -v -23.43233 67.95802 -4.34112 -v -18.61332 72.99809 -8.90259 -v -20.23419 74.12721 -1.41772 -v -12.60220 74.56046 -10.68128 -v -12.94932 76.47528 -8.58134 -v -10.45363 78.98860 -2.16391 -v -8.83198 76.90851 2.69288 -v 3.81918 53.71509 -6.98945 -v 4.12565 61.08748 -1.43128 -v 4.05750 61.53149 -7.23820 -v 0.00827 60.65422 -12.70553 -v 2.12415 68.39125 -0.98101 -v -1.99323 67.95802 -12.25522 -v -0.50352 72.99809 -5.78912 -v -6.13427 74.12721 -10.97999 -v -2.01692 74.56046 0.29425 -v -10.21204 78.39401 -2.89509 -v -5.26171 48.18827 -2.73619 -v -4.42912 52.53621 -2.75786 -v -7.61212 76.93153 -2.87997 -v -5.69444 52.96737 0.97144 -v -6.74019 72.16529 0.94606 -v -10.21204 77.05724 0.93604 -v -5.77671 52.99540 -6.22879 -v -6.81012 72.11992 -6.24944 -v -10.21204 76.97034 -6.25756 -v -8.07379 75.73182 0.93993 -v -8.10377 75.65381 -6.25441 -v -5.66441 72.86312 -2.85627 -v -10.21204 78.39401 -2.89509 -v -11.33979 48.18827 -7.71785 -v -11.57622 52.53621 -8.51648 -v -10.87034 76.93153 -5.41030 -v -7.64647 52.96737 -8.25946 -v -7.40033 72.16529 -7.24280 -v -6.51143 77.05724 -3.88664 -v -14.58008 52.99540 -6.31645 -v -14.33255 72.11992 -5.31289 -v -13.45996 76.97034 -2.02481 -v -7.06109 75.73182 -5.95304 -v -14.00254 75.65381 -4.06203 -v -11.35155 72.86312 -7.29782 -v -10.21204 78.39401 -2.89509 -v -14.57858 48.18827 -0.55754 -v -15.28877 52.53621 -0.12246 -v -12.47115 76.93153 -1.60820 -v -16.05761 52.96737 -3.98479 -v -15.13929 72.16529 -4.48569 -v -12.12759 77.05724 -6.21294 -v -12.38628 52.99540 2.20965 -v -11.48100 72.11992 1.71082 -v -8.53077 76.97034 0.01692 -v -13.98132 75.73182 -5.14717 -v -10.35816 75.65381 1.06830 -v -14.16978 72.86312 -0.65490 -v -10.44903 79.77632 -3.62446 -v 24.50405 64.78104 -3.11306 -v -10.12760 77.01504 -9.58943 -v -10.12760 77.01504 3.53948 -v 4.06179 78.82862 -3.43684 -v -1.55534 77.31634 -9.58943 -v -1.55534 77.31637 3.53948 -v 8.37491 75.02855 -9.58943 -v 8.37491 75.02855 3.53948 -v 18.61311 71.49373 -3.22649 -v 16.75584 69.44512 -9.58943 -v 16.75584 69.44512 3.53948 -v -10.38275 79.69398 -2.99172 -v 9.66596 89.74811 -18.75913 -v -11.84035 79.13151 -8.50859 -v -4.61295 79.13148 0.35798 -v -4.92321 89.81444 -7.23102 -v -9.59605 85.53781 -10.33799 -v -2.36865 85.53781 -1.47142 -v -4.71765 90.59598 -14.31453 -v 2.50975 90.59598 -5.44793 -v 4.66857 92.82192 -14.81317 -v 1.24351 90.76253 -19.17366 -v 8.47093 90.76253 -10.30709 -v -10.38391 79.69290 -2.99219 -v -18.32011 91.23226 -31.17001 -v -16.87472 79.04730 -3.86447 -v -4.30157 79.04730 -7.64395 -v -12.48737 91.30843 -10.64154 -v -17.83139 86.40004 -7.04697 -v -5.25824 86.40004 -10.82645 -v -19.91086 92.20540 -13.96475 -v -7.33769 92.20540 -17.74420 -v -16.32519 94.76021 -24.13948 -v -22.45190 92.39657 -22.41788 -v -9.87872 92.39657 -26.19736 -v -10.38275 79.45189 -2.97089 -v -41.32091 83.91205 -6.58549 -v -13.44662 78.19869 2.71689 -v -12.13738 78.19869 -10.34657 -v -20.71376 88.91924 -4.19482 -v -18.35498 84.58398 2.22495 -v -17.04576 84.58398 -10.83850 -v -26.68326 88.56215 1.39031 -v -25.37401 88.56215 -11.67319 -v -35.06999 89.03370 -5.84500 -v -35.27212 86.70753 0.52953 -v -33.96289 86.70753 -12.53395 -v -10.38278 79.69298 -2.99251 -v -25.67569 81.06716 24.47323 -v -6.23248 78.20169 1.89216 -v -17.80556 78.20169 -4.30724 -v -15.87573 88.09097 6.86440 -v -8.84715 84.07065 6.77325 -v -20.42026 84.07065 0.57382 -v -12.96508 87.20599 14.46055 -v -24.53815 87.20599 8.26109 -v -22.85625 86.78320 19.45012 -v -16.93507 84.51105 21.87173 -v -28.50815 84.51105 15.67233 -v -10.38433 79.69290 -2.99200 -v 9.09273 82.58592 21.55190 -v -4.24081 78.31685 -4.90835 -v -14.39043 78.31685 3.41953 -v -3.63871 88.62683 5.52499 -v -0.91261 84.44678 -0.85212 -v -11.06226 84.44678 7.47579 -v 4.51643 88.00030 5.76453 -v -5.63322 88.00030 14.09243 -v 5.35620 88.01668 16.81914 -v 9.92593 85.71520 12.35737 -v -0.22374 85.71520 20.68525 -v -10.38625 79.45452 -2.96728 -v 5.78933 69.27960 -24.34362 -v -13.84824 77.37615 -7.03819 -v -4.61298 77.37615 -0.28825 -v -3.13302 81.58288 -12.61416 -v -9.95018 79.78129 -12.37152 -v -0.71491 79.78129 -5.62162 -v -5.22000 78.81336 -18.84339 -v 4.01524 78.81336 -12.09343 -v 3.65394 75.26327 -21.58948 -v -1.64994 73.75260 -23.72795 -v 7.58538 73.75260 -16.97804 -v -10.38746 79.08742 -2.95808 -v 12.18477 68.91248 11.50196 -v -6.59878 77.00903 -6.72688 -v -12.60827 77.00903 3.00645 -v -0.20454 81.21575 3.52107 -v -0.97780 79.41417 -3.25642 -v -6.98728 79.41417 6.47690 -v 5.84311 78.44620 0.95487 -v -0.16644 78.44620 10.68822 -v 9.27257 74.89615 9.58774 -v 10.99111 73.38548 4.13333 -v 4.98162 73.38545 13.86668 -v -10.38012 79.08742 -2.95868 -v -30.80250 68.91248 14.40571 -v -7.88225 77.00903 1.76555 -v -15.43589 77.00903 -6.82482 -v -19.55100 81.21572 4.88773 -v -12.84318 79.41417 6.12775 -v -20.39685 79.41417 -2.46260 -v -18.86306 78.44620 11.42116 -v -26.41674 78.44620 2.83079 -v -28.12118 74.89615 12.17959 -v -23.40659 73.38548 15.41633 -v -30.96022 73.38545 6.82595 -v -10.38018 79.08742 -2.95258 -v -29.90984 68.91248 -21.31531 -v -14.79703 77.00903 0.05559 -v -7.10081 77.00903 -8.40729 -v -19.19862 81.21572 -11.19315 -v -19.68432 79.41417 -4.38896 -v -11.98810 79.41417 -12.85183 -v -25.61489 78.44620 -9.78228 -v -17.91865 78.44623 -18.24513 -v -27.39910 74.89615 -18.89843 -v -30.09093 73.38548 -13.85285 -v -22.39474 73.38545 -22.31569 -v -13.94389 81.89546 -8.34133 -v -10.75563 79.18687 -2.68627 -v -7.56074 76.47060 0.26535 -v 18.08783 78.57141 -7.49491 -v 11.53546 79.41725 -2.11762 -v 14.44077 82.88506 -5.49890 -v 14.40379 87.31975 -10.65513 -v 6.09564 81.89030 -0.66531 -v 6.03060 90.30315 -9.23667 -v 2.39890 85.56259 -3.41956 -v -4.50957 88.46229 -8.51762 -v -1.09321 80.89403 0.07931 -v -5.96901 84.04305 -0.95795 -v -10.75563 79.18687 -2.68627 -v -13.11209 74.67113 -3.28014 -v -12.75513 59.73576 19.06470 -v -16.41584 64.10811 12.73656 -v -15.34132 65.06978 18.19734 -v -12.36734 68.96122 22.91608 -v -17.41462 69.40550 9.77726 -v -12.86132 76.62742 18.22472 -v -15.48089 74.92661 10.49518 -v -10.42160 82.38032 9.50964 -v -16.07644 73.48321 3.87746 -v -13.62152 82.98376 1.05449 -v -10.75563 79.18687 -2.68627 -v -9.99257 76.17702 -5.82036 -v -21.44165 80.57317 -25.42474 -v -15.48481 79.57203 -21.27486 -v -17.79927 83.41570 -23.14028 -v -20.52369 88.51360 -22.23264 -v -12.37074 81.05634 -17.26374 -v -16.60054 90.37240 -15.81994 -v -12.58876 84.77310 -13.82152 -v -14.09346 88.50004 -7.14094 -v -10.38914 79.91440 -11.41872 -v -11.41969 74.17125 0.43367 -v -9.95504 74.17125 -1.40291 -v -11.70722 72.93552 0.79423 -v -11.70722 72.93552 -1.66780 -v -9.63590 72.93552 -1.80311 -v -9.30692 72.93552 0.24639 -v -11.41969 71.69978 0.43367 -v -11.41969 71.69978 -1.30723 -v -9.95504 71.69978 -1.40291 -v -9.72242 71.69978 0.04628 -v -10.72552 74.68313 -0.43680 -v -10.72552 71.18792 -0.43680 -v -8.30409 75.35542 -0.36239 -v -7.56989 74.32461 -2.34143 -v -8.13975 74.54718 0.66694 -v -8.94506 73.13096 -1.17894 -v -7.10146 73.08943 -2.13188 -v -6.13122 74.27412 -0.73053 -v -7.68716 73.33425 0.91921 -v -8.25662 72.33281 -0.38604 -v -6.95298 72.30344 -1.05986 -v -6.26693 73.14116 -0.06894 -v -8.08386 75.28546 -1.56578 -v -7.21143 72.42710 0.24665 -v -10.05874 76.53522 1.07535 -v -9.32457 75.50441 -0.90369 -v -9.89443 75.72701 2.10466 -v -10.69974 74.31076 0.25880 -v -8.85614 74.26922 -0.69414 -v -7.88590 75.45392 0.70721 -v -9.44186 74.51404 2.35695 -v -10.01130 73.51261 1.05171 -v -8.70768 73.48327 0.37788 -v -8.02158 74.32096 1.36880 -v -9.83853 76.46526 -0.12804 -v -8.96613 73.60690 1.68439 -v -11.50827 76.65575 -0.79205 -v -9.64321 75.32249 -0.27995 -v -12.62497 75.98267 -0.59288 -v -11.05484 74.39134 -1.62440 -v -9.98739 74.09717 0.13133 -v -11.13855 75.38901 1.27788 -v -13.00936 74.78608 -0.19266 -v -11.89913 73.66086 -0.92205 -v -11.14431 73.45286 0.31945 -v -11.95833 74.36632 1.13016 -v -10.31343 76.41105 -0.67349 -v -12.43632 73.76698 0.17419 -v -7.26605 78.10896 -1.40938 -v -8.94688 76.47087 -1.31060 -v -6.31075 77.84249 -0.53984 -v -8.42733 77.32295 0.60546 -v -8.68775 75.52587 -0.40016 -v -6.94869 75.67746 -1.52328 -v -6.01535 76.93286 0.36847 -v -7.51200 76.56548 1.17831 -v -7.69615 75.29475 0.46723 -v -6.46646 75.40195 -0.32694 -v -8.32168 77.57616 -1.73076 -v -6.55293 75.91289 0.78348 -v -10.48845 78.86225 -0.28447 -v -9.85976 77.20328 -1.82420 -v -9.98650 78.59989 0.90672 -v -10.72999 76.43578 -0.00185 -v -9.09742 76.25373 -1.27081 -v -8.21270 78.04518 -0.70808 -v -9.23775 77.68614 1.49335 -v -9.76345 76.15590 0.85091 -v -8.60903 76.02716 -0.04638 -v -7.98347 77.29391 0.35153 -v -10.44950 78.31956 -1.38242 -v -8.68073 76.65630 1.13179 -v -10.88037 72.83527 -1.53919 -v -9.10554 72.81712 -3.07801 -v -10.63794 72.00218 -0.54575 -v -9.87107 70.85765 -2.58626 -v -8.12796 71.97654 -2.72196 -v -8.49618 73.11696 -1.02714 -v -9.69865 71.16193 -0.15652 -v -9.15641 70.35264 -1.59937 -v -7.92383 71.14378 -1.69533 -v -8.18422 71.95023 -0.49692 -v -10.28395 73.17321 -2.55488 -v -8.61272 70.80678 -0.59948 -v -14.18259 77.38483 -5.18894 -v -11.91544 78.24130 -4.54852 -v -14.06587 76.22170 -5.97282 -v -12.17170 77.84125 -6.80439 -v -10.85964 77.43290 -5.06717 -v -12.24455 76.00573 -4.09175 -v -13.05902 75.39484 -6.50531 -v -11.71964 76.54003 -7.09331 -v -10.79184 76.25129 -5.86489 -v -11.77113 75.24212 -5.17518 -v -13.34077 78.20289 -4.61277 -v -11.75177 75.38861 -6.47440 -v -13.30918 75.30115 -5.65502 -v -11.17811 75.95102 -4.50615 -v -13.58175 73.93551 -5.45064 -v -10.99222 74.09704 -5.86368 -v -10.56796 74.85458 -3.82594 -v -12.67881 74.83903 -3.15485 -v -13.01757 72.82504 -4.79521 -v -11.18652 72.93926 -5.08726 -v -10.88652 73.47493 -3.64636 -v -12.37910 73.46393 -3.17184 -v -12.35953 76.12198 -5.28859 -v -11.94718 72.62024 -4.07263 -v -13.40178 77.87250 -3.96943 -v -11.15559 77.70621 -2.86916 -v -14.24710 76.84039 -3.52084 -v -11.88075 75.74394 -3.83780 -v -11.07049 76.60522 -1.96485 -v -12.93231 77.66433 -1.40075 -v -14.21049 75.74300 -2.64030 -v -12.53721 74.96766 -2.86440 -v -11.96428 75.57670 -1.54003 -v -13.28078 76.32561 -1.14115 -v -12.16970 78.23472 -3.72321 -v -13.31339 75.22314 -1.84356 -# 493 verticies -vt 0.82950 0.57913 -vt 0.82950 0.37951 -vt 0.97984 0.37967 -vt 0.97984 0.57920 -vt 0.82950 0.77869 -vt 0.97984 0.77866 -vt 0.82950 0.99484 -vt 0.97984 0.99471 -vt 0.82950 0.17990 -vt 0.82950 0.00013 -vt 0.97984 0.00047 -vt 0.97984 0.18017 -vt 0.00000 0.85764 -vt 0.27783 0.86187 -vt 0.18484 0.99936 -vt 0.00000 0.99936 -vt 0.00000 0.75516 -vt 0.18484 0.75516 -vt 0.55870 0.75516 -vt 0.73255 0.86879 -vt 0.55870 0.86614 -vt 0.55870 0.99936 -vt 0.37083 0.75516 -vt 0.37083 0.99936 -vt 0.00000 0.62496 -vt 0.17401 0.62748 -vt 0.17401 0.75452 -vt 0.00000 0.75452 -vt 0.00000 0.53210 -vt 0.17401 0.53210 -vt 0.43401 0.53210 -vt 0.63144 0.63410 -vt 0.43401 0.63124 -vt 0.43401 0.75452 -vt 0.00000 0.14459 -vt 0.07538 0.14417 -vt 0.07538 0.23867 -vt 0.00000 0.23876 -vt 0.68493 0.23796 -vt 0.19374 0.23854 -vt 0.19374 0.14351 -vt 0.68493 0.14075 -vt 0.79316 0.14014 -vt 0.68493 0.03631 -vt 0.19374 0.03702 -vt 0.00000 0.03730 -vt 0.07538 0.03719 -vt 0.00000 0.40942 -vt 0.29098 0.40582 -vt 0.18139 0.52380 -vt 0.00000 0.52380 -vt 0.00000 0.27205 -vt 0.18139 0.27205 -vt 0.40058 0.52380 -vt 0.40058 0.27205 -vt 0.61722 0.40179 -vt 0.61722 0.52380 -vt 0.61722 0.27205 -vt 0.79316 0.39961 -vt 0.69040 0.68226 -vt 0.74054 0.68298 -vt 0.74312 0.74410 -vt 0.66780 0.73186 -vt 0.73796 0.62185 -vt 0.66806 0.63410 -vt 0.68638 0.58258 -vt 0.73128 0.55511 -vt 0.74980 0.81085 -vt 0.68882 0.79212 -vt 0.79068 0.68369 -vt 0.77408 0.74211 -vt 0.77055 0.62558 -vt 0.79226 0.57383 -vt 0.79470 0.78338 -vt 0.81302 0.73186 -vt 0.81328 0.63410 -# 76 texture verticies -vn -0.64697 0.42174 0.63527 -vn 0.40426 0.42174 0.81161 -vn -0.80411 0.42174 -0.41899 -vn 0.15000 0.42174 -0.89422 -vn 0.89681 0.42174 -0.13367 -vn -0.42505 0.50661 -0.75012 -vn -0.84475 0.50661 0.17244 -vn 0.58206 0.50661 -0.63604 -vn 0.78478 0.50662 0.35702 -vn -0.09704 0.50662 0.85669 -vn -0.42034 0.52252 -0.74181 -vn -0.83540 0.52252 0.17053 -vn 0.57561 0.52252 -0.62900 -vn 0.77609 0.52252 0.35307 -vn -0.09596 0.52252 0.84721 -vn -0.89000 0.35252 0.28918 -vn 0.00000 0.35252 0.93580 -vn -0.55005 0.35252 -0.75708 -vn 0.55005 0.35252 -0.75708 -vn 0.89000 0.35252 0.28918 -vn -0.97221 0.17468 0.15584 -vn -0.91283 0.37570 0.15996 -vn -0.94592 0.27666 -0.16939 -vn -0.97208 0.18722 -0.14143 -vn -0.88628 0.14668 0.43931 -vn -0.85181 0.22575 0.47272 -vn -0.62720 0.63189 0.45534 -vn -0.58613 0.79656 0.14816 -vn -0.70461 0.69306 0.15227 -vn -0.71045 0.68383 -0.16623 -vn -0.78047 0.42165 0.46160 -vn -0.86642 0.47338 -0.15883 -vn -0.39569 0.89659 0.19889 -vn -0.06842 0.99673 0.04310 -vn -0.37050 0.91847 -0.13836 -vn -0.49037 0.87123 -0.02227 -vn -0.27786 0.86948 0.40841 -vn -0.11353 0.91074 0.39707 -vn 0.61052 0.79199 -0.00472 -vn 0.71554 0.62081 -0.32031 -vn 0.52311 0.81831 -0.23817 -vn 0.40288 0.79323 -0.45659 -vn 0.21683 0.95381 0.20794 -vn -0.01463 0.95853 -0.28462 -vn -0.06400 0.84125 0.53685 -vn -0.00842 0.98130 0.19231 -vn -0.32829 0.88530 0.32934 -vn -0.29986 0.82003 0.48747 -vn 0.17560 0.81324 0.55480 -vn 0.25877 0.87065 0.41834 -vn 0.33642 0.84573 -0.41421 -vn 0.13612 0.70432 -0.69671 -vn 0.09424 0.87728 -0.47063 -vn -0.15378 0.85374 -0.49748 -vn 0.28888 0.95625 0.04615 -vn -0.24837 0.96784 -0.04005 -vn 0.40595 0.90855 -0.09871 -vn 0.04540 0.99815 -0.04050 -vn 0.28836 0.93232 0.21824 -vn 0.43697 0.88846 0.14036 -vn 0.35117 0.87548 -0.33200 -vn 0.18881 0.91089 -0.36692 -vn -0.61355 0.76953 -0.17713 -vn -0.79567 0.59732 0.10054 -vn -0.59456 0.80092 0.07083 -vn -0.53824 0.78201 0.31426 -vn -0.18201 0.94363 -0.27648 -vn -0.09511 0.96077 0.26051 -vn -0.18698 0.94294 -0.27552 -vn -0.00972 0.99863 0.05142 -vn 0.15173 0.95140 -0.26797 -vn 0.02752 0.92231 -0.38546 -vn -0.39053 0.90838 -0.14947 -vn -0.36860 0.92942 0.01760 -vn 0.06788 0.71319 0.69768 -vn 0.38220 0.52122 0.76306 -vn 0.29696 0.74262 0.60028 -vn 0.50732 0.72540 0.46521 -vn -0.16004 0.92710 0.33893 -vn 0.31881 0.94436 0.08085 -vn -0.87065 0.34774 -0.34791 -vn -0.75734 0.58138 -0.29738 -vn -0.58054 0.55557 -0.59524 -vn -0.69016 0.33323 -0.64236 -vn -0.94711 0.32070 -0.01189 -vn -0.84270 0.53719 0.03570 -vn -0.46628 0.86383 0.19075 -vn -0.08624 0.99627 0.00344 -vn -0.35500 0.92756 -0.11666 -vn -0.20411 0.88826 -0.41150 -vn 0.74834 0.21583 -0.62721 -vn 0.67133 0.46405 -0.57790 -vn 0.84625 0.45452 -0.27797 -vn 0.91954 0.21808 -0.32692 -vn 0.48773 0.18779 -0.85256 -vn 0.41598 0.41774 -0.80775 -vn 0.13110 0.79688 -0.58974 -vn 0.12707 0.97485 -0.18310 -vn 0.35344 0.86679 -0.35179 -vn 0.53677 0.84044 -0.07442 -vn 0.07061 -0.01974 0.99731 -vn 0.07989 0.24286 0.96677 -vn -0.26567 0.24703 0.93188 -vn -0.27287 -0.00339 0.96205 -vn 0.40565 -0.03373 0.91341 -vn 0.41519 0.20948 0.88529 -vn 0.41231 0.66225 0.62564 -vn 0.08860 0.89705 0.43295 -vn 0.09023 0.72575 0.68201 -vn -0.24229 0.70867 0.66264 -vn -0.17460 0.94936 -0.26121 -vn -0.21947 0.96921 0.11162 -vn 0.09605 0.99344 -0.06207 -vn 0.06446 0.97080 -0.23108 -vn -0.40345 0.87237 -0.27605 -vn -0.48102 0.86774 -0.12506 -vn -0.45809 0.59096 0.66402 -vn -0.20225 0.42634 0.88166 -vn -0.22319 0.66097 0.71645 -vn 0.02565 0.68945 0.72388 -vn -0.48662 0.83508 0.25659 -vn 0.04240 0.94707 0.31822 -vn -0.06201 0.90567 0.41942 -vn -0.12912 0.64262 0.75523 -vn 0.16580 0.73745 0.65473 -vn 0.13283 0.88687 0.44251 -vn -0.25445 0.88929 0.38003 -vn -0.37199 0.74260 0.55693 -vn -0.43860 0.15537 0.88515 -vn -0.18365 -0.03899 0.98222 -vn -0.17452 0.15606 0.97221 -vn 0.10303 0.14469 0.98410 -vn -0.43039 0.44552 0.78503 -vn 0.13423 0.43640 0.88968 -vn -0.33012 0.90567 -0.26604 -vn -0.58559 0.64262 -0.49409 -vn -0.64844 0.73745 -0.18892 -vn -0.44879 0.88687 -0.10977 -vn -0.19864 0.88929 -0.41196 -vn -0.29156 0.74260 -0.60294 -vn -0.54073 0.15537 -0.82672 -vn -0.75362 -0.03899 -0.65615 -vn -0.74962 0.15606 -0.64320 -vn -0.90055 0.14469 -0.40997 -vn -0.45858 0.44552 -0.76890 -vn -0.83498 0.43640 -0.33521 -vn 0.39665 0.90567 -0.14974 -vn 0.72273 0.64262 -0.25437 -vn 0.49151 0.73745 -0.46323 -vn 0.32209 0.88687 -0.33123 -vn 0.45581 0.88929 0.03757 -vn 0.66754 0.74260 0.05426 -vn 0.98673 0.15537 -0.04712 -vn 0.94759 -0.03899 -0.31709 -vn 0.93441 0.15606 -0.32020 -vn 0.80985 0.14469 -0.56852 -vn 0.89525 0.44552 -0.00561 -vn 0.71217 0.43640 -0.54988 -vn 0.50756 0.86112 -0.02930 -vn 0.75186 0.65870 -0.02876 -vn 0.70481 0.61423 -0.35493 -vn 0.47584 0.80381 -0.35704 -vn 0.93007 -0.06200 -0.36212 -vn 0.91688 0.21448 -0.33663 -vn 0.97299 0.22951 -0.02486 -vn 0.99761 -0.06502 -0.02320 -vn 0.98189 -0.18814 -0.02245 -vn 0.94599 -0.06028 0.31854 -vn 0.93118 0.22143 0.28962 -vn 0.48259 0.82224 0.30171 -vn 0.71566 0.63023 0.30107 -vn -0.15967 0.86111 -0.48269 -vn -0.22238 0.65869 -0.71880 -vn -0.52525 0.61423 -0.58893 -vn -0.46803 0.80381 -0.36721 -vn -0.59050 -0.06200 -0.80465 -vn -0.56247 0.21448 -0.79851 -vn -0.27584 0.22951 -0.93340 -vn -0.28061 -0.06502 -0.95762 -vn -0.27582 -0.18814 -0.94262 -vn 0.06284 -0.06028 -0.99620 -vn 0.03875 0.22143 -0.97441 -vn 0.16652 0.82224 -0.54424 -vn 0.10559 0.63023 -0.76920 -vn -0.42491 0.86112 0.27916 -vn -0.63675 0.65870 0.40084 -vn -0.43292 0.61423 0.65978 -vn -0.23357 0.80381 0.54712 -vn -0.62440 -0.06200 0.77864 -vn -0.62573 0.21448 0.74997 -vn -0.83020 0.22951 0.50803 -vn -0.85236 -0.06502 0.51890 -vn -0.83911 -0.18814 0.51039 -vn -0.97852 -0.06028 0.19713 -vn -0.95123 0.22143 0.21477 -vn -0.56879 0.82224 -0.01999 -vn -0.77031 0.63023 0.09709 -vn 0.02818 0.99931 -0.02438 -vn 0.25408 0.96698 -0.01988 -vn 0.11766 0.91883 -0.37671 -vn 0.02908 0.93862 -0.34373 -vn 0.02431 0.95440 0.29754 -vn 0.11726 0.93562 0.33296 -vn 0.34172 0.87021 -0.35492 -vn 0.34314 0.88224 0.32234 -vn 0.62765 0.77841 -0.01149 -vn 0.59048 0.72671 -0.35103 -vn 0.58994 0.73723 0.32935 -vn 0.75166 0.65946 -0.01072 -vn -0.67910 0.51031 0.52764 -vn -0.46202 0.81309 0.35416 -vn -0.76753 0.61394 0.18433 -vn -0.81586 0.49192 0.30394 -vn -0.49543 0.49345 0.71488 -vn -0.36937 0.62157 0.69080 -vn -0.48158 0.87636 0.00824 -vn -0.12847 0.88280 0.45184 -vn 0.10368 0.99006 -0.09499 -vn -0.05500 0.95652 -0.28645 -vn 0.25576 0.96131 0.10235 -vn 0.33192 0.90046 -0.28107 -vn 0.22826 0.51031 0.82914 -vn 0.15085 0.81309 0.56226 -vn -0.12280 0.61394 0.77974 -vn -0.03071 0.49192 0.87010 -vn 0.47146 0.49345 0.73091 -vn 0.49735 0.62157 0.60522 -vn -0.17632 0.87636 0.44822 -vn 0.36852 0.88280 0.29131 -vn -0.04819 0.99006 -0.13210 -vn -0.28574 0.95652 -0.05857 -vn 0.19227 0.96131 -0.19728 -vn -0.13299 0.90046 -0.41411 -vn 0.71290 0.69525 0.09164 -vn 0.37453 0.92558 0.05502 -vn 0.51333 0.76177 0.39523 -vn 0.65703 0.66919 0.34714 -vn 0.71953 0.67328 -0.17019 -vn 0.58683 0.77183 -0.24478 -vn 0.13510 0.94012 0.31292 -vn 0.19653 0.94790 -0.25071 -vn -0.36445 0.93079 -0.02837 -vn -0.37956 0.89862 0.22003 -vn -0.32641 0.90439 -0.27485 -vn -0.62892 0.77553 -0.05484 -vn 0.32303 0.76257 -0.56048 -vn 0.15003 0.95830 -0.24323 -vn 0.52467 0.81220 -0.25504 -vn 0.53910 0.73367 -0.41365 -vn 0.08465 0.73879 -0.66860 -vn -0.03923 0.82313 -0.56650 -vn 0.29674 0.95186 0.07690 -vn -0.20107 0.96008 -0.19445 -vn -0.20782 0.89032 0.40515 -vn 0.01745 0.85926 0.51124 -vn -0.41989 0.86534 0.27363 -vn -0.32548 0.70966 0.62486 -vn -0.41753 0.73040 -0.54054 -vn -0.19668 0.94338 -0.26713 -vn -0.05988 0.78839 -0.61225 -vn -0.19844 0.70286 -0.68309 -vn -0.60778 0.70748 -0.36066 -vn -0.56343 0.79891 -0.21046 -vn 0.15526 0.94724 -0.28040 -vn -0.28590 0.95526 0.07573 -vn 0.26741 0.91130 0.31310 -vn 0.45245 0.87965 0.14661 -vn 0.06563 0.88559 0.45981 -vn 0.43088 0.74290 0.51229 -vn -0.15530 0.97162 0.17843 -vn 0.07780 0.98762 -0.13623 -vn -0.31033 0.93789 -0.15511 -vn -0.35824 0.93349 0.01582 -vn 0.05837 0.94263 0.32871 -vn 0.20825 0.95137 0.22700 -vn -0.05020 0.89097 -0.45128 -vn 0.42146 0.90056 -0.10659 -vn 0.41958 0.69060 -0.58909 -vn 0.18854 0.66160 -0.72576 -vn 0.61994 0.66927 -0.40957 -vn 0.50270 0.50300 -0.70306 -vn -0.19000 0.97162 -0.14092 -vn 0.14188 0.98762 0.06694 -vn 0.13044 0.93789 -0.32148 -vn -0.04370 0.93349 -0.35592 -vn -0.32316 0.94263 0.08381 -vn -0.21008 0.95137 0.22531 -vn 0.44599 0.89097 -0.08522 -vn 0.13912 0.90056 0.41187 -vn 0.62000 0.69060 0.37238 -vn 0.73825 0.66160 0.13140 -vn 0.45665 0.66927 0.58613 -vn 0.74010 0.50300 0.44636 -vn 0.19027 0.97162 -0.14055 -vn -0.10546 0.98762 0.11614 -vn 0.26936 0.93789 0.21865 -vn 0.35316 0.93350 0.06216 -vn 0.01423 0.94262 -0.33355 -vn -0.15412 0.95137 -0.26673 -vn -0.04876 0.89097 0.45144 -vn -0.43455 0.90056 0.01275 -vn -0.53724 0.69060 0.48420 -vn -0.34129 0.66160 0.66768 -vn -0.69395 0.66927 0.26554 -vn -0.64307 0.50300 0.57746 -vn 0.16085 0.97162 0.17344 -vn -0.12716 0.98762 -0.09188 -vn -0.18731 0.93789 0.29202 -vn -0.02246 0.93349 0.35789 -vn 0.33306 0.94263 -0.02298 -vn 0.24791 0.95137 -0.18285 -vn -0.45406 0.89097 0.00179 -vn -0.06104 0.90056 -0.43043 -vn -0.54099 0.69060 -0.48000 -vn -0.70152 0.66160 -0.26486 -vn -0.34113 0.66927 -0.66008 -vn -0.64545 0.50300 -0.57480 -vn -0.33174 0.64399 0.68937 -vn -0.02286 0.69552 0.71814 -vn -0.22674 0.73662 0.63717 -vn -0.34879 0.65580 0.66953 -vn -0.31442 0.63164 0.70864 -vn -0.15951 0.62423 0.76478 -vn 0.50160 0.43102 0.75008 -vn 0.72993 0.34377 0.59078 -vn 0.53917 0.52177 0.66110 -vn 0.56743 0.60386 0.55980 -vn 0.16663 0.62751 0.76057 -vn 0.10408 0.75792 0.64400 -vn -0.78604 0.60080 -0.14553 -vn -0.90142 0.42401 0.08755 -vn -0.79781 0.60290 0.00343 -vn -0.76879 0.62349 -0.14220 -vn -0.80265 0.57761 -0.14874 -vn -0.88549 0.45956 -0.06869 -vn -0.94981 -0.12780 0.28553 -vn -0.82576 -0.32547 0.46064 -vn -0.91251 -0.07641 0.40186 -vn -0.85877 -0.02331 0.51182 -vn -0.95700 0.24051 0.16217 -vn -0.88709 0.39222 0.24340 -vn 0.92721 0.36385 0.08889 -vn 0.88599 0.40837 -0.21968 -vn 0.88227 0.47072 -0.00541 -vn 0.91789 0.38140 0.10960 -vn 0.93576 0.34601 0.06810 -vn 0.94166 0.32285 -0.09511 -vn 0.68352 0.15888 -0.71243 -vn 0.44835 0.13556 -0.88352 -vn 0.62317 0.27523 -0.73205 -vn 0.55137 0.38747 -0.73883 -vn 0.84989 0.33360 -0.40792 -vn 0.80518 0.49472 -0.32701 -vn -0.46321 0.66936 0.58085 -vn -0.61372 0.17637 0.76957 -vn 0.80345 0.13888 0.57894 -vn 0.02765 0.99902 -0.03467 -vn -0.74321 0.13888 -0.65448 -vn 0.44087 0.70711 -0.55284 -vn 0.61410 0.17287 -0.77006 -vn -0.42882 -0.72592 0.53773 -vn 0.57104 -0.70661 0.41787 -vn -0.53446 -0.70661 -0.46374 -vn 0.42136 -0.73708 -0.52837 -vn -0.00321 -0.99999 0.00403 -vn -0.39927 0.87341 0.27881 -vn -0.35166 0.57617 0.73781 -vn 0.88699 0.46069 0.03176 -vn -0.23550 0.79754 -0.55540 -vn -0.92613 -0.27593 -0.25719 -vn 0.04450 0.26799 -0.96239 -vn 0.26468 -0.29083 -0.91944 -vn -0.03376 -0.29185 0.95587 -vn 0.83352 -0.32748 0.44497 -vn -0.46244 -0.85399 0.23844 -vn 0.39519 -0.89933 -0.18714 -vn 0.24799 -0.81553 0.52289 -vn -0.39927 0.87341 0.27880 -vn -0.23550 0.79753 -0.55541 -vn 0.04449 0.26798 -0.96240 -vn -0.18330 0.92803 -0.32430 -vn -0.67438 0.69208 -0.25736 -vn 0.09574 0.39907 0.91191 -vn 0.64198 0.73058 -0.23262 -vn 0.14968 -0.24379 -0.95821 -vn 0.99088 0.13360 -0.01734 -vn 0.88699 -0.42824 0.17279 -vn -0.98697 -0.15879 0.02612 -vn -0.42517 -0.32144 0.84611 -vn -0.38661 -0.78094 -0.49058 -vn 0.08887 -0.94115 0.32609 -vn -0.61145 -0.75356 0.24140 -vn 0.19284 0.83661 -0.51273 -vn 0.61504 0.77034 -0.16826 -vn 0.37153 -0.49774 -0.78372 -vn -0.53729 0.44448 -0.71677 -vn -0.58123 0.56255 0.58797 -vn -0.86378 -0.15660 -0.47892 -vn -0.79222 -0.60457 -0.08294 -vn 0.85947 0.13417 0.49326 -vn 0.67710 -0.73564 0.01931 -vn -0.00390 0.02222 0.99975 -vn -0.11054 -0.82202 0.55862 -vn 0.50973 -0.47228 0.71911 -vn -0.53756 0.84321 0.00547 -vn -0.35268 0.77908 0.51832 -vn 0.75366 0.55049 -0.35910 -vn -0.49369 0.44409 -0.74770 -vn -0.86837 -0.48655 0.09596 -vn -0.16860 -0.16288 -0.97213 -vn 0.17611 -0.61332 -0.76995 -vn 0.18329 0.14028 0.97300 -vn 0.94512 0.01365 0.32644 -vn -0.21425 -0.72759 0.65170 -vn 0.55387 -0.82802 0.08724 -vn 0.50467 -0.47223 0.72271 -vn -0.88136 0.45893 0.11220 -vn -0.82802 0.12701 0.54613 -vn 0.41306 0.82155 0.39298 -vn -0.44417 0.67604 -0.58795 -vn -0.47287 -0.63424 -0.61166 -vn 0.19614 0.47328 -0.85880 -vn 0.66150 0.10944 -0.74192 -vn -0.17255 -0.48617 0.85666 -vn 0.67664 0.04164 0.73514 -vn 0.04341 -0.99891 0.01706 -vn 0.86302 -0.50425 -0.03034 -vn 0.47425 -0.67700 0.56282 -vn -0.95711 0.25124 0.14430 -vn -0.96540 -0.20322 -0.16344 -vn -0.03747 -0.43289 0.90067 -vn -0.38551 0.76897 0.50997 -vn 0.00652 0.67549 -0.73734 -vn 0.33828 0.77514 0.53359 -vn 0.81717 0.46696 0.33791 -vn -0.31279 -0.78274 -0.53804 -vn 0.31185 -0.91927 0.24019 -vn 0.34329 -0.12704 -0.93060 -vn 0.92524 -0.32527 -0.19525 -vn 0.42137 -0.75631 -0.50045 -vn -0.70561 0.43584 -0.55872 -vn -0.85631 -0.08960 -0.50863 -vn -0.48350 0.36694 0.79472 -vn -0.07275 0.94945 -0.30537 -vn 0.53493 -0.08111 -0.84099 -vn 0.52296 0.84721 0.09355 -vn 0.81823 0.41766 0.39505 -vn -0.50445 -0.85986 -0.07856 -vn -0.26091 -0.49569 0.82838 -vn 0.46703 -0.81594 -0.34077 -vn 0.65602 -0.51682 0.55003 -vn 0.10618 -0.94020 0.32365 -vn -0.46047 0.58977 -0.66343 -vn -0.82794 0.20771 -0.52093 -vn -0.23161 0.68875 0.68701 -vn 0.34607 0.80372 -0.48401 -vn 0.40336 -0.47088 -0.78458 -vn 0.85045 0.52405 -0.04599 -vn 0.93559 0.07425 0.34519 -vn -0.83890 -0.54052 0.06396 -vn -0.41732 -0.15807 0.89491 -vn 0.03654 -0.98693 -0.15694 -vn 0.37956 -0.63999 0.66809 -vn -0.31125 -0.80711 0.50170 -# 464 normals -usemtl branches -f 48/72/27 47/73/28 46/74/28 42/75/27 -f 49/76/29 48/72/27 42/75/27 43/77/29 -f 50/78/30 49/76/29 43/77/29 44/79/30 -f 51/80/31 50/81/30 44/82/30 45/83/31 -f 47/73/28 51/80/31 45/83/31 46/74/28 -f 58/72/32 57/73/33 56/74/33 52/75/32 -f 59/76/34 58/72/32 52/75/32 53/77/34 -f 60/78/35 59/76/34 53/77/34 54/79/35 -f 61/80/36 60/81/35 54/82/35 55/83/36 -f 57/73/33 61/80/36 55/83/36 56/74/33 -f 68/72/37 67/73/38 66/74/38 62/75/37 -f 69/76/39 68/72/37 62/75/37 63/77/39 -f 70/78/40 69/76/39 63/77/39 64/79/40 -f 71/80/41 70/81/40 64/82/40 65/83/41 -f 67/73/38 71/80/41 65/83/41 66/74/38 -f 78/72/42 77/73/43 76/74/43 72/75/42 -f 79/76/44 78/72/42 72/75/42 73/77/44 -f 80/78/45 79/76/44 73/77/44 74/79/45 -f 81/80/46 80/81/45 74/82/45 75/83/46 -f 77/73/43 81/80/46 75/83/46 76/74/43 -f 83/84/47 91/85/48 92/86/49 82/87/50 -f 84/88/51 93/89/52 91/85/48 83/84/47 -f 86/90/53 85/91/54 87/92/55 -f 88/93/56 87/92/55 85/91/54 -f 89/94/57 86/90/53 87/92/55 91/85/48 -f 90/95/58 91/85/48 87/92/55 88/93/56 -f 93/89/52 89/94/57 91/85/48 -f 92/86/49 91/85/48 90/95/58 -f 95/84/59 103/85/60 104/86/61 94/87/62 -f 96/88/63 105/89/64 103/85/60 95/84/59 -f 98/90/65 97/91/66 99/92/67 -f 100/93/68 99/92/67 97/91/66 -f 101/94/69 98/90/65 99/92/67 103/85/60 -f 102/95/70 103/85/60 99/92/67 100/93/68 -f 105/89/64 101/94/69 103/85/60 -f 104/86/61 103/85/60 102/95/70 -f 107/84/71 115/85/72 116/86/73 106/87/74 -f 108/88/75 117/89/76 115/85/72 107/84/71 -f 110/90/77 109/91/78 111/92/79 -f 112/93/80 111/92/79 109/91/78 -f 113/94/81 110/90/77 111/92/79 115/85/72 -f 114/95/82 115/85/72 111/92/79 112/93/80 -f 117/89/76 113/94/81 115/85/72 -f 116/86/73 115/85/72 114/95/82 -f 119/84/83 127/85/84 128/86/85 118/87/86 -f 120/88/87 129/89/88 127/85/84 119/84/83 -f 122/90/89 121/91/90 123/92/91 -f 124/93/92 123/92/91 121/91/90 -f 125/94/93 122/90/89 123/92/91 127/85/84 -f 126/95/94 127/85/84 123/92/91 124/93/92 -f 129/89/88 125/94/93 127/85/84 -f 128/86/85 127/85/84 126/95/94 -f 131/84/95 139/85/96 140/86/97 130/87/98 -f 132/88/99 141/89/100 139/85/96 131/84/95 -f 134/90/101 133/91/102 135/92/103 -f 136/93/104 135/92/103 133/91/102 -f 137/94/105 134/90/101 135/92/103 139/85/96 -f 138/95/106 139/85/96 135/92/103 136/93/104 -f 141/89/100 137/94/105 139/85/96 -f 140/86/97 139/85/96 138/95/106 -f 144/96/107 146/97/108 150/98/109 143/99/110 -f 142/100/111 149/101/112 146/97/108 144/96/107 -f 147/102/113 145/103/114 151/104/115 -f 148/105/116 151/104/115 145/103/114 -f 149/101/112 147/102/113 151/104/115 146/97/108 -f 150/98/109 146/97/108 151/104/115 148/105/116 -f 154/96/117 156/97/118 160/98/119 153/99/120 -f 152/100/121 159/101/122 156/97/118 154/96/117 -f 157/102/123 155/103/124 161/104/125 -f 158/105/126 161/104/125 155/103/124 -f 159/101/122 157/102/123 161/104/125 156/97/118 -f 160/98/119 156/97/118 161/104/125 158/105/126 -f 164/96/127 166/97/128 170/98/129 163/99/130 -f 162/100/131 169/101/132 166/97/128 164/96/127 -f 167/102/133 165/103/134 171/104/135 -f 168/105/136 171/104/135 165/103/134 -f 169/101/132 167/102/133 171/104/135 166/97/128 -f 170/98/129 166/97/128 171/104/135 168/105/136 -f 173/84/137 181/85/138 182/86/139 172/87/140 -f 174/88/141 183/89/142 181/85/138 173/84/137 -f 176/90/143 175/91/144 177/92/145 -f 178/93/146 177/92/145 175/91/144 -f 179/94/147 176/90/143 177/92/145 181/85/138 -f 180/95/148 181/85/138 177/92/145 178/93/146 -f 183/89/142 179/94/147 181/85/138 -f 182/86/139 181/85/138 180/95/148 -f 185/84/149 193/85/150 194/86/151 184/87/152 -f 186/88/153 195/89/154 193/85/150 185/84/149 -f 188/90/155 187/91/156 189/92/157 -f 190/93/158 189/92/157 187/91/156 -f 191/94/159 188/90/155 189/92/157 193/85/150 -f 192/95/160 193/85/150 189/92/157 190/93/158 -f 195/89/154 191/94/159 193/85/150 -f 194/86/151 193/85/150 192/95/160 -f 197/84/161 205/85/162 206/86/163 196/87/164 -f 198/88/165 207/89/166 205/85/162 197/84/161 -f 200/90/167 199/91/168 201/92/169 -f 202/93/170 201/92/169 199/91/168 -f 203/94/171 200/90/167 201/92/169 205/85/162 -f 204/95/172 205/85/162 201/92/169 202/93/170 -f 207/89/166 203/94/171 205/85/162 -f 206/86/163 205/85/162 204/95/172 -f 209/84/173 217/85/174 218/86/175 208/87/176 -f 210/88/177 219/89/178 217/85/174 209/84/173 -f 212/90/179 211/91/180 213/92/181 -f 214/93/182 213/92/181 211/91/180 -f 215/94/183 212/90/179 213/92/181 217/85/174 -f 216/95/184 217/85/174 213/92/181 214/93/182 -f 219/89/178 215/94/183 217/85/174 -f 218/86/175 217/85/174 216/95/184 -f 220/106/185 223/107/186 231/108/187 229/109/188 -f 227/110/189 228/111/190 232/112/191 222/113/192 -f 221/114/193 227/110/189 222/113/192 -f 222/113/192 224/115/194 221/114/193 -f 232/112/191 225/116/195 224/115/194 222/113/192 -f 226/117/196 230/118/197 223/107/186 220/106/185 -f 232/112/191 223/107/186 230/118/197 225/116/195 -f 228/111/190 231/108/187 223/107/186 232/112/191 -f 233/106/198 236/107/199 244/108/200 242/109/201 -f 240/110/202 241/111/203 245/112/204 235/113/205 -f 234/114/206 240/110/202 235/113/205 -f 235/113/205 237/115/207 234/114/206 -f 245/112/204 238/116/208 237/115/207 235/113/205 -f 239/117/209 243/118/210 236/107/199 233/106/198 -f 245/112/204 236/107/199 243/118/210 238/116/208 -f 241/111/203 244/108/200 236/107/199 245/112/204 -f 246/106/211 249/107/212 257/108/213 255/109/214 -f 253/110/215 254/111/216 258/112/217 248/113/218 -f 247/114/219 253/110/215 248/113/218 -f 248/113/218 250/115/220 247/114/219 -f 258/112/217 251/116/221 250/115/220 248/113/218 -f 252/117/222 256/118/223 249/107/212 246/106/211 -f 258/112/217 249/107/212 256/118/223 251/116/221 -f 254/111/216 257/108/213 249/107/212 258/112/217 -f 259/119/224 263/120/225 264/121/226 261/122/227 -f 262/123/228 265/124/229 263/120/225 259/119/224 -f 264/121/226 263/120/225 266/125/230 -f 263/120/225 265/124/229 267/126/231 -f 266/125/230 263/120/225 268/127/232 269/128/233 -f 263/120/225 267/126/231 270/129/234 268/127/232 -f 269/128/233 268/127/232 260/130/235 -f 268/127/232 270/129/234 260/130/235 -f 271/119/236 275/120/237 276/121/238 273/122/239 -f 274/123/240 277/124/241 275/120/237 271/119/236 -f 276/121/238 275/120/237 278/125/242 -f 275/120/237 277/124/241 279/126/243 -f 278/125/242 275/120/237 280/127/244 281/128/245 -f 275/120/237 279/126/243 282/129/246 280/127/244 -f 281/128/245 280/127/244 272/130/247 -f 280/127/244 282/129/246 272/130/247 -f 283/119/248 287/120/249 288/121/250 285/122/251 -f 286/123/252 289/124/253 287/120/249 283/119/248 -f 288/121/250 287/120/249 290/125/254 -f 287/120/249 289/124/253 291/126/255 -f 290/125/254 287/120/249 292/127/256 293/128/257 -f 287/120/249 291/126/255 294/129/258 292/127/256 -f 293/128/257 292/127/256 284/130/259 -f 292/127/256 294/129/258 284/130/259 -f 295/119/260 299/120/261 300/121/262 297/122/263 -f 298/123/264 301/124/265 299/120/261 295/119/260 -f 300/121/262 299/120/261 302/125/266 -f 299/120/261 301/124/265 303/126/267 -f 302/125/266 299/120/261 304/127/268 305/128/269 -f 299/120/261 303/126/267 306/129/270 304/127/268 -f 305/128/269 304/127/268 296/130/271 -f 304/127/268 306/129/270 296/130/271 -f 307/119/272 311/120/273 312/121/274 309/122/275 -f 310/123/276 313/124/277 311/120/273 307/119/272 -f 312/121/274 311/120/273 314/125/278 -f 311/120/273 313/124/277 315/126/279 -f 314/125/278 311/120/273 316/127/280 317/128/281 -f 311/120/273 315/126/279 318/129/282 316/127/280 -f 317/128/281 316/127/280 308/130/283 -f 316/127/280 318/129/282 308/130/283 -f 319/119/284 323/120/285 324/121/286 321/122/287 -f 322/123/288 325/124/289 323/120/285 319/119/284 -f 324/121/286 323/120/285 326/125/290 -f 323/120/285 325/124/289 327/126/291 -f 326/125/290 323/120/285 328/127/292 329/128/293 -f 323/120/285 327/126/291 330/129/294 328/127/292 -f 329/128/293 328/127/292 320/130/295 -f 328/127/292 330/129/294 320/130/295 -f 331/119/296 335/120/297 336/121/298 333/122/299 -f 334/123/300 337/124/301 335/120/297 331/119/296 -f 336/121/298 335/120/297 338/125/302 -f 335/120/297 337/124/301 339/126/303 -f 338/125/302 335/120/297 340/127/304 341/128/305 -f 335/120/297 339/126/303 342/129/306 340/127/304 -f 341/128/305 340/127/304 332/130/307 -f 340/127/304 342/129/306 332/130/307 -f 343/119/308 347/120/309 348/121/310 345/122/311 -f 346/123/312 349/124/313 347/120/309 343/119/308 -f 348/121/310 347/120/309 350/125/314 -f 347/120/309 349/124/313 351/126/315 -f 350/125/314 347/120/309 352/127/316 353/128/317 -f 347/120/309 351/126/315 354/129/318 352/127/316 -f 353/128/317 352/127/316 344/130/319 -f 352/127/316 354/129/318 344/130/319 -f 355/119/320 359/120/321 360/121/322 357/122/323 -f 358/123/324 361/124/325 359/120/321 355/119/320 -f 360/121/322 359/120/321 362/125/326 -f 359/120/321 361/124/325 363/126/327 -f 362/125/326 359/120/321 364/127/328 365/128/329 -f 359/120/321 363/126/327 366/129/330 364/127/328 -f 365/128/329 364/127/328 356/130/331 -f 364/127/328 366/129/330 356/130/331 -f 367/119/332 371/120/333 372/121/334 369/122/335 -f 370/123/336 373/124/337 371/120/333 367/119/332 -f 372/121/334 371/120/333 374/125/338 -f 371/120/333 373/124/337 375/126/339 -f 374/125/338 371/120/333 376/127/340 377/128/341 -f 371/120/333 375/126/339 378/129/342 376/127/340 -f 377/128/341 376/127/340 368/130/343 -f 376/127/340 378/129/342 368/130/343 -f 380/84/344 388/85/345 389/86/346 379/87/347 -f 381/88/348 390/89/349 388/85/345 380/84/344 -f 383/90/350 382/91/351 384/92/352 -f 385/93/353 384/92/352 382/91/351 -f 386/94/354 383/90/350 384/92/352 388/85/345 -f 387/95/355 388/85/345 384/92/352 385/93/353 -f 390/89/349 386/94/354 388/85/345 -f 389/86/346 388/85/345 387/95/355 -f 392/84/356 400/85/357 401/86/358 391/87/359 -f 393/88/360 402/89/361 400/85/357 392/84/356 -f 395/90/362 394/91/363 396/92/364 -f 397/93/365 396/92/364 394/91/363 -f 398/94/366 395/90/362 396/92/364 400/85/357 -f 399/95/367 400/85/357 396/92/364 397/93/365 -f 402/89/361 398/94/366 400/85/357 -f 401/86/358 400/85/357 399/95/367 -f 404/84/368 412/85/369 413/86/370 403/87/371 -f 405/88/372 414/89/373 412/85/369 404/84/368 -f 407/90/374 406/91/375 408/92/376 -f 409/93/377 408/92/376 406/91/375 -f 410/94/378 407/90/374 408/92/376 412/85/369 -f 411/95/379 412/85/369 408/92/376 409/93/377 -f 414/89/373 410/94/378 412/85/369 -f 413/86/370 412/85/369 411/95/379 -f 415/131/380 417/132/381 420/133/382 425/134/383 -f 418/135/384 417/132/381 415/131/380 425/136/383 -f 416/137/385 419/138/386 418/135/384 425/136/383 -f 420/133/382 419/139/386 416/140/385 425/134/383 -f 420/133/382 417/132/381 421/141/387 424/142/388 -f 417/132/381 418/135/384 422/143/389 421/141/387 -f 418/135/384 419/138/386 423/144/390 422/143/389 -f 419/139/386 420/133/382 424/142/388 423/145/390 -f 424/142/388 421/141/387 426/146/391 -f 421/141/387 422/143/389 426/147/391 -f 422/143/389 423/144/390 426/147/391 -f 423/145/390 424/142/388 426/146/391 -f 427/131/392 429/132/393 432/133/394 437/134/395 -f 430/135/396 429/132/393 427/131/392 437/136/395 -f 428/137/397 431/138/398 430/135/396 437/136/395 -f 432/133/394 431/139/398 428/140/397 437/134/395 -f 432/133/394 429/132/393 433/141/399 436/142/400 -f 429/132/393 430/135/396 434/143/401 433/141/399 -f 430/135/396 431/138/398 435/144/402 434/143/401 -f 431/139/398 432/133/394 436/142/400 435/145/402 -f 436/142/400 433/141/399 438/146/403 -f 433/141/399 434/143/401 438/147/403 -f 434/143/401 435/144/402 438/147/403 -f 435/145/402 436/142/400 438/146/403 -f 439/131/404 441/132/393 444/133/394 449/134/405 -f 442/135/396 441/132/393 439/131/404 449/136/405 -f 440/137/406 443/138/398 442/135/396 449/136/405 -f 444/133/394 443/139/398 440/140/406 449/134/405 -f 444/133/394 441/132/393 445/141/399 448/142/400 -f 441/132/393 442/135/396 446/143/401 445/141/399 -f 442/135/396 443/138/398 447/144/402 446/143/401 -f 443/139/398 444/133/394 448/142/400 447/145/402 -f 448/142/400 445/141/399 450/146/403 -f 445/141/399 446/143/401 450/147/403 -f 446/143/401 447/144/402 450/147/403 -f 447/145/402 448/142/400 450/146/403 -f 451/131/407 453/132/408 456/133/409 461/134/410 -f 454/135/411 453/132/408 451/131/407 461/136/410 -f 452/137/412 455/138/413 454/135/411 461/136/410 -f 456/133/409 455/139/413 452/140/412 461/134/410 -f 456/133/409 453/132/408 457/141/414 460/142/415 -f 453/132/408 454/135/411 458/143/416 457/141/414 -f 454/135/411 455/138/413 459/144/417 458/143/416 -f 455/139/413 456/133/409 460/142/415 459/145/417 -f 460/142/415 457/141/414 462/146/418 -f 457/141/414 458/143/416 462/147/418 -f 458/143/416 459/144/417 462/147/418 -f 459/145/417 460/142/415 462/146/418 -f 463/131/419 465/132/420 468/133/421 473/134/422 -f 466/135/423 465/132/420 463/131/419 473/136/422 -f 464/137/424 467/138/425 466/135/423 473/136/422 -f 468/133/421 467/139/425 464/140/424 473/134/422 -f 468/133/421 465/132/420 469/141/426 472/142/427 -f 465/132/420 466/135/423 470/143/428 469/141/426 -f 466/135/423 467/138/425 471/144/429 470/143/428 -f 467/139/425 468/133/421 472/142/427 471/145/429 -f 472/142/427 469/141/426 474/146/430 -f 469/141/426 470/143/428 474/147/430 -f 470/143/428 471/144/429 474/147/430 -f 471/145/429 472/142/427 474/146/430 -f 475/131/431 477/132/432 480/133/433 485/134/434 -f 478/135/435 477/132/432 475/131/431 485/136/434 -f 476/137/436 479/138/437 478/135/435 485/136/434 -f 480/133/433 479/139/437 476/140/436 485/134/434 -f 480/133/433 477/132/432 481/141/438 484/142/439 -f 477/132/432 478/135/435 482/143/440 481/141/438 -f 478/135/435 479/138/437 483/144/441 482/143/440 -f 479/139/437 480/133/433 484/142/439 483/145/441 -f 484/142/439 481/141/438 486/146/442 -f 481/141/438 482/143/440 486/147/442 -f 482/143/440 483/144/441 486/147/442 -f 483/145/441 484/142/439 486/146/442 -f 487/131/443 489/132/444 492/133/445 497/134/446 -f 490/135/447 489/132/444 487/131/443 497/136/446 -f 488/137/448 491/138/449 490/135/447 497/136/446 -f 492/133/445 491/139/449 488/140/448 497/134/446 -f 492/133/445 489/132/444 493/141/450 496/142/451 -f 489/132/444 490/135/447 494/143/452 493/141/450 -f 490/135/447 491/138/449 495/144/453 494/143/452 -f 491/139/449 492/133/445 496/142/451 495/145/453 -f 496/142/451 493/141/450 498/146/454 -f 493/141/450 494/143/452 498/147/454 -f 494/143/452 495/144/453 498/147/454 -f 495/145/453 496/142/451 498/146/454 -f 499/131/455 501/132/456 504/133/457 509/134/458 -f 502/135/459 501/132/456 499/131/455 509/136/458 -f 500/137/460 503/138/461 502/135/459 509/136/458 -f 504/133/457 503/139/461 500/140/460 509/134/458 -f 504/133/457 501/132/456 505/141/462 508/142/463 -f 501/132/456 502/135/459 506/143/464 505/141/462 -f 502/135/459 503/138/461 507/144/465 506/143/464 -f 503/139/461 504/133/457 508/142/463 507/145/465 -f 508/142/463 505/141/462 510/146/466 -f 505/141/462 506/143/464 510/147/466 -f 506/143/464 507/144/465 510/147/466 -f 507/145/465 508/142/463 510/146/466 -f 511/131/467 513/132/468 516/133/469 521/134/470 -f 514/135/471 513/132/468 511/131/467 521/136/470 -f 512/137/472 515/138/473 514/135/471 521/136/470 -f 516/133/469 515/139/473 512/140/472 521/134/470 -f 516/133/469 513/132/468 517/141/474 520/142/475 -f 513/132/468 514/135/471 518/143/476 517/141/474 -f 514/135/471 515/138/473 519/144/477 518/143/476 -f 515/139/473 516/133/469 520/142/475 519/145/477 -f 520/142/475 517/141/474 522/146/478 -f 517/141/474 518/143/476 522/147/478 -f 518/143/476 519/144/477 522/147/478 -f 519/145/477 520/142/475 522/146/478 -f 523/131/479 525/132/480 528/133/481 533/134/482 -f 526/135/483 525/132/480 523/131/479 533/136/482 -f 524/137/484 527/138/485 526/135/483 533/136/482 -f 528/133/481 527/139/485 524/140/484 533/134/482 -f 528/133/481 525/132/480 529/141/486 532/142/487 -f 525/132/480 526/135/483 530/143/488 529/141/486 -f 526/135/483 527/138/485 531/144/489 530/143/488 -f 527/139/485 528/133/481 532/142/487 531/145/489 -f 532/142/487 529/141/486 534/146/490 -f 529/141/486 530/143/488 534/147/490 -f 530/143/488 531/144/489 534/147/490 -f 531/145/489 532/142/487 534/146/490 diff --git a/examples/assets/3d/dreampalm/palm_bark.jpg b/examples/assets/3d/dreampalm/palm_bark.jpg deleted file mode 100644 index a31861c..0000000 Binary files a/examples/assets/3d/dreampalm/palm_bark.jpg and /dev/null differ diff --git a/examples/assets/3d/dreampalm/palm_bark.png b/examples/assets/3d/dreampalm/palm_bark.png deleted file mode 100644 index 5807ac6..0000000 Binary files a/examples/assets/3d/dreampalm/palm_bark.png and /dev/null differ diff --git a/examples/assets/3d/dreampalm/palm_leafs.jpg b/examples/assets/3d/dreampalm/palm_leafs.jpg deleted file mode 100644 index 033a4ac..0000000 Binary files a/examples/assets/3d/dreampalm/palm_leafs.jpg and /dev/null differ diff --git a/examples/assets/3d/dreampsd/palm.mtl b/examples/assets/3d/dreampsd/palm.mtl deleted file mode 100644 index 884c1b8..0000000 --- a/examples/assets/3d/dreampsd/palm.mtl +++ /dev/null @@ -1,18 +0,0 @@ -newmtl trunk -Ka 0.012984 0.012984 0.012984 -Kd 1.000000 1.000000 1.000000 -Ks 1.000000 1.000000 1.000000 -illum 1 -Ns 2.000000 -Tr 1.000000 -map_Kd palm_bark.JPG - -newmtl branches -Ka 0.012984 0.012984 0.012984 -Kd 1.000000 1.000000 1.000000 -Ks 1.000000 1.000000 1.000000 -illum 1 -Ns 2.000000 -Tr 1.000000 -map_Kd palm_leafs.JPG - diff --git a/examples/assets/3d/dreampsd/palm.obj b/examples/assets/3d/dreampsd/palm.obj deleted file mode 100644 index 6ca75eb..0000000 --- a/examples/assets/3d/dreampsd/palm.obj +++ /dev/null @@ -1,2267 +0,0 @@ -mtllib palm.mtl -v -8.741820 -3.191790 -4.954030 -v -11.682210 -3.191790 -4.954030 -v -11.589090 6.560420 -4.825820 -v -8.834950 6.560420 -4.825820 -v -12.590860 -3.191790 -2.157520 -v -12.440170 6.560450 -2.206490 -v -10.212040 -3.191790 -0.429220 -v -10.212040 6.560450 -0.587650 -v -7.833200 -3.191790 -2.157520 -v -7.983900 6.560450 -2.206490 -v -8.741820 -3.191790 -4.954030 -v -8.834950 6.560420 -4.825820 -v -11.431210 23.093100 -4.608510 -v -8.992820 23.093100 -4.608510 -v -8.992820 23.093100 -4.608510 -v -8.239340 23.093100 -2.289490 -v -10.212040 23.093100 -0.856250 -v -12.184720 23.093100 -2.289490 -v -11.431210 23.093100 -4.608510 -v -12.184720 23.093100 -2.289490 -v -11.933140 39.375481 -2.371230 -v -11.275730 39.375481 -4.394510 -v -8.992820 23.093100 -4.608510 -v -9.148310 39.375481 -4.394510 -v -8.239340 23.093100 -2.289490 -v -8.992820 23.093100 -4.608510 -v -9.148310 39.375481 -4.394510 -v -8.490920 39.375481 -2.371230 -v -10.212040 23.093100 -0.856250 -v -10.212040 39.375481 -1.120790 -v -11.275730 39.375481 -4.394510 -v -11.933140 39.375481 -2.371230 -v -11.680770 55.708988 -2.453230 -v -11.119750 55.708988 -4.179820 -v -9.148310 39.375481 -4.394510 -v -9.304320 55.708988 -4.179820 -v -8.490920 39.375481 -2.371230 -v -9.148310 39.375481 -4.394510 -v -9.304320 55.708988 -4.179820 -v -8.743320 55.708988 -2.453230 -v -10.212040 39.375481 -1.120790 -v -10.212040 55.708988 -1.386160 -v -11.119750 55.708988 -4.179820 -v -11.680770 55.708988 -2.453230 -v -11.505460 70.822510 -2.510200 -v -11.011420 70.822540 -4.030700 -v -9.304320 55.708988 -4.179820 -v -9.412670 70.822510 -4.030700 -v -8.743320 55.708988 -2.453230 -v -9.304320 55.708988 -4.179820 -v -9.412670 70.822510 -4.030700 -v -8.918610 70.822510 -2.510200 -v -10.212040 55.708988 -1.386160 -v -10.212040 70.822540 -1.570460 -v -11.399550 79.115936 -2.544620 -v -10.945960 79.115936 -3.940600 -v -9.478130 79.115936 -3.940600 -v -9.478130 79.115936 -3.940600 -v -9.024540 79.115936 -2.544620 -v -10.212040 79.115936 -1.681840 -v -10.212040 79.950951 -2.201070 -v -10.905720 79.950951 -2.705080 -v -10.640750 79.950951 -3.520520 -v -9.783340 79.950951 -3.520520 -v -9.783340 79.950951 -3.520520 -v -9.518370 79.950951 -2.705080 -v -10.212040 80.531479 -2.930470 -v -10.212040 80.531479 -2.930470 -v -10.212040 80.531479 -2.930470 -v -10.212040 80.531479 -2.930470 -v -10.212040 80.531479 -2.930470 -v -12.148660 75.590103 -3.939580 -v -11.770210 75.590103 -1.400440 -v -11.056630 77.740211 -2.101140 -v -11.261760 77.740211 -3.477440 -v -11.964280 75.576698 -1.540030 -v -13.280780 76.325607 -1.141150 -v -13.313390 75.223137 -1.843560 -v -9.850760 75.590103 -5.084130 -v -10.016210 77.740211 -4.097850 -v -8.052120 75.590103 -3.252400 -v -9.850760 75.590103 -5.084130 -v -10.016210 77.740211 -4.097850 -v -9.041270 77.740211 -3.104960 -v -9.238410 75.590103 -0.975750 -v -9.684290 77.740211 -1.870910 -v -11.501950 73.638901 -5.206900 -v -12.775670 73.638901 -2.407130 -v -11.452090 75.937866 -2.677330 -v -10.835970 75.937866 -4.031600 -v -8.445640 73.638901 -4.860690 -v -9.357600 75.937851 -3.864120 -v -7.830380 73.638901 -1.846980 -v -9.060020 75.937851 -2.406370 -v -10.506520 73.638901 -0.330600 -v -7.830380 73.638901 -1.846980 -v -9.060020 75.937851 -2.406370 -v -10.354480 75.937851 -1.672870 -v -11.781260 71.177238 -5.699800 -v -13.330740 71.177238 -2.293800 -v -11.448910 74.311249 -2.677960 -v -10.834390 74.311249 -4.028790 -v -8.063160 71.177238 -5.278640 -v -9.359780 74.311249 -3.861760 -v -7.314730 71.177238 -1.612380 -v -9.062960 74.311249 -2.407710 -v -10.570290 71.177238 0.232340 -v -7.314730 71.177238 -1.612380 -v -9.062960 74.311249 -2.407710 -v -10.354110 74.311249 -1.676080 -v -12.108110 70.794289 -2.314370 -v -10.212040 70.794289 -0.936800 -v -10.212040 72.944458 -1.746750 -v -11.337790 72.944458 -2.564660 -v -11.383870 70.794289 -4.543360 -v -10.907800 72.944458 -3.888080 -v -9.040190 70.794289 -4.543360 -v -9.516260 72.944458 -3.888080 -v -8.315930 70.794289 -2.314370 -v -9.040190 70.794289 -4.543360 -v -9.516260 72.944458 -3.888080 -v -9.086260 72.944458 -2.564660 -v -10.418260 80.108788 -2.291460 -v -7.914830 91.561493 -1.916270 -v -8.106080 87.816223 -7.981100 -v -9.113670 80.437813 -8.401480 -v -8.049300 79.713043 1.768580 -v -7.041740 87.091431 2.188950 -v 0.378670 99.755257 2.314850 -v 4.516830 105.921707 -2.486840 -v -1.415930 101.478828 -2.070570 -v -0.685670 100.480049 -7.855210 -v -4.341540 93.969101 2.396510 -v -5.405880 94.693893 -7.773550 -v -10.450240 79.353027 -2.180300 -v 0.522060 84.594177 -7.634160 -v -5.621690 81.815468 -12.169990 -v -11.984340 77.517242 -9.108880 -v -6.928840 77.790024 1.782230 -v -0.566190 82.088257 -1.278880 -v 12.956660 79.671028 -7.495460 -v 15.855080 75.237938 -14.892680 -v 11.441130 81.377327 -12.853990 -v 7.901180 79.398262 -18.386570 -v 6.602490 83.024361 -4.629910 -v 1.546950 82.751587 -15.521020 -v -10.449110 79.593880 -2.200340 -v -8.786270 86.174789 -13.669060 -v -15.983100 83.092773 -11.490330 -v -17.024361 78.031609 -5.038240 -v -5.182150 78.144302 -3.038770 -v -4.140900 83.205467 -9.490810 -v -1.626720 82.466003 -24.339680 -v -6.072970 78.775261 -31.366859 -v -6.914610 84.332458 -25.913361 -v -13.468930 82.353310 -26.339149 -v -2.865930 85.020126 -17.144360 -v -14.708110 84.907471 -19.143841 -v -10.447500 79.353081 -2.181240 -v -22.659451 84.241531 -0.041700 -v -17.912310 81.723457 6.054610 -v -10.818060 77.631462 4.934020 -v -12.691930 77.631462 -6.929230 -v -19.786230 81.723457 -5.808630 -v -34.411400 78.873352 -3.498510 -v -39.086380 74.400703 2.897720 -v -34.482719 80.677628 2.038780 -v -32.537510 78.873352 8.364740 -v -27.626089 82.429024 -4.570290 -v -25.752230 82.429024 7.292950 -v -10.450000 79.353241 -2.182790 -v -4.207280 83.083138 8.985120 -v -0.124230 80.918831 2.300430 -v -3.689790 77.503387 -4.329050 -v -14.267330 77.503387 1.359880 -v -10.701760 80.918808 7.989370 -v -3.841870 76.721588 20.744061 -v 3.534220 71.752296 22.660191 -v 1.484460 78.432442 19.123899 -v 6.735690 76.721588 15.055100 -v -6.927390 80.892807 15.007130 -v 3.650180 80.892838 9.318150 -v -10.484530 80.208168 -2.789290 -v -8.264590 86.714027 -1.806710 -v -4.877020 85.959503 -5.830510 -v -6.860510 79.978958 -6.809150 -v -10.608460 79.904968 1.239410 -v -8.624950 85.885513 2.218040 -v -2.430250 91.492760 5.154200 -v 5.141760 93.455292 4.206330 -v -1.374370 92.901314 1.292850 -v 1.317650 91.566742 -2.894360 -v -10.488420 80.208481 -2.788600 -v -11.818020 86.981163 -2.024870 -v -9.964640 86.586998 2.939540 -v -8.703450 80.366928 2.323500 -v -13.986630 80.001503 -4.802890 -v -15.247850 86.221558 -4.186840 -v -20.252180 92.701012 -0.809120 -v -22.832371 95.653458 6.025450 -v -17.243010 94.134552 1.817420 -v -14.968970 93.066452 6.317270 -v -10.486660 80.209053 -2.793340 -v -10.201660 87.533768 -2.681540 -v -15.597270 87.562866 -4.216930 -v -15.956780 80.841721 -4.337490 -v -6.598750 80.344887 -4.547040 -v -6.239210 87.066048 -4.426490 -v -5.909810 95.205879 -9.015310 -v -10.094850 99.811958 -14.535100 -v -9.996680 96.519096 -7.732550 -v -15.267860 95.702713 -8.805750 -v -10.447840 79.353531 -2.183430 -v -12.162680 81.843277 10.796030 -v -4.768830 81.274788 7.472080 -v -3.415930 78.634727 -0.243340 -v -15.165170 76.536728 -1.585720 -v -16.518070 79.176804 6.129730 -v -17.143970 73.701782 20.165020 -v -11.264260 69.320488 25.550640 -v -12.224120 76.229141 21.989660 -v -5.394730 75.799812 21.507380 -v -17.281670 78.402351 14.023560 -v -5.532440 80.500397 15.365940 -v -10.448340 78.988602 -2.170590 -v -12.118440 72.998093 8.286810 -v -4.844700 74.127213 5.890320 -v -3.627090 76.475281 -1.231170 -v -15.480860 76.908508 -3.115010 -v -16.698460 74.560463 4.006460 -v -18.177250 61.087479 10.213070 -v -13.171320 53.715092 12.647750 -v -13.069830 61.531490 12.976970 -v -6.323500 60.654221 12.096930 -v -17.597561 68.391251 8.245130 -v -5.743810 67.958023 10.128960 -v -10.445160 78.988602 -2.162650 -v -18.613319 72.998093 -8.902590 -v -20.234190 74.127213 -1.417720 -v -14.712260 76.475281 3.241380 -v -7.080300 76.908508 -6.022190 -v -12.602200 74.560463 -10.681280 -v -17.202959 61.087479 -15.101860 -v -21.839020 53.715092 -12.020530 -v -22.174259 61.531490 -12.099930 -v -24.834949 60.654190 -5.838270 -v -15.800350 68.391251 -13.604710 -v -23.432329 67.958023 -4.341120 -v -10.453630 78.988602 -2.163910 -v -0.503520 72.998093 -5.789120 -v -6.134270 74.127213 -10.979990 -v -12.949320 76.475281 -8.581340 -v -8.831980 76.908508 2.692880 -v -2.016920 74.560463 0.294250 -v 4.125650 61.087479 -1.431280 -v 3.819180 53.715092 -6.989450 -v 4.057500 61.531490 -7.238200 -v 0.008270 60.654221 -12.705530 -v 2.124150 68.391251 -0.981010 -v -1.993230 67.958023 -12.255220 -v -10.212040 78.394012 -2.895090 -v -7.612120 76.931534 -2.879970 -v -8.103770 75.653809 -6.254410 -v -10.212040 76.970337 -6.257560 -v -5.776710 52.995399 -6.228790 -v -6.810120 72.119919 -6.249440 -v -5.664410 72.863121 -2.856270 -v -4.429120 52.536209 -2.757860 -v -5.261710 48.188271 -2.736190 -v -5.694440 52.967369 0.971440 -v -6.740190 72.165291 0.946060 -v -10.212040 77.057243 0.936040 -v -8.073790 75.731819 0.939930 -v -10.212040 78.394012 -2.895090 -v -10.870340 76.931534 -5.410300 -v -14.002540 75.653809 -4.062030 -v -13.459960 76.970337 -2.024810 -v -14.580080 52.995399 -6.316450 -v -14.332550 72.119919 -5.312890 -v -11.351550 72.863121 -7.297820 -v -11.576220 52.536209 -8.516480 -v -11.339790 48.188271 -7.717850 -v -7.646470 52.967369 -8.259460 -v -7.400330 72.165291 -7.242800 -v -6.511430 77.057243 -3.886640 -v -7.061090 75.731819 -5.953040 -v -10.212040 78.394012 -2.895090 -v -12.471150 76.931534 -1.608200 -v -10.358160 75.653809 1.068300 -v -8.530770 76.970337 0.016920 -v -12.386280 52.995399 2.209650 -v -11.481000 72.119919 1.710820 -v -14.169780 72.863121 -0.654900 -v -15.288770 52.536209 -0.122460 -v -14.578580 48.188271 -0.557540 -v -16.057610 52.967369 -3.984790 -v -15.139290 72.165291 -4.485690 -v -12.127590 77.057243 -6.212940 -v -13.981320 75.731819 -5.147170 -v -10.449030 79.776321 -3.624460 -v 4.061790 78.828621 -3.436840 -v -1.555340 77.316338 -9.589430 -v -10.127600 77.015038 -9.589430 -v -10.127600 77.015038 3.539480 -v -1.555340 77.316368 3.539480 -v 8.374910 75.028549 -9.589430 -v 8.374910 75.028549 3.539480 -v 18.613110 71.493729 -3.226490 -v 16.755840 69.445122 -9.589430 -v 16.755840 69.445122 3.539480 -v 24.504049 64.781036 -3.113060 -v -10.382750 79.693977 -2.991720 -v -4.923210 89.814438 -7.231020 -v -9.596050 85.537811 -10.337990 -v -11.840350 79.131508 -8.508590 -v -4.612950 79.131477 0.357980 -v -2.368650 85.537811 -1.471420 -v -4.717650 90.595978 -14.314530 -v 2.509750 90.595978 -5.447930 -v 4.668570 92.821922 -14.813170 -v 1.243510 90.762527 -19.173660 -v 8.470930 90.762527 -10.307090 -v 9.665960 89.748108 -18.759130 -v -10.383910 79.692902 -2.992190 -v -12.487370 91.308434 -10.641540 -v -17.831390 86.400040 -7.046970 -v -16.874720 79.047302 -3.864470 -v -4.301570 79.047302 -7.643950 -v -5.258240 86.400040 -10.826450 -v -19.910860 92.205399 -13.964750 -v -7.337690 92.205399 -17.744200 -v -16.325190 94.760208 -24.139481 -v -22.451900 92.396568 -22.417879 -v -9.878720 92.396568 -26.197359 -v -18.320110 91.232262 -31.170010 -v -10.382750 79.451889 -2.970890 -v -20.713760 88.919243 -4.194820 -v -18.354980 84.583977 2.224950 -v -13.446620 78.198692 2.716890 -v -12.137380 78.198692 -10.346570 -v -17.045759 84.583977 -10.838500 -v -26.683260 88.562149 1.390310 -v -25.374010 88.562149 -11.673190 -v -35.069988 89.033699 -5.845000 -v -35.272121 86.707527 0.529530 -v -33.962891 86.707527 -12.533950 -v -41.320911 83.912048 -6.585490 -v -10.382780 79.692978 -2.992510 -v -15.875730 88.090973 6.864400 -v -8.847150 84.070648 6.773250 -v -6.232480 78.201691 1.892160 -v -17.805559 78.201691 -4.307240 -v -20.420259 84.070648 0.573820 -v -12.965080 87.205994 14.460550 -v -24.538151 87.205994 8.261090 -v -22.856251 86.783203 19.450121 -v -16.935070 84.511047 21.871731 -v -28.508150 84.511047 15.672330 -v -25.675690 81.067162 24.473230 -v -10.384330 79.692902 -2.992000 -v -3.638710 88.626831 5.524990 -v -0.912610 84.446777 -0.852120 -v -4.240810 78.316849 -4.908350 -v -14.390430 78.316849 3.419530 -v -11.062260 84.446777 7.475790 -v 4.516430 88.000298 5.764530 -v -5.633220 88.000298 14.092430 -v 5.356200 88.016678 16.819139 -v 9.925930 85.715202 12.357370 -v -0.223740 85.715202 20.685249 -v 9.092730 82.585922 21.551901 -v -10.386250 79.454521 -2.967280 -v -3.133020 81.582878 -12.614160 -v -9.950180 79.781288 -12.371520 -v -13.848240 77.376152 -7.038190 -v -4.612980 77.376152 -0.288250 -v -0.714910 79.781288 -5.621620 -v -5.220000 78.813362 -18.843390 -v 4.015240 78.813362 -12.093430 -v 3.653940 75.263268 -21.589479 -v -1.649940 73.752602 -23.727949 -v 7.585380 73.752602 -16.978041 -v 5.789330 69.279602 -24.343620 -v -10.387460 79.087418 -2.958080 -v -0.204540 81.215752 3.521070 -v -0.977800 79.414169 -3.256420 -v -6.598780 77.009033 -6.726880 -v -12.608270 77.009033 3.006450 -v -6.987280 79.414169 6.476900 -v 5.843110 78.446198 0.954870 -v -0.166440 78.446198 10.688220 -v 9.272570 74.896149 9.587740 -v 10.991110 73.385483 4.133330 -v 4.981620 73.385452 13.866680 -v 12.184770 68.912483 11.501960 -v -10.380120 79.087418 -2.958680 -v -19.551001 81.215721 4.887730 -v -12.843180 79.414169 6.127750 -v -7.882250 77.009033 1.765550 -v -15.435890 77.009033 -6.824820 -v -20.396851 79.414169 -2.462600 -v -18.863060 78.446198 11.421160 -v -26.416740 78.446198 2.830790 -v -28.121180 74.896149 12.179590 -v -23.406590 73.385483 15.416330 -v -30.960220 73.385452 6.825950 -v -30.802500 68.912483 14.405710 -v -10.380180 79.087418 -2.952580 -v -19.198620 81.215721 -11.193150 -v -19.684320 79.414169 -4.388960 -v -14.797030 77.009033 0.055590 -v -7.100810 77.009033 -8.407290 -v -11.988100 79.414169 -12.851830 -v -25.614889 78.446198 -9.782280 -v -17.918650 78.446228 -18.245131 -v -27.399099 74.896149 -18.898430 -v -30.090931 73.385483 -13.852850 -v -22.394739 73.385452 -22.315689 -v -29.909840 68.912483 -21.315310 -v -10.755630 79.186867 -2.686270 -v 2.398900 85.562592 -3.419560 -v -4.509570 88.462288 -8.517620 -v -13.943890 81.895462 -8.341330 -v -7.560740 76.470596 0.265350 -v -1.093210 80.894028 0.079310 -v 11.535460 79.417252 -2.117620 -v 18.087830 78.571411 -7.494910 -v 14.440770 82.885063 -5.498900 -v 14.403790 87.319748 -10.655130 -v 6.095640 81.890297 -0.665310 -v 6.030600 90.303146 -9.236670 -v -10.755630 79.186867 -2.686270 -v -15.480890 74.926613 10.495180 -v -10.421600 82.380318 9.509640 -v -5.969010 84.043053 -0.957950 -v -13.112090 74.671127 -3.280140 -v -16.076441 73.483208 3.877460 -v -16.415840 64.108109 12.736560 -v -12.755130 59.735760 19.064699 -v -15.341320 65.069778 18.197340 -v -12.367340 68.961220 22.916080 -v -17.414619 69.405502 9.777260 -v -12.861320 76.627419 18.224720 -v -10.755630 79.186867 -2.686270 -v -12.588760 84.773102 -13.821520 -v -14.093460 88.500038 -7.140940 -v -13.621520 82.983757 1.054490 -v -9.992570 76.177017 -5.820360 -v -10.389140 79.914398 -11.418720 -v -15.484810 79.572029 -21.274860 -v -21.441650 80.573174 -25.424740 -v -17.799271 83.415703 -23.140280 -v -20.523689 88.513603 -22.232639 -v -12.370740 81.056343 -17.263741 -v -16.600540 90.372398 -15.819940 -v -11.419690 74.171249 0.433670 -v -11.707220 72.935516 0.794230 -v -9.306920 72.935516 0.246390 -v -10.725520 74.683128 -0.436800 -v -11.707220 72.935516 -1.667800 -v -10.725520 74.683128 -0.436800 -v -9.955040 74.171249 -1.402910 -v -9.635900 72.935516 -1.803110 -v -9.635900 72.935516 -1.803110 -v -9.955040 74.171249 -1.402910 -v -11.419690 71.699783 0.433670 -v -9.722420 71.699783 0.046280 -v -11.419690 71.699783 -1.307230 -v -9.955040 71.699783 -1.402910 -v -9.955040 71.699783 -1.402910 -v -10.725520 71.187920 -0.436800 -v -10.725520 71.187920 -0.436800 -v -8.304090 75.355423 -0.362390 -v -8.139750 74.547180 0.666940 -v -6.131220 74.274117 -0.730530 -v -8.083860 75.285461 -1.565780 -v -8.945060 73.130959 -1.178940 -v -8.083860 75.285461 -1.565780 -v -7.569890 74.324608 -2.341430 -v -7.101460 73.089432 -2.131880 -v -7.101460 73.089432 -2.131880 -v -7.569890 74.324608 -2.341430 -v -7.687160 73.334251 0.919210 -v -6.266930 73.141159 -0.068940 -v -8.256620 72.332809 -0.386040 -v -6.952980 72.303436 -1.059860 -v -6.952980 72.303436 -1.059860 -v -7.211430 72.427101 0.246650 -v -7.211430 72.427101 0.246650 -v -10.058740 76.535217 1.075350 -v -9.894430 75.727013 2.104660 -v -7.885900 75.453918 0.707210 -v -9.838530 76.465263 -0.128040 -v -10.699740 74.310760 0.258800 -v -9.838530 76.465263 -0.128040 -v -9.324570 75.504410 -0.903690 -v -8.856140 74.269218 -0.694140 -v -8.856140 74.269218 -0.694140 -v -9.324570 75.504410 -0.903690 -v -9.441860 74.514038 2.356950 -v -8.021580 74.320961 1.368800 -v -10.011300 73.512611 1.051710 -v -8.707680 73.483269 0.377880 -v -8.707680 73.483269 0.377880 -v -8.966130 73.606903 1.684390 -v -8.966130 73.606903 1.684390 -v -11.508270 76.655746 -0.792050 -v -12.624970 75.982674 -0.592880 -v -11.138550 75.389008 1.277880 -v -10.313430 76.411049 -0.673490 -v -11.054840 74.391342 -1.624400 -v -10.313430 76.411049 -0.673490 -v -9.643210 75.322487 -0.279950 -v -9.987390 74.097168 0.131330 -v -9.987390 74.097168 0.131330 -v -9.643210 75.322487 -0.279950 -v -13.009360 74.786079 -0.192660 -v -11.958330 74.366318 1.130160 -v -11.899130 73.660858 -0.922050 -v -11.144310 73.452858 0.319450 -v -11.144310 73.452858 0.319450 -v -12.436320 73.766983 0.174190 -v -12.436320 73.766983 0.174190 -v -7.266050 78.108963 -1.409380 -v -6.310750 77.842491 -0.539840 -v -6.948690 75.677460 -1.523280 -v -8.321680 77.576157 -1.730760 -v -8.427330 77.322952 0.605460 -v -8.321680 77.576157 -1.730760 -v -8.946880 76.470871 -1.310600 -v -8.687750 75.525871 -0.400160 -v -8.687750 75.525871 -0.400160 -v -8.946880 76.470871 -1.310600 -v -6.015350 76.932861 0.368470 -v -6.466460 75.401947 -0.326940 -v -7.512000 76.565483 1.178310 -v -7.696150 75.294746 0.467230 -v -7.696150 75.294746 0.467230 -v -6.552930 75.912888 0.783480 -v -6.552930 75.912888 0.783480 -v -10.488450 78.862251 -0.284470 -v -9.986500 78.599892 0.906720 -v -8.212700 78.045181 -0.708080 -v -10.449500 78.319557 -1.382420 -v -10.729990 76.435783 -0.001850 -v -10.449500 78.319557 -1.382420 -v -9.859760 77.203278 -1.824200 -v -9.097420 76.253731 -1.270810 -v -9.097420 76.253731 -1.270810 -v -9.859760 77.203278 -1.824200 -v -9.237750 77.686142 1.493350 -v -7.983470 77.293907 0.351530 -v -9.763450 76.155899 0.850910 -v -8.609030 76.027161 -0.046380 -v -8.609030 76.027161 -0.046380 -v -8.680730 76.656303 1.131790 -v -8.680730 76.656303 1.131790 -v -10.880370 72.835274 -1.539190 -v -10.637940 72.002182 -0.545750 -v -8.496180 73.116959 -1.027140 -v -10.283950 73.173210 -2.554880 -v -9.871070 70.857651 -2.586260 -v -10.283950 73.173210 -2.554880 -v -9.105540 72.817123 -3.078010 -v -8.127960 71.976540 -2.721960 -v -8.127960 71.976540 -2.721960 -v -9.105540 72.817123 -3.078010 -v -9.698650 71.161926 -0.156520 -v -8.184220 71.950233 -0.496920 -v -9.156410 70.352638 -1.599370 -v -7.923830 71.143784 -1.695330 -v -7.923830 71.143784 -1.695330 -v -8.612720 70.806778 -0.599480 -v -8.612720 70.806778 -0.599480 -v -14.182590 77.384827 -5.188940 -v -14.065870 76.221703 -5.972820 -v -12.244550 76.005730 -4.091750 -v -13.340770 78.202888 -4.612770 -v -12.171700 77.841248 -6.804390 -v -13.340770 78.202888 -4.612770 -v -11.915440 78.241302 -4.548520 -v -10.859640 77.432899 -5.067170 -v -10.859640 77.432899 -5.067170 -v -11.915440 78.241302 -4.548520 -v -13.059020 75.394836 -6.505310 -v -11.771130 75.242119 -5.175180 -v -11.719640 76.540031 -7.093310 -v -10.791840 76.251289 -5.864890 -v -10.791840 76.251289 -5.864890 -v -11.751770 75.388611 -6.474400 -v -11.751770 75.388611 -6.474400 -v -13.309180 75.301147 -5.655020 -v -13.581750 73.935509 -5.450640 -v -12.678810 74.839027 -3.154850 -v -12.359530 76.121979 -5.288590 -v -10.992220 74.097038 -5.863680 -v -12.359530 76.121979 -5.288590 -v -11.178110 75.951019 -4.506150 -v -10.567960 74.854584 -3.825940 -v -10.567960 74.854584 -3.825940 -v -11.178110 75.951019 -4.506150 -v -13.017570 72.825043 -4.795210 -v -12.379100 73.463928 -3.171840 -v -11.186520 72.939262 -5.087260 -v -10.886520 73.474930 -3.646360 -v -10.886520 73.474930 -3.646360 -v -11.947180 72.620239 -4.072630 -v -11.947180 72.620239 -4.072630 -v -13.401780 77.872498 -3.969430 -v -14.247100 76.840393 -3.520840 -v -12.932310 77.664330 -1.400750 -v -12.169700 78.234718 -3.723210 -v -11.880750 75.743942 -3.837800 -v -12.169700 78.234718 -3.723210 -v -11.155590 77.706207 -2.869160 -v -11.070490 76.605217 -1.964850 -v -11.070490 76.605217 -1.964850 -v -11.155590 77.706207 -2.869160 -v -14.210490 75.742996 -2.640300 -v -12.537210 74.967659 -2.864400 -v -11.964280 75.576698 -1.540030 -v -13.313390 75.223137 -1.843560 -vt 0.008820 0.002480 -vt 0.208160 0.002480 -vt 0.208370 0.258850 -vt 0.009600 0.258850 -vt 0.407660 0.002480 -vt 0.407300 0.258850 -vt 0.607210 0.002480 -vt 0.606290 0.258850 -vt 0.806750 0.002480 -vt 0.805250 0.258850 -vt 0.996100 0.002480 -vt 0.994170 0.258850 -vt 0.208740 0.692300 -vt 0.010930 0.692300 -vt 0.990900 0.692300 -vt 0.802710 0.692300 -vt 0.604710 0.692300 -vt 0.406690 0.692300 -vt 0.208740 0.258850 -vt 0.406690 0.258850 -vt 0.406100 0.692300 -vt 0.209090 0.692300 -vt 0.010930 0.258850 -vt 0.012240 0.692300 -vt 0.802710 0.258850 -vt 0.990900 0.258850 -vt 0.987690 0.692300 -vt 0.800210 0.692300 -vt 0.604710 0.258850 -vt 0.603160 0.692300 -vt 0.209090 0.258850 -vt 0.406100 0.258850 -vt 0.405500 0.692300 -vt 0.209450 0.692300 -vt 0.012240 0.258850 -vt 0.013550 0.692300 -vt 0.800210 0.258850 -vt 0.987690 0.258850 -vt 0.984460 0.692300 -vt 0.797700 0.692300 -vt 0.603160 0.258850 -vt 0.601610 0.692300 -vt 0.209450 0.258850 -vt 0.405500 0.258850 -vt 0.405080 0.692300 -vt 0.209690 0.692300 -vt 0.013550 0.258850 -vt 0.014460 0.692300 -vt 0.797700 0.258850 -vt 0.984460 0.258850 -vt 0.982220 0.692300 -vt 0.795960 0.692300 -vt 0.601610 0.258850 -vt 0.600530 0.692300 -vt 0.404830 0.954180 -vt 0.209850 0.954180 -vt 0.015010 0.954180 -vt 0.980870 0.954180 -vt 0.794910 0.954180 -vt 0.599880 0.954180 -vt 0.599810 0.980550 -vt 0.404810 0.980550 -vt 0.209860 0.980550 -vt 0.015060 0.980550 -vt 0.980730 0.980550 -vt 0.794800 0.980550 -vt 0.502280 0.998880 -vt 0.307320 0.998880 -vt 0.112460 0.998880 -vt 0.892170 0.998880 -vt 0.697260 0.998880 -vt 0.829500 0.778690 -vt 0.829500 0.579130 -vt 0.979840 0.579200 -vt 0.979840 0.778660 -vt 0.794700 0.783380 -vt 0.774080 0.742110 -vt 0.813020 0.731860 -vt 0.829500 0.994840 -vt 0.979840 0.994710 -vt 0.829500 0.179900 -vt 0.829500 0.000130 -vt 0.979840 0.000470 -vt 0.979840 0.180170 -vt 0.829500 0.379510 -vt 0.979840 0.379670 -vt 0.829500 0.579130 -vt 0.829500 0.379510 -vt 0.979840 0.379670 -vt 0.979840 0.579200 -vt 0.829500 0.778690 -vt 0.979840 0.778660 -vt 0.829500 0.994840 -vt 0.979840 0.994710 -vt 0.829500 0.179900 -vt 0.829500 0.000130 -vt 0.979840 0.000470 -vt 0.979840 0.180170 -vt 0.829500 0.579130 -vt 0.829500 0.379510 -vt 0.979840 0.379670 -vt 0.979840 0.579200 -vt 0.829500 0.778690 -vt 0.979840 0.778660 -vt 0.829500 0.994840 -vt 0.979840 0.994710 -vt 0.829500 0.179900 -vt 0.829500 0.000130 -vt 0.979840 0.000470 -vt 0.979840 0.180170 -vt 0.829500 0.579130 -vt 0.829500 0.379510 -vt 0.979840 0.379670 -vt 0.979840 0.579200 -vt 0.829500 0.778690 -vt 0.979840 0.778660 -vt 0.829500 0.994840 -vt 0.979840 0.994710 -vt 0.829500 0.179900 -vt 0.829500 0.000130 -vt 0.979840 0.000470 -vt 0.979840 0.180170 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.624960 -vt 0.174010 0.627480 -vt 0.174010 0.754520 -vt 0.000000 0.754520 -vt 0.000000 0.532100 -vt 0.174010 0.532100 -vt 0.434010 0.532100 -vt 0.631440 0.634100 -vt 0.434010 0.631240 -vt 0.434010 0.754520 -vt 0.000000 0.624960 -vt 0.174010 0.627480 -vt 0.174010 0.754520 -vt 0.000000 0.754520 -vt 0.000000 0.532100 -vt 0.174010 0.532100 -vt 0.434010 0.532100 -vt 0.631440 0.634100 -vt 0.434010 0.631240 -vt 0.434010 0.754520 -vt 0.000000 0.624960 -vt 0.174010 0.627480 -vt 0.174010 0.754520 -vt 0.000000 0.754520 -vt 0.000000 0.532100 -vt 0.174010 0.532100 -vt 0.434010 0.532100 -vt 0.631440 0.634100 -vt 0.434010 0.631240 -vt 0.434010 0.754520 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.144590 -vt 0.075380 0.144170 -vt 0.075380 0.238670 -vt 0.000000 0.238760 -vt 0.684930 0.237960 -vt 0.193740 0.238540 -vt 0.193740 0.143510 -vt 0.684930 0.140750 -vt 0.793160 0.140140 -vt 0.684930 0.036310 -vt 0.193740 0.037020 -vt 0.000000 0.037300 -vt 0.075380 0.037190 -vt 0.000000 0.144590 -vt 0.075380 0.144170 -vt 0.075380 0.238670 -vt 0.000000 0.238760 -vt 0.684930 0.237960 -vt 0.193740 0.238540 -vt 0.193740 0.143510 -vt 0.684930 0.140750 -vt 0.793160 0.140140 -vt 0.684930 0.036310 -vt 0.193740 0.037020 -vt 0.000000 0.037300 -vt 0.075380 0.037190 -vt 0.000000 0.144590 -vt 0.075380 0.144170 -vt 0.075380 0.238670 -vt 0.000000 0.238760 -vt 0.684930 0.237960 -vt 0.193740 0.238540 -vt 0.193740 0.143510 -vt 0.684930 0.140750 -vt 0.793160 0.140140 -vt 0.684930 0.036310 -vt 0.193740 0.037020 -vt 0.000000 0.037300 -vt 0.075380 0.037190 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.409420 -vt 0.290980 0.405820 -vt 0.181390 0.523800 -vt 0.000000 0.523800 -vt 0.000000 0.272050 -vt 0.181390 0.272050 -vt 0.400580 0.523800 -vt 0.400580 0.272050 -vt 0.617220 0.401790 -vt 0.617220 0.523800 -vt 0.617220 0.272050 -vt 0.793160 0.399610 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.000000 0.857640 -vt 0.277830 0.861870 -vt 0.184840 0.999360 -vt 0.000000 0.999360 -vt 0.000000 0.755160 -vt 0.184840 0.755160 -vt 0.558700 0.755160 -vt 0.732550 0.868790 -vt 0.558700 0.866140 -vt 0.558700 0.999360 -vt 0.370830 0.755160 -vt 0.370830 0.999360 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.774080 0.742110 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.794700 0.783380 -vt 0.813020 0.731860 -vt 0.813280 0.634100 -vt 0.690400 0.682260 -vt 0.740540 0.682980 -vt 0.743120 0.744100 -vt 0.667800 0.731860 -vt 0.737960 0.621850 -vt 0.668060 0.634100 -vt 0.686380 0.582580 -vt 0.731280 0.555110 -vt 0.749800 0.810850 -vt 0.688820 0.792120 -vt 0.790680 0.683690 -vt 0.770550 0.625580 -vt 0.792260 0.573830 -vt 0.813280 0.634100 -vn 0.587709 0.016240 -0.808909 -vn -0.587709 0.016240 -0.808909 -vn -0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn -0.950930 0.016240 0.308980 -vn -0.950930 0.016240 0.308980 -vn 0.000000 0.016240 0.999868 -vn 0.000000 0.016240 0.999868 -vn 0.950930 0.016240 0.308980 -vn 0.950930 0.016240 0.308980 -vn 0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn -0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn 0.950930 0.016240 0.308980 -vn 0.000000 0.016240 0.999868 -vn -0.950930 0.016240 0.308980 -vn -0.587709 0.016240 -0.808909 -vn -0.950930 0.016240 0.308980 -vn -0.950930 0.016240 0.308980 -vn -0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn 0.950930 0.016240 0.308980 -vn 0.587709 0.016240 -0.808909 -vn 0.587709 0.016240 -0.808909 -vn 0.950930 0.016240 0.308980 -vn 0.000000 0.016240 0.999868 -vn 0.000000 0.016240 0.999868 -vn -0.587709 0.016240 -0.808909 -vn -0.950930 0.016240 0.308980 -vn -0.950959 0.014220 0.308990 -vn -0.587731 0.014220 -0.808931 -vn 0.587709 0.016240 -0.808909 -vn 0.587731 0.014220 -0.808931 -vn 0.950930 0.016240 0.308980 -vn 0.587709 0.016240 -0.808909 -vn 0.587731 0.014220 -0.808931 -vn 0.950959 0.014220 0.308990 -vn 0.000000 0.016240 0.999868 -vn 0.000000 0.014220 0.999899 -vn -0.587731 0.014220 -0.808931 -vn -0.950959 0.014220 0.308990 -vn -0.950979 0.012810 0.308990 -vn -0.587739 0.012810 -0.808949 -vn 0.587731 0.014220 -0.808931 -vn 0.587739 0.012810 -0.808949 -vn 0.950959 0.014220 0.308990 -vn 0.587731 0.014220 -0.808931 -vn 0.587739 0.012810 -0.808949 -vn 0.950979 0.012810 0.308990 -vn 0.000000 0.014220 0.999899 -vn 0.000000 0.012810 0.999918 -vn -0.910819 0.287800 0.295940 -vn -0.562918 0.287799 -0.774787 -vn 0.562918 0.287799 -0.774787 -vn 0.562918 0.287799 -0.774787 -vn 0.910819 0.287800 0.295940 -vn 0.000000 0.287800 0.957691 -vn 0.000000 0.669338 0.742958 -vn -0.706591 0.669341 0.229590 -vn -0.436701 0.669341 -0.601061 -vn 0.436698 0.669337 -0.601068 -vn 0.436698 0.669337 -0.601068 -vn 0.706591 0.669341 0.229590 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn -0.804106 0.421738 -0.418988 -vn -0.646969 0.421739 0.635269 -vn -0.646969 0.421739 0.635269 -vn -0.804106 0.421738 -0.418988 -vn 0.379561 -0.639991 0.668091 -vn -0.417319 -0.158070 0.894907 -vn -0.311249 -0.807108 0.501698 -vn 0.150000 0.421741 -0.894223 -vn 0.150000 0.421741 -0.894223 -vn 0.896810 0.421740 -0.133670 -vn 0.150000 0.421741 -0.894223 -vn 0.150000 0.421741 -0.894223 -vn 0.896810 0.421740 -0.133670 -vn 0.404260 0.421740 0.811609 -vn 0.404260 0.421740 0.811609 -vn -0.425050 0.506610 -0.750120 -vn -0.844753 0.506612 0.172441 -vn -0.844753 0.506612 0.172441 -vn -0.425050 0.506610 -0.750120 -vn 0.582062 0.506611 -0.636042 -vn 0.582062 0.506611 -0.636042 -vn 0.784777 0.506618 0.357019 -vn 0.784777 0.506618 0.357019 -vn -0.097040 0.506620 0.856691 -vn 0.784777 0.506618 0.357019 -vn 0.784777 0.506618 0.357019 -vn -0.097040 0.506620 0.856691 -vn -0.420341 0.522521 -0.741812 -vn -0.835400 0.522520 0.170530 -vn -0.835400 0.522520 0.170530 -vn -0.420341 0.522521 -0.741812 -vn 0.575611 0.522521 -0.629002 -vn 0.575611 0.522521 -0.629002 -vn 0.776090 0.522520 0.353070 -vn 0.776090 0.522520 0.353070 -vn -0.095960 0.522520 0.847210 -vn 0.776090 0.522520 0.353070 -vn 0.776090 0.522520 0.353070 -vn -0.095960 0.522520 0.847210 -vn -0.890002 0.352521 0.289181 -vn 0.000000 0.352521 0.935804 -vn 0.000000 0.352521 0.935804 -vn -0.890002 0.352521 0.289181 -vn -0.550051 0.352521 -0.757082 -vn -0.550051 0.352521 -0.757082 -vn 0.550051 0.352521 -0.757082 -vn 0.550051 0.352521 -0.757082 -vn 0.890002 0.352521 0.289181 -vn 0.550051 0.352521 -0.757082 -vn 0.550051 0.352521 -0.757082 -vn 0.890002 0.352521 0.289181 -vn -0.972214 0.174681 0.155841 -vn -0.912832 0.375701 0.159960 -vn -0.945921 0.276660 -0.169390 -vn -0.972083 0.187221 -0.141430 -vn -0.886280 0.146680 0.439310 -vn -0.851807 0.225749 0.472718 -vn -0.627200 0.631890 0.455340 -vn -0.586128 0.796557 0.148159 -vn -0.704612 0.693062 0.152270 -vn -0.710452 0.683832 -0.166230 -vn -0.780471 0.421651 0.461601 -vn -0.866420 0.473380 -0.158830 -vn -0.395690 0.896589 0.198890 -vn -0.068420 0.996725 0.043100 -vn -0.370500 0.918470 -0.138360 -vn -0.490370 0.871230 -0.022270 -vn -0.277860 0.869480 0.408410 -vn -0.113530 0.910740 0.397070 -vn 0.610518 0.791988 -0.004720 -vn 0.715540 0.620810 -0.320310 -vn 0.523110 0.818310 -0.238170 -vn 0.402880 0.793230 -0.456590 -vn 0.216829 0.953806 0.207939 -vn -0.014630 0.958529 -0.284620 -vn -0.064000 0.841248 0.536849 -vn -0.008420 0.981298 0.192310 -vn -0.328291 0.885302 0.329341 -vn -0.299861 0.820033 0.487472 -vn 0.175600 0.813241 0.554801 -vn 0.258770 0.870649 0.418340 -vn 0.336419 0.845727 -0.414208 -vn 0.136120 0.704320 -0.696710 -vn 0.094240 0.877283 -0.470631 -vn -0.153779 0.853737 -0.497478 -vn 0.288881 0.956252 0.046150 -vn -0.248369 0.967837 -0.040050 -vn 0.405950 0.908549 -0.098710 -vn 0.045400 0.998148 -0.040500 -vn 0.288360 0.932320 0.218240 -vn 0.436969 0.888458 0.140360 -vn 0.351168 0.875476 -0.331998 -vn 0.188810 0.910890 -0.366920 -vn -0.613551 0.769532 -0.177130 -vn -0.795674 0.597323 0.100540 -vn -0.594563 0.800923 0.070830 -vn -0.538240 0.782009 0.314260 -vn -0.182009 0.943627 -0.276479 -vn -0.095110 0.960775 0.260511 -vn -0.186979 0.942936 -0.275519 -vn -0.009720 0.998630 0.051420 -vn 0.151731 0.951404 -0.267971 -vn 0.027520 0.922313 -0.385461 -vn -0.390528 0.908376 -0.149469 -vn -0.368601 0.929421 0.017600 -vn 0.067880 0.713188 0.697678 -vn 0.382199 0.521218 0.763057 -vn 0.296959 0.742618 0.600278 -vn 0.507320 0.725400 0.465210 -vn -0.160040 0.927100 0.338930 -vn 0.318811 0.944364 0.080850 -vn -0.870652 0.347741 -0.347911 -vn -0.757339 0.581380 -0.297380 -vn -0.580541 0.555571 -0.595241 -vn -0.690164 0.333232 -0.642363 -vn -0.947107 0.320699 -0.011890 -vn -0.842704 0.537192 0.035700 -vn -0.466279 0.863828 0.190750 -vn -0.086240 0.996268 0.003440 -vn -0.355000 0.927559 -0.116660 -vn -0.204110 0.888260 -0.411500 -vn 0.748345 0.215831 -0.627214 -vn 0.671332 0.464051 -0.577901 -vn 0.846252 0.454521 -0.277971 -vn 0.919545 0.218081 -0.326922 -vn 0.487729 0.187790 -0.852558 -vn 0.415979 0.417739 -0.807747 -vn 0.131100 0.796881 -0.589741 -vn 0.127070 0.974848 -0.183100 -vn 0.353440 0.866790 -0.351790 -vn 0.536770 0.840440 -0.074420 -vn 0.070610 -0.019740 0.997309 -vn 0.079890 0.242859 0.966766 -vn -0.265669 0.247029 0.931878 -vn -0.272869 -0.003390 0.962045 -vn 0.405648 -0.033730 0.913407 -vn 0.415189 0.209480 0.885289 -vn 0.412310 0.662250 0.625640 -vn 0.088600 0.897053 0.432951 -vn 0.090230 0.725753 0.682013 -vn -0.242289 0.708667 0.662637 -vn -0.174600 0.949360 -0.261210 -vn -0.219471 0.969213 0.111620 -vn 0.096050 0.993439 -0.062070 -vn 0.064460 0.970797 -0.231079 -vn -0.403449 0.872368 -0.276049 -vn -0.481022 0.867743 -0.125060 -vn -0.458089 0.590959 0.664019 -vn -0.202250 0.426341 0.881662 -vn -0.223190 0.660971 0.716452 -vn 0.025650 0.689450 0.723879 -vn -0.486621 0.835082 0.256591 -vn 0.042400 0.947068 0.318219 -vn -0.062010 0.905672 0.419421 -vn -0.129120 0.642618 0.755228 -vn 0.165801 0.737452 0.654732 -vn 0.132830 0.886871 0.442511 -vn -0.254449 0.889288 0.380029 -vn -0.371990 0.742599 0.556929 -vn -0.438600 0.155370 0.885150 -vn -0.183650 -0.038990 0.982218 -vn -0.174520 0.156060 0.972208 -vn 0.103030 0.144690 0.984098 -vn -0.430391 0.445521 0.785032 -vn 0.134230 0.436401 0.889683 -vn -0.330121 0.905672 -0.266041 -vn -0.585590 0.642620 -0.494090 -vn -0.648441 0.737451 -0.188920 -vn -0.448790 0.886870 -0.109770 -vn -0.198639 0.889288 -0.411959 -vn -0.291560 0.742601 -0.602940 -vn -0.540731 0.155370 -0.826722 -vn -0.753622 -0.038990 -0.656151 -vn -0.749623 0.156061 -0.643203 -vn -0.900550 0.144690 -0.409970 -vn -0.458582 0.445522 -0.768903 -vn -0.834979 0.436400 -0.335210 -vn 0.396652 0.905674 -0.149741 -vn 0.722729 0.642619 -0.254370 -vn 0.491511 0.737451 -0.463231 -vn 0.322091 0.886873 -0.331231 -vn 0.455808 0.889285 0.037570 -vn 0.667537 0.742597 0.054260 -vn 0.986732 0.155370 -0.047120 -vn 0.947593 -0.038990 -0.317091 -vn 0.934408 0.156060 -0.320199 -vn 0.809847 0.144689 -0.568518 -vn 0.895254 0.445522 -0.005610 -vn 0.712170 0.436400 -0.549880 -vn 0.507559 0.861119 -0.029300 -vn 0.751858 0.658698 -0.028760 -vn 0.704806 0.614227 -0.354928 -vn 0.475837 0.803805 -0.357038 -vn 0.930068 -0.062000 -0.362119 -vn 0.916884 0.214481 -0.336632 -vn 0.972989 0.229510 -0.024860 -vn 0.997614 -0.065020 -0.023200 -vn 0.981886 -0.188139 -0.022450 -vn 0.945991 -0.060280 0.318540 -vn 0.931177 0.221429 0.289619 -vn 0.482590 0.822240 0.301710 -vn 0.715659 0.630229 0.301070 -vn -0.159670 0.861112 -0.482691 -vn -0.222380 0.658690 -0.718800 -vn -0.525249 0.614229 -0.588929 -vn -0.468029 0.803808 -0.367209 -vn -0.590501 -0.062000 -0.804652 -vn -0.562472 0.214481 -0.798513 -vn -0.275840 0.229510 -0.933401 -vn -0.280609 -0.065020 -0.957617 -vn -0.275819 -0.188139 -0.942617 -vn 0.062840 -0.060280 -0.996202 -vn 0.038750 0.221429 -0.974406 -vn 0.166520 0.822238 -0.544239 -vn 0.105590 0.630228 -0.769197 -vn -0.424909 0.861117 0.279159 -vn -0.636747 0.658697 0.400838 -vn -0.432918 0.614228 0.659777 -vn -0.233569 0.803808 0.547118 -vn -0.624400 -0.062000 0.778640 -vn -0.625732 0.214481 0.749972 -vn -0.830199 0.229510 0.508030 -vn -0.852359 -0.065020 0.518899 -vn -0.839110 -0.188140 0.510390 -vn -0.978522 -0.060280 0.197130 -vn -0.951232 0.221430 0.214770 -vn -0.568790 0.822240 -0.019990 -vn -0.770312 0.630232 0.097090 -vn 0.028180 0.999306 -0.024380 -vn 0.254080 0.966979 -0.019880 -vn 0.117660 0.918829 -0.376709 -vn 0.029080 0.938618 -0.343729 -vn 0.024310 0.954400 0.297540 -vn 0.117260 0.935621 0.332961 -vn 0.341719 0.870207 -0.354919 -vn 0.343141 0.882242 0.322341 -vn 0.627650 0.778411 -0.011490 -vn 0.590481 0.726711 -0.351031 -vn 0.589937 0.737227 0.329349 -vn 0.751662 0.659462 -0.010720 -vn -0.679101 0.510311 0.527641 -vn -0.462018 0.813087 0.354159 -vn -0.767529 0.613939 0.184330 -vn -0.815863 0.491922 0.303941 -vn -0.495431 0.493451 0.714881 -vn -0.369372 0.621574 0.690804 -vn -0.481581 0.876363 0.008240 -vn -0.128470 0.882800 0.451840 -vn 0.103680 0.990064 -0.094990 -vn -0.055000 0.956516 -0.286449 -vn 0.255759 0.961307 0.102350 -vn 0.331920 0.900460 -0.281070 -vn 0.228261 0.510312 0.829143 -vn 0.150849 0.813087 0.562258 -vn -0.122800 0.613941 0.779741 -vn -0.030710 0.491919 0.870099 -vn 0.471461 0.493451 0.730911 -vn 0.497351 0.621571 0.605221 -vn -0.176320 0.876361 0.448221 -vn 0.368519 0.882798 0.291309 -vn -0.048190 0.990064 -0.132101 -vn -0.285739 0.956516 -0.058570 -vn 0.192270 0.961308 -0.197280 -vn -0.132990 0.900459 -0.414110 -vn 0.712901 0.695251 0.091640 -vn 0.374530 0.925581 0.055020 -vn 0.513328 0.761767 0.395228 -vn 0.657027 0.669187 0.347138 -vn 0.719532 0.673282 -0.170191 -vn 0.586828 0.771827 -0.244779 -vn 0.135100 0.940122 0.312921 -vn 0.196531 0.947903 -0.250711 -vn -0.364450 0.930791 -0.028370 -vn -0.379561 0.898621 0.220030 -vn -0.326409 0.904387 -0.274849 -vn -0.628922 0.775532 -0.054840 -vn 0.323030 0.762570 -0.560480 -vn 0.150029 0.958296 -0.243229 -vn 0.524672 0.812203 -0.255041 -vn 0.539098 0.733667 -0.413649 -vn 0.084650 0.738789 -0.668599 -vn -0.039230 0.823128 -0.566499 -vn 0.296739 0.951857 0.076900 -vn -0.201071 0.960083 -0.194451 -vn -0.207819 0.890318 0.405149 -vn 0.017450 0.859261 0.511240 -vn -0.419891 0.865342 0.273631 -vn -0.325479 0.709658 0.624859 -vn -0.417530 0.730400 -0.540540 -vn -0.196679 0.943377 -0.267129 -vn -0.059880 0.788392 -0.612252 -vn -0.198440 0.702859 -0.683089 -vn -0.607780 0.707480 -0.360660 -vn -0.563429 0.798908 -0.210460 -vn 0.155261 0.947243 -0.280401 -vn -0.285901 0.955262 0.075730 -vn 0.267409 0.911297 0.313099 -vn 0.452452 0.879655 0.146611 -vn 0.065630 0.885589 0.459809 -vn 0.430880 0.742900 0.512290 -vn -0.155300 0.971620 0.178430 -vn 0.077800 0.987618 -0.136230 -vn -0.310330 0.937889 -0.155110 -vn -0.358242 0.933495 0.015820 -vn 0.058370 0.942626 0.328709 -vn 0.208250 0.951369 0.227000 -vn -0.050200 0.890969 -0.451280 -vn 0.421460 0.900561 -0.106590 -vn 0.419579 0.690599 -0.589089 -vn 0.188541 0.661604 -0.725764 -vn 0.619941 0.669271 -0.409571 -vn 0.502698 0.502998 -0.703057 -vn -0.190000 0.971618 -0.140920 -vn 0.141880 0.987618 0.066940 -vn 0.130440 0.937889 -0.321480 -vn -0.043700 0.933494 -0.355921 -vn -0.323159 0.942626 0.083810 -vn -0.210080 0.951369 0.225310 -vn 0.445991 0.890971 -0.085220 -vn 0.139120 0.900560 0.411870 -vn 0.620001 0.690602 0.372381 -vn 0.738252 0.661602 0.131400 -vn 0.456650 0.669270 0.586130 -vn 0.740102 0.503001 0.446361 -vn 0.190270 0.971619 -0.140550 -vn -0.105460 0.987618 0.116140 -vn 0.269360 0.937890 0.218650 -vn 0.353159 0.933496 0.062160 -vn 0.014230 0.942624 -0.333552 -vn -0.154120 0.951369 -0.266730 -vn -0.048760 0.890969 0.451439 -vn -0.434549 0.900558 0.012750 -vn -0.537239 0.690598 0.484199 -vn -0.341292 0.661603 0.667683 -vn -0.693950 0.669270 0.265540 -vn -0.643067 0.502998 0.577458 -vn 0.160850 0.971620 0.173440 -vn -0.127160 0.987618 -0.091880 -vn -0.187310 0.937891 0.292020 -vn -0.022460 0.933493 0.357891 -vn 0.333059 0.942626 -0.022980 -vn 0.247910 0.951371 -0.182850 -vn -0.454060 0.890969 0.001790 -vn -0.061040 0.900558 -0.430429 -vn -0.540990 0.690601 -0.480000 -vn -0.701522 0.661601 -0.264861 -vn -0.341130 0.669271 -0.660081 -vn -0.645447 0.502998 -0.574797 -vn -0.331739 0.643988 0.689368 -vn -0.022860 0.695521 0.718142 -vn -0.226739 0.736618 0.637168 -vn -0.348790 0.655801 0.669531 -vn -0.314420 0.631640 0.708640 -vn -0.159510 0.624232 0.764782 -vn 0.501600 0.431020 0.750080 -vn 0.729931 0.343771 0.590781 -vn 0.539170 0.521770 0.661099 -vn 0.567430 0.603860 0.559800 -vn 0.166630 0.627510 0.760570 -vn 0.104079 0.757916 0.643996 -vn -0.786041 0.600800 -0.145530 -vn -0.901417 0.424008 0.087550 -vn -0.797810 0.602900 0.003430 -vn -0.768791 0.623490 -0.142200 -vn -0.802648 0.577609 -0.148740 -vn -0.885487 0.459559 -0.068690 -vn -0.949810 -0.127800 0.285530 -vn -0.825760 -0.325470 0.460640 -vn -0.912508 -0.076410 0.401859 -vn -0.858775 -0.023310 0.511823 -vn -0.957003 0.240511 0.162171 -vn -0.887086 0.392218 0.243399 -vn 0.927207 0.363849 0.088890 -vn 0.885988 0.408369 -0.219680 -vn 0.882267 0.470718 -0.005410 -vn 0.917890 0.381400 0.109600 -vn 0.935757 0.346009 0.068100 -vn 0.941659 0.322850 -0.095110 -vn 0.683520 0.158880 -0.712430 -vn 0.448350 0.135560 -0.883519 -vn 0.623173 0.275231 -0.732054 -vn 0.551367 0.387468 -0.738826 -vn 0.849890 0.333600 -0.407920 -vn 0.805181 0.494720 -0.327010 -vn -0.463212 0.669362 0.580852 -vn -0.613721 0.176370 0.769571 -vn 0.803454 0.138881 0.578943 -vn 0.027650 0.999016 -0.034670 -vn -0.743213 0.138881 -0.654482 -vn 0.027650 0.999016 -0.034670 -vn 0.440869 0.707109 -0.552839 -vn 0.614101 0.172870 -0.770062 -vn 0.614101 0.172870 -0.770062 -vn 0.440869 0.707109 -0.552839 -vn -0.428820 -0.725920 0.537730 -vn 0.571040 -0.706610 0.417870 -vn -0.534460 -0.706610 -0.463740 -vn 0.421359 -0.737078 -0.528368 -vn 0.421359 -0.737078 -0.528368 -vn -0.003210 -0.999987 0.004030 -vn -0.003210 -0.999987 0.004030 -vn -0.399271 0.873411 0.278810 -vn -0.351660 0.576170 0.737810 -vn 0.886992 0.460691 0.031760 -vn -0.235500 0.797540 -0.555400 -vn -0.926130 -0.275930 -0.257190 -vn -0.235500 0.797540 -0.555400 -vn 0.044500 0.267991 -0.962393 -vn 0.264679 -0.290829 -0.919437 -vn 0.264679 -0.290829 -0.919437 -vn 0.044500 0.267991 -0.962393 -vn -0.033760 -0.291849 0.955868 -vn 0.833521 -0.327480 0.444971 -vn -0.462439 -0.853989 0.238440 -vn 0.395192 -0.899334 -0.187141 -vn 0.395192 -0.899334 -0.187141 -vn 0.247990 -0.815529 0.522889 -vn 0.247990 -0.815529 0.522889 -vn -0.399272 0.873414 0.278801 -vn -0.351660 0.576170 0.737810 -vn 0.886992 0.460691 0.031760 -vn -0.235501 0.797532 -0.555412 -vn -0.926130 -0.275930 -0.257190 -vn -0.235501 0.797532 -0.555412 -vn 0.044490 0.267979 -0.962397 -vn 0.264679 -0.290829 -0.919437 -vn 0.264679 -0.290829 -0.919437 -vn 0.044490 0.267979 -0.962397 -vn -0.033760 -0.291849 0.955868 -vn 0.833521 -0.327480 0.444971 -vn -0.462439 -0.853989 0.238440 -vn 0.395192 -0.899334 -0.187141 -vn 0.395192 -0.899334 -0.187141 -vn 0.247990 -0.815529 0.522889 -vn 0.247990 -0.815529 0.522889 -vn -0.183299 0.928026 -0.324299 -vn -0.674381 0.692081 -0.257360 -vn 0.095740 0.399069 0.911909 -vn 0.641981 0.730581 -0.232620 -vn 0.149680 -0.243790 -0.958208 -vn 0.641981 0.730581 -0.232620 -vn 0.990884 0.133600 -0.017340 -vn 0.886991 -0.428241 0.172790 -vn 0.886991 -0.428241 0.172790 -vn 0.990884 0.133600 -0.017340 -vn -0.986967 -0.158790 0.026120 -vn -0.425171 -0.321441 0.846112 -vn -0.386609 -0.780939 -0.490579 -vn 0.088870 -0.941152 0.326091 -vn 0.088870 -0.941152 0.326091 -vn -0.611451 -0.753561 0.241400 -vn -0.611451 -0.753561 0.241400 -vn 0.192840 0.836612 -0.512731 -vn 0.615037 0.770336 -0.168259 -vn 0.371531 -0.497741 -0.783721 -vn -0.537289 0.444480 -0.716769 -vn -0.581230 0.562550 0.587970 -vn -0.537289 0.444480 -0.716769 -vn -0.863778 -0.156600 -0.478919 -vn -0.792221 -0.604571 -0.082940 -vn -0.792221 -0.604571 -0.082940 -vn -0.863778 -0.156600 -0.478919 -vn 0.859472 0.134170 0.493261 -vn 0.677099 -0.735639 0.019310 -vn -0.003900 0.022220 0.999746 -vn -0.110540 -0.822023 0.558622 -vn -0.110540 -0.822023 0.558622 -vn 0.509732 -0.472282 0.719113 -vn 0.509732 -0.472282 0.719113 -vn -0.537559 0.843208 0.005470 -vn -0.352679 0.779078 0.518319 -vn 0.753662 0.550491 -0.359101 -vn -0.493690 0.444090 -0.747700 -vn -0.868368 -0.486549 0.095960 -vn -0.493690 0.444090 -0.747700 -vn -0.168601 -0.162881 -0.972134 -vn 0.176110 -0.613320 -0.769950 -vn 0.176110 -0.613320 -0.769950 -vn -0.168601 -0.162881 -0.972134 -vn 0.183290 0.140280 0.972999 -vn 0.945119 0.013650 0.326440 -vn -0.214250 -0.727589 0.651699 -vn 0.553870 -0.828020 0.087240 -vn 0.553870 -0.828020 0.087240 -vn 0.504669 -0.472229 0.722709 -vn 0.504669 -0.472229 0.722709 -vn -0.881360 0.458930 0.112200 -vn -0.828017 0.127010 0.546128 -vn 0.413061 0.821552 0.392981 -vn -0.444170 0.676039 -0.587949 -vn -0.472871 -0.634242 -0.611662 -vn -0.444170 0.676039 -0.587949 -vn 0.196140 0.473279 -0.858799 -vn 0.661498 0.109440 -0.741918 -vn 0.661498 0.109440 -0.741918 -vn 0.196140 0.473279 -0.858799 -vn -0.172550 -0.486170 0.856660 -vn 0.676638 0.041640 0.735138 -vn 0.043410 -0.998912 0.017060 -vn 0.863023 -0.504252 -0.030340 -vn 0.863023 -0.504252 -0.030340 -vn 0.474248 -0.676997 0.562818 -vn 0.474248 -0.676997 0.562818 -vn -0.957108 0.251240 0.144300 -vn -0.965396 -0.203219 -0.163439 -vn -0.037470 -0.432889 0.900668 -vn -0.385510 0.768969 0.509969 -vn 0.006520 0.675490 -0.737340 -vn -0.385510 0.768969 0.509969 -vn 0.338281 0.775142 0.533592 -vn 0.817169 0.466960 0.337910 -vn 0.817169 0.466960 0.337910 -vn 0.338281 0.775142 0.533592 -vn -0.312789 -0.782737 -0.538038 -vn 0.311850 -0.919270 0.240190 -vn 0.343289 -0.127040 -0.930598 -vn 0.925244 -0.325271 -0.195251 -vn 0.925244 -0.325271 -0.195251 -vn 0.421368 -0.756307 -0.500448 -vn 0.421368 -0.756307 -0.500448 -vn -0.705606 0.435838 -0.558717 -vn -0.856310 -0.089600 -0.508630 -vn -0.483501 0.366941 0.794721 -vn -0.072750 0.949451 -0.305370 -vn 0.534932 -0.081110 -0.840993 -vn -0.072750 0.949451 -0.305370 -vn 0.522959 0.847208 0.093550 -vn 0.818228 0.417659 0.395049 -vn 0.818228 0.417659 0.395049 -vn 0.522959 0.847208 0.093550 -vn -0.504450 -0.859860 -0.078560 -vn -0.260911 -0.495691 0.828382 -vn 0.467030 -0.815940 -0.340770 -vn 0.656021 -0.516821 0.550031 -vn 0.656021 -0.516821 0.550031 -vn 0.106180 -0.940200 0.323650 -vn 0.106180 -0.940200 0.323650 -vn -0.460470 0.589770 -0.663430 -vn -0.827942 0.207710 -0.520931 -vn -0.231610 0.688749 0.687009 -vn 0.346071 0.803722 -0.484011 -vn 0.403361 -0.470882 -0.784583 -vn 0.346071 0.803722 -0.484011 -vn 0.850446 0.524048 -0.045990 -vn 0.935591 0.074250 0.345190 -vn 0.935591 0.074250 0.345190 -vn 0.850446 0.524048 -0.045990 -vn -0.838898 -0.540518 0.063960 -vn 0.036540 -0.986932 -0.156940 -vn 0.379561 -0.639991 0.668091 -vn -0.311249 -0.807108 0.501698 -usemtl trunk -f 1/1/1 2/2/2 3/3/3 4/4/4 -f 2/2/2 5/5/5 6/6/6 3/3/3 -f 5/5/5 7/7/7 8/8/8 6/6/6 -f 7/7/7 9/9/9 10/10/10 8/8/8 -f 9/9/9 11/11/11 12/12/12 10/10/10 -f 4/4/4 3/3/3 13/13/13 14/14/14 -f 10/10/10 12/12/12 15/15/15 16/16/16 -f 8/8/8 10/10/10 16/16/16 17/17/17 -f 6/6/6 8/8/8 17/17/17 18/18/18 -f 3/3/3 6/6/6 18/18/18 13/13/13 -f 19/19/19 20/20/20 21/21/21 22/22/22 -f 23/23/23 19/19/19 22/22/22 24/24/24 -f 25/25/25 26/26/26 27/27/27 28/28/28 -f 29/29/29 25/25/25 28/28/28 30/30/30 -f 20/20/20 29/29/29 30/30/30 21/21/21 -f 31/31/31 32/32/32 33/33/33 34/34/34 -f 35/35/35 31/31/31 34/34/34 36/36/36 -f 37/37/37 38/38/38 39/39/39 40/40/40 -f 41/41/41 37/37/37 40/40/40 42/42/42 -f 32/32/32 41/41/41 42/42/42 33/33/33 -f 43/43/43 44/44/44 45/45/45 46/46/46 -f 47/47/47 43/43/43 46/46/46 48/48/48 -f 49/49/49 50/50/50 51/51/51 52/52/52 -f 53/53/53 49/49/49 52/52/52 54/54/54 -f 44/44/44 53/53/53 54/54/54 45/45/45 -f 46/46/46 45/45/45 55/55/55 56/56/56 -f 48/48/48 46/46/46 56/56/56 57/57/57 -f 52/52/52 51/51/51 58/58/58 59/59/59 -f 54/54/54 52/52/52 59/59/59 60/60/60 -f 45/45/45 54/54/54 60/60/60 55/55/55 -f 55/55/55 60/60/60 61/61/61 62/62/62 -f 56/56/56 55/55/55 62/62/62 63/63/63 -f 57/57/57 56/56/56 63/63/63 64/64/64 -f 59/59/59 58/58/58 65/65/65 66/66/66 -f 60/60/60 59/59/59 66/66/66 61/61/61 -f 62/62/62 61/61/61 67/67/67 -f 63/63/63 62/62/62 68/68/68 -f 64/64/64 63/63/63 69/69/69 -f 66/66/66 65/65/65 70/70/70 -f 61/61/61 66/66/66 71/71/71 -usemtl branches -f 72/72/72 73/73/73 74/74/74 75/75/75 -f 76/76/76 77/77/77 78/78/78 -f 79/79/79 72/72/72 75/75/75 80/80/80 -f 81/81/81 82/82/82 83/83/83 84/84/84 -f 85/85/85 81/81/81 84/84/84 86/86/86 -f 87/87/87 88/88/88 89/89/89 90/90/90 -f 91/91/91 87/87/87 90/90/90 92/92/92 -f 93/93/93 91/91/91 92/92/92 94/94/94 -f 95/95/95 96/96/96 97/97/97 98/98/98 -f 88/88/88 95/95/95 98/98/98 89/89/89 -f 99/99/99 100/100/100 101/101/101 102/102/102 -f 103/103/103 99/99/99 102/102/102 104/104/104 -f 105/105/105 103/103/103 104/104/104 106/106/106 -f 107/107/107 108/108/108 109/109/109 110/110/110 -f 100/100/100 107/107/107 110/110/110 101/101/101 -f 111/111/111 112/112/112 113/113/113 114/114/114 -f 115/115/115 111/111/111 114/114/114 116/116/116 -f 117/117/117 115/115/115 116/116/116 118/118/118 -f 119/119/119 120/120/120 121/121/121 122/122/122 -f 112/112/112 119/119/119 122/122/122 113/113/113 -f 123/123/123 124/124/124 125/125/125 126/126/126 -f 127/127/127 128/128/128 124/124/124 123/123/123 -f 129/129/129 130/130/130 131/131/131 -f 132/132/132 131/131/131 130/130/130 -f 133/133/133 129/129/129 131/131/131 124/124/124 -f 134/134/134 124/124/124 131/131/131 132/132/132 -f 128/128/128 133/133/133 124/124/124 -f 125/125/125 124/124/124 134/134/134 -f 135/135/135 136/136/136 137/137/137 138/138/138 -f 139/139/139 140/140/140 136/136/136 135/135/135 -f 141/141/141 142/142/142 143/143/143 -f 144/144/144 143/143/143 142/142/142 -f 145/145/145 141/141/141 143/143/143 136/136/136 -f 146/146/146 136/136/136 143/143/143 144/144/144 -f 140/140/140 145/145/145 136/136/136 -f 137/137/137 136/136/136 146/146/146 -f 147/147/147 148/148/148 149/149/149 150/150/150 -f 151/151/151 152/152/152 148/148/148 147/147/147 -f 153/153/153 154/154/154 155/155/155 -f 156/156/156 155/155/155 154/154/154 -f 157/157/157 153/153/153 155/155/155 148/148/148 -f 158/158/158 148/148/148 155/155/155 156/156/156 -f 152/152/152 157/157/157 148/148/148 -f 149/149/149 148/148/148 158/158/158 -f 159/159/159 160/160/160 161/161/161 162/162/162 -f 163/163/163 164/164/164 160/160/160 159/159/159 -f 165/165/165 166/166/166 167/167/167 -f 168/168/168 167/167/167 166/166/166 -f 169/169/169 165/165/165 167/167/167 160/160/160 -f 170/170/170 160/160/160 167/167/167 168/168/168 -f 164/164/164 169/169/169 160/160/160 -f 161/161/161 160/160/160 170/170/170 -f 171/171/171 172/172/172 173/173/173 174/174/174 -f 175/175/175 176/176/176 172/172/172 171/171/171 -f 177/177/177 178/178/178 179/179/179 -f 180/180/180 179/179/179 178/178/178 -f 181/181/181 177/177/177 179/179/179 172/172/172 -f 182/182/182 172/172/172 179/179/179 180/180/180 -f 176/176/176 181/181/181 172/172/172 -f 173/173/173 172/172/172 182/182/182 -f 183/183/183 184/184/184 185/185/185 186/186/186 -f 187/187/187 188/188/188 184/184/184 183/183/183 -f 189/189/189 190/190/190 191/191/191 -f 192/192/192 191/191/191 190/190/190 -f 188/188/188 189/189/189 191/191/191 184/184/184 -f 185/185/185 184/184/184 191/191/191 192/192/192 -f 193/193/193 194/194/194 195/195/195 196/196/196 -f 197/197/197 198/198/198 194/194/194 193/193/193 -f 199/199/199 200/200/200 201/201/201 -f 202/202/202 201/201/201 200/200/200 -f 198/198/198 199/199/199 201/201/201 194/194/194 -f 195/195/195 194/194/194 201/201/201 202/202/202 -f 203/203/203 204/204/204 205/205/205 206/206/206 -f 207/207/207 208/208/208 204/204/204 203/203/203 -f 209/209/209 210/210/210 211/211/211 -f 212/212/212 211/211/211 210/210/210 -f 208/208/208 209/209/209 211/211/211 204/204/204 -f 205/205/205 204/204/204 211/211/211 212/212/212 -f 213/213/213 214/214/214 215/215/215 216/216/216 -f 217/217/217 218/218/218 214/214/214 213/213/213 -f 219/219/219 220/220/220 221/221/221 -f 222/222/222 221/221/221 220/220/220 -f 223/223/223 219/219/219 221/221/221 214/214/214 -f 224/224/224 214/214/214 221/221/221 222/222/222 -f 218/218/218 223/223/223 214/214/214 -f 215/215/215 214/214/214 224/224/224 -f 225/225/225 226/226/226 227/227/227 228/228/228 -f 229/229/229 230/230/230 226/226/226 225/225/225 -f 231/231/231 232/232/232 233/233/233 -f 234/234/234 233/233/233 232/232/232 -f 235/235/235 231/231/231 233/233/233 226/226/226 -f 236/236/236 226/226/226 233/233/233 234/234/234 -f 230/230/230 235/235/235 226/226/226 -f 227/227/227 226/226/226 236/236/236 -f 237/237/237 238/238/238 239/239/239 240/240/240 -f 241/241/241 242/242/242 238/238/238 237/237/237 -f 243/243/243 244/244/244 245/245/245 -f 246/246/246 245/245/245 244/244/244 -f 247/247/247 243/243/243 245/245/245 238/238/238 -f 248/248/248 238/238/238 245/245/245 246/246/246 -f 242/242/242 247/247/247 238/238/238 -f 239/239/239 238/238/238 248/248/248 -f 249/249/249 250/250/250 251/251/251 252/252/252 -f 253/253/253 254/254/254 250/250/250 249/249/249 -f 255/255/255 256/256/256 257/257/257 -f 258/258/258 257/257/257 256/256/256 -f 259/259/259 255/255/255 257/257/257 250/250/250 -f 260/260/260 250/250/250 257/257/257 258/258/258 -f 254/254/254 259/259/259 250/250/250 -f 251/251/251 250/250/250 260/260/260 -f 261/261/261 262/262/262 263/263/263 264/264/264 -f 265/265/265 266/266/266 267/267/267 268/268/268 -f 269/269/269 265/265/265 268/268/268 -f 268/268/268 270/270/270 269/269/269 -f 267/267/267 271/271/271 270/270/270 268/268/268 -f 272/272/272 273/273/273 262/262/262 261/261/261 -f 267/267/267 262/262/262 273/273/273 271/271/271 -f 266/266/266 263/263/263 262/262/262 267/267/267 -f 274/274/274 275/275/275 276/276/276 277/277/277 -f 278/278/278 279/279/279 280/280/280 281/281/281 -f 282/282/282 278/278/278 281/281/281 -f 281/281/281 283/283/283 282/282/282 -f 280/280/280 284/284/284 283/283/283 281/281/281 -f 285/285/285 286/286/286 275/275/275 274/274/274 -f 280/280/280 275/275/275 286/286/286 284/284/284 -f 279/279/279 276/276/276 275/275/275 280/280/280 -f 287/287/287 288/288/288 289/289/289 290/290/290 -f 291/291/291 292/292/292 293/293/293 294/294/294 -f 295/295/295 291/291/291 294/294/294 -f 294/294/294 296/296/296 295/295/295 -f 293/293/293 297/297/297 296/296/296 294/294/294 -f 298/298/298 299/299/299 288/288/288 287/287/287 -f 293/293/293 288/288/288 299/299/299 297/297/297 -f 292/292/292 289/289/289 288/288/288 293/293/293 -f 300/300/300 301/301/301 302/302/302 303/303/303 -f 304/304/304 305/305/305 301/301/301 300/300/300 -f 302/302/302 301/301/301 306/306/306 -f 301/301/301 305/305/305 307/307/307 -f 306/306/306 301/301/301 308/308/308 309/309/309 -f 301/301/301 307/307/307 310/310/310 308/308/308 -f 309/309/309 308/308/308 311/311/311 -f 308/308/308 310/310/310 311/311/311 -f 312/312/312 313/313/313 314/314/314 315/315/315 -f 316/316/316 317/317/317 313/313/313 312/312/312 -f 314/314/314 313/313/313 318/318/318 -f 313/313/313 317/317/317 319/319/319 -f 318/318/318 313/313/313 320/320/320 321/321/321 -f 313/313/313 319/319/319 322/322/322 320/320/320 -f 321/321/321 320/320/320 323/323/323 -f 320/320/320 322/322/322 323/323/323 -f 324/324/324 325/325/325 326/326/326 327/327/327 -f 328/328/328 329/329/329 325/325/325 324/324/324 -f 326/326/326 325/325/325 330/330/330 -f 325/325/325 329/329/329 331/331/331 -f 330/330/330 325/325/325 332/332/332 333/333/333 -f 325/325/325 331/331/331 334/334/334 332/332/332 -f 333/333/333 332/332/332 335/335/335 -f 332/332/332 334/334/334 335/335/335 -f 336/336/336 337/337/337 338/338/338 339/339/339 -f 340/340/340 341/341/341 337/337/337 336/336/336 -f 338/338/338 337/337/337 342/342/342 -f 337/337/337 341/341/341 343/343/343 -f 342/342/342 337/337/337 344/344/344 345/345/345 -f 337/337/337 343/343/343 346/346/346 344/344/344 -f 345/345/345 344/344/344 347/347/347 -f 344/344/344 346/346/346 347/347/347 -f 348/348/348 349/349/349 350/350/350 351/351/351 -f 352/352/352 353/353/353 349/349/349 348/348/348 -f 350/350/350 349/349/349 354/354/354 -f 349/349/349 353/353/353 355/355/355 -f 354/354/354 349/349/349 356/356/356 357/357/357 -f 349/349/349 355/355/355 358/358/358 356/356/356 -f 357/357/357 356/356/356 359/359/359 -f 356/356/356 358/358/358 359/359/359 -f 360/360/360 361/361/361 362/362/362 363/363/363 -f 364/364/364 365/365/365 361/361/361 360/360/360 -f 362/362/362 361/361/361 366/366/366 -f 361/361/361 365/365/365 367/367/367 -f 366/366/366 361/361/361 368/368/368 369/369/369 -f 361/361/361 367/367/367 370/370/370 368/368/368 -f 369/369/369 368/368/368 371/371/371 -f 368/368/368 370/370/370 371/371/371 -f 372/372/372 373/373/373 374/374/374 375/375/375 -f 376/376/376 377/377/377 373/373/373 372/372/372 -f 374/374/374 373/373/373 378/378/378 -f 373/373/373 377/377/377 379/379/379 -f 378/378/378 373/373/373 380/380/380 381/381/381 -f 373/373/373 379/379/379 382/382/382 380/380/380 -f 381/381/381 380/380/380 383/383/383 -f 380/380/380 382/382/382 383/383/383 -f 384/384/384 385/385/385 386/386/386 387/387/387 -f 388/388/388 389/389/389 385/385/385 384/384/384 -f 386/386/386 385/385/385 390/390/390 -f 385/385/385 389/389/389 391/391/391 -f 390/390/390 385/385/385 392/392/392 393/393/393 -f 385/385/385 391/391/391 394/394/394 392/392/392 -f 393/393/393 392/392/392 395/395/395 -f 392/392/392 394/394/394 395/395/395 -f 396/396/396 397/397/397 398/398/398 399/399/399 -f 400/400/400 401/401/401 397/397/397 396/396/396 -f 398/398/398 397/397/397 402/402/402 -f 397/397/397 401/401/401 403/403/403 -f 402/402/402 397/397/397 404/404/404 405/405/405 -f 397/397/397 403/403/403 406/406/406 404/404/404 -f 405/405/405 404/404/404 407/407/407 -f 404/404/404 406/406/406 407/407/407 -f 408/408/408 409/409/409 410/410/410 411/411/411 -f 412/412/412 413/413/413 409/409/409 408/408/408 -f 410/410/410 409/409/409 414/414/414 -f 409/409/409 413/413/413 415/415/415 -f 414/414/414 409/409/409 416/416/416 417/417/417 -f 409/409/409 415/415/415 418/418/418 416/416/416 -f 417/417/417 416/416/416 419/419/419 -f 416/416/416 418/418/418 419/419/419 -f 420/420/420 421/421/421 422/422/422 423/423/423 -f 424/424/424 425/425/425 421/421/421 420/420/420 -f 426/426/426 427/427/427 428/428/428 -f 429/429/429 428/428/428 427/427/427 -f 430/430/430 426/426/426 428/428/428 421/421/421 -f 431/431/431 421/421/421 428/428/428 429/429/429 -f 425/425/425 430/430/430 421/421/421 -f 422/422/422 421/421/421 431/431/431 -f 432/432/432 433/433/433 434/434/434 435/435/435 -f 436/436/436 437/437/437 433/433/433 432/432/432 -f 438/438/438 439/439/439 440/440/440 -f 441/441/441 440/440/440 439/439/439 -f 442/442/442 438/438/438 440/440/440 433/433/433 -f 443/443/443 433/433/433 440/440/440 441/441/441 -f 437/437/437 442/442/442 433/433/433 -f 434/434/434 433/433/433 443/443/443 -f 444/444/444 445/445/445 446/446/446 447/447/447 -f 448/448/448 449/449/449 445/445/445 444/444/444 -f 450/450/450 451/451/451 452/452/452 -f 453/453/453 452/452/452 451/451/451 -f 454/454/454 450/450/450 452/452/452 445/445/445 -f 455/455/455 445/445/445 452/452/452 453/453/453 -f 449/449/449 454/454/454 445/445/445 -f 446/446/446 445/445/445 455/455/455 -f 456/456/456 457/457/457 458/458/458 459/459/459 -f 460/460/460 457/457/457 456/456/456 461/461/461 -f 462/462/462 463/463/463 460/460/460 461/461/461 -f 458/458/458 464/464/464 465/465/465 459/459/459 -f 458/458/458 457/457/457 466/466/466 467/467/467 -f 457/457/457 460/460/460 468/468/468 466/466/466 -f 460/460/460 463/463/463 469/469/469 468/468/468 -f 464/464/464 458/458/458 467/467/467 470/470/470 -f 467/467/467 466/466/466 471/471/471 -f 466/466/466 468/468/468 472/472/472 -f 468/468/468 469/469/469 472/472/472 -f 470/470/470 467/467/467 471/471/471 -f 473/473/473 474/474/474 475/475/475 476/476/476 -f 477/477/477 474/474/474 473/473/473 478/478/478 -f 479/479/479 480/480/480 477/477/477 478/478/478 -f 475/475/475 481/481/481 482/482/482 476/476/476 -f 475/475/475 474/474/474 483/483/483 484/484/484 -f 474/474/474 477/477/477 485/485/485 483/483/483 -f 477/477/477 480/480/480 486/486/486 485/485/485 -f 481/481/481 475/475/475 484/484/484 487/487/487 -f 484/484/484 483/483/483 488/488/488 -f 483/483/483 485/485/485 489/489/489 -f 485/485/485 486/486/486 489/489/489 -f 487/487/487 484/484/484 488/488/488 -f 490/490/490 491/491/491 492/492/492 493/493/493 -f 494/494/494 491/491/491 490/490/490 495/495/495 -f 496/496/496 497/497/497 494/494/494 495/495/495 -f 492/492/492 498/498/498 499/499/499 493/493/493 -f 492/492/492 491/491/491 500/500/500 501/501/501 -f 491/491/491 494/494/494 502/502/502 500/500/500 -f 494/494/494 497/497/497 503/503/503 502/502/502 -f 498/498/498 492/492/492 501/501/501 504/504/504 -f 501/501/501 500/500/500 505/505/505 -f 500/500/500 502/502/502 506/506/506 -f 502/502/502 503/503/503 506/506/506 -f 504/504/504 501/501/501 505/505/505 -f 507/507/507 508/508/508 509/509/509 510/510/510 -f 511/511/511 508/508/508 507/507/507 512/512/512 -f 513/513/513 514/514/514 511/511/511 512/512/512 -f 509/509/509 515/515/515 516/516/516 510/510/510 -f 509/509/509 508/508/508 517/517/517 518/518/518 -f 508/508/508 511/511/511 519/519/519 517/517/517 -f 511/511/511 514/514/514 520/520/520 519/519/519 -f 515/515/515 509/509/509 518/518/518 521/521/521 -f 518/518/518 517/517/517 522/522/522 -f 517/517/517 519/519/519 523/523/523 -f 519/519/519 520/520/520 523/523/523 -f 521/521/521 518/518/518 522/522/522 -f 524/524/524 525/525/525 526/526/526 527/527/527 -f 528/528/528 525/525/525 524/524/524 529/529/529 -f 530/530/530 531/531/531 528/528/528 529/529/529 -f 526/526/526 532/532/532 533/533/533 527/527/527 -f 526/526/526 525/525/525 534/534/534 535/535/535 -f 525/525/525 528/528/528 536/536/536 534/534/534 -f 528/528/528 531/531/531 537/537/537 536/536/536 -f 532/532/532 526/526/526 535/535/535 538/538/538 -f 535/535/535 534/534/534 539/539/539 -f 534/534/534 536/536/536 540/540/540 -f 536/536/536 537/537/537 540/540/540 -f 538/538/538 535/535/535 539/539/539 -f 541/541/541 542/542/542 543/543/543 544/544/544 -f 545/545/545 542/542/542 541/541/541 546/546/546 -f 547/547/547 548/548/548 545/545/545 546/546/546 -f 543/543/543 549/549/549 550/550/550 544/544/544 -f 543/543/543 542/542/542 551/551/551 552/552/552 -f 542/542/542 545/545/545 553/553/553 551/551/551 -f 545/545/545 548/548/548 554/554/554 553/553/553 -f 549/549/549 543/543/543 552/552/552 555/555/555 -f 552/552/552 551/551/551 556/556/556 -f 551/551/551 553/553/553 557/557/557 -f 553/553/553 554/554/554 557/557/557 -f 555/555/555 552/552/552 556/556/556 -f 558/558/558 559/559/559 560/560/560 561/561/561 -f 562/562/562 559/559/559 558/558/558 563/563/563 -f 564/564/564 565/565/565 562/562/562 563/563/563 -f 560/560/560 566/566/566 567/567/567 561/561/561 -f 560/560/560 559/559/559 568/568/568 569/569/569 -f 559/559/559 562/562/562 570/570/570 568/568/568 -f 562/562/562 565/565/565 571/571/571 570/570/570 -f 566/566/566 560/560/560 569/569/569 572/572/572 -f 569/569/569 568/568/568 573/573/573 -f 568/568/568 570/570/570 574/574/574 -f 570/570/570 571/571/571 574/574/574 -f 572/572/572 569/569/569 573/573/573 -f 575/575/575 576/576/576 577/577/577 578/578/578 -f 579/579/579 576/576/576 575/575/575 580/580/580 -f 581/581/581 582/582/582 579/579/579 580/580/580 -f 577/577/577 583/583/583 584/584/584 578/578/578 -f 577/577/577 576/576/576 585/585/585 586/586/586 -f 576/576/576 579/579/579 587/587/587 585/585/585 -f 579/579/579 582/582/582 588/588/588 587/587/587 -f 583/583/583 577/577/577 586/586/586 589/589/589 -f 586/586/586 585/585/585 590/590/590 -f 585/585/585 587/587/587 591/591/591 -f 587/587/587 588/588/588 591/591/591 -f 589/589/589 586/586/586 590/590/590 -f 592/592/592 593/593/593 594/594/594 595/595/595 -f 596/596/596 593/593/593 592/592/592 597/597/597 -f 598/598/598 599/599/599 596/596/596 597/597/597 -f 594/594/594 600/600/600 601/601/601 595/595/595 -f 594/594/594 593/593/593 602/602/602 603/603/603 -f 593/593/593 596/596/596 604/604/604 602/602/602 -f 596/596/596 599/599/599 605/605/605 604/604/604 -f 600/600/600 594/594/594 603/603/603 606/606/606 -f 603/603/603 602/602/602 607/607/607 -f 602/602/602 604/604/604 608/608/608 -f 604/604/604 605/605/605 608/608/608 -f 606/606/606 603/603/603 607/607/607 -f 609/609/609 610/610/610 611/611/611 612/612/612 -f 613/613/613 610/610/610 609/609/609 614/614/614 -f 615/615/615 616/616/616 613/613/613 614/614/614 -f 611/611/611 617/617/617 618/618/618 612/612/612 -f 611/611/611 610/610/610 619/619/619 77/77/77 -f 610/610/610 613/613/613 620/620/620 619/619/619 -f 613/613/613 616/616/616 621/621/621 620/620/620 -f 617/617/617 611/611/611 77/77/77 76/76/76 -f 77/77/77 619/619/619 78/78/78 -f 619/619/619 620/620/620 622/622/622 -f 620/620/620 621/621/621 622/622/622 -f 73/73/73 85/85/85 86/86/86 74/74/74 diff --git a/examples/assets/3d/dreampsd/palm_bark.JPG b/examples/assets/3d/dreampsd/palm_bark.JPG deleted file mode 100644 index bdc837a..0000000 Binary files a/examples/assets/3d/dreampsd/palm_bark.JPG and /dev/null differ diff --git a/examples/assets/3d/dreampsd/palm_leafs.JPG b/examples/assets/3d/dreampsd/palm_leafs.JPG deleted file mode 100644 index 9029598..0000000 Binary files a/examples/assets/3d/dreampsd/palm_leafs.JPG and /dev/null differ diff --git a/examples/assets/3d/palm/maps/palm_bark.jpg b/examples/assets/3d/palm/maps/palm_bark.jpg new file mode 100755 index 0000000..eb862aa Binary files /dev/null and b/examples/assets/3d/palm/maps/palm_bark.jpg differ diff --git a/examples/assets/3d/palm/maps/palm_bark_norm.jpg b/examples/assets/3d/palm/maps/palm_bark_norm.jpg new file mode 100755 index 0000000..b325503 Binary files /dev/null and b/examples/assets/3d/palm/maps/palm_bark_norm.jpg differ diff --git a/examples/assets/3d/palm/maps/palm_bark_spec.jpg b/examples/assets/3d/palm/maps/palm_bark_spec.jpg new file mode 100755 index 0000000..087ef5c Binary files /dev/null and b/examples/assets/3d/palm/maps/palm_bark_spec.jpg differ diff --git a/examples/assets/3d/dreampalm/palm_leafs.png b/examples/assets/3d/palm/maps/palm_leafs.png old mode 100644 new mode 100755 similarity index 77% rename from examples/assets/3d/dreampalm/palm_leafs.png rename to examples/assets/3d/palm/maps/palm_leafs.png index ade885d..cf9931e Binary files a/examples/assets/3d/dreampalm/palm_leafs.png and b/examples/assets/3d/palm/maps/palm_leafs.png differ diff --git a/examples/assets/3d/palm/maps/palm_leafs_spec.jpg b/examples/assets/3d/palm/maps/palm_leafs_spec.jpg new file mode 100755 index 0000000..cf6f4a4 Binary files /dev/null and b/examples/assets/3d/palm/maps/palm_leafs_spec.jpg differ diff --git a/examples/assets/3d/palm/mesh.bin b/examples/assets/3d/palm/mesh.bin new file mode 100644 index 0000000..c7c5d5e Binary files /dev/null and b/examples/assets/3d/palm/mesh.bin differ diff --git a/examples/assets/3d/palm/mesh.js b/examples/assets/3d/palm/mesh.js new file mode 100644 index 0000000..b86ab07 --- /dev/null +++ b/examples/assets/3d/palm/mesh.js @@ -0,0 +1,51 @@ +{ + "metadata": { + "formatVersion": 0.6, + "sourceFile": "palm.obj", + "generatedBy": "three-obj", + "vertices": 537, + "faces": 399, + "normals": 490, + "colors": 0, + "uvs": 150, + "materials": 3 + }, + + "materials": [{ + "DbgName": "coconuts", + "DbgIndex": 0, + "DbgColor": 15597568, + "colorDiffuse": [1, 1, 1], + "colorSpecular": [1, 1, 1], + "illumination": 2, + "specularCoef": 8, + "mapDiffuse": "maps/palm_leafs.png", + "mapSpecular": "maps/palm_leafs_spec.jpg", + "transparent" : false + }, { + "DbgName": "trunk", + "DbgIndex": 1, + "DbgColor": 15658734, + "colorDiffuse": [1, 1, 1], + "colorSpecular": [1, 1, 1], + "illumination": 2, + "specularCoef": 8, + "mapDiffuse": "maps/palm_bark.jpg", + "mapBump": "maps/palm_bark_norm.jpg", + "mapSpecular": "maps/palm_bark_spec.jpg", + "transparent" : false + }, { + "DbgName": "branches", + "DbgIndex": 2, + "DbgColor": 60928, + "colorDiffuse": [1, 1, 1], + "colorSpecular": [1, 1, 1], + "illumination": 2, + "specularCoef": 8, + "mapDiffuse": "maps/palm_leafs.png", + "mapSpecular": "maps/palm_leafs_spec.jpg", + "opacity" : 1.0, + "transparent" : true + }], + "buffers": "mesh.bin" +} diff --git a/examples/assets/3d/palm/palm leafs.png b/examples/assets/3d/palm/palm leafs.png deleted file mode 100644 index ade885d..0000000 Binary files a/examples/assets/3d/palm/palm leafs.png and /dev/null differ diff --git a/examples/assets/3d/palm/palm leafs_spec.png b/examples/assets/3d/palm/palm leafs_spec.png deleted file mode 100644 index f500de0..0000000 Binary files a/examples/assets/3d/palm/palm leafs_spec.png and /dev/null differ diff --git a/examples/assets/3d/palm/palm.mtl b/examples/assets/3d/palm/palm.mtl deleted file mode 100644 index e100338..0000000 --- a/examples/assets/3d/palm/palm.mtl +++ /dev/null @@ -1,38 +0,0 @@ -# -# Wavefront material file -# Converted by the DEEP Exploration Deep Exploration 5.5 5.5.4.2708 Release -# Right Hemisphere, LTD -# http://www.righthemisphere.com/ -# - -newmtl trunk -Ka 0.117647 0.117647 0.117647 -Kd 1 1 1 -Ks 1 1 1 -illum 2 -Ns 8 -map_Kd palm_bark.png -map_bump palm_bark_norm.png -bump palm_bark_norm.png -map_opacity -map_d -refl -map_kS palm_bark_spec.png -map_kA -map_Ns - -newmtl branches -Ka 0.117647 0.117647 0.117647 -Kd 1 1 1 -Ks 1 1 1 -illum 2 -Ns 8 -map_Kd palm leafs.png -map_bump -bump -map_opacity -map_d -refl -map_kS palm leafs_spec.png -map_kA -map_Ns diff --git a/examples/assets/3d/palm/palm.obj b/examples/assets/3d/palm/palm.obj deleted file mode 100644 index 533117d..0000000 --- a/examples/assets/3d/palm/palm.obj +++ /dev/null @@ -1,1588 +0,0 @@ -# -# Wavefront OBJ file -# Converted by the DEEP Exploration Deep Exploration 5.5 5.5.4.2708 Release -# Right Hemisphere, LTD -# http://www.righthemisphere.com/ -# -mtllib palm.mtl -# object trunk -g trunk -v -8.74182 -3.19179 -4.95403 -v -11.68221 -3.19179 -4.95403 -v -12.59086 -3.19179 -2.15752 -v -10.21204 -3.19179 -0.42922 -v -7.83320 -3.19179 -2.15752 -v -10.21204 80.53148 -2.93047 -v -11.58909 6.56042 -4.82582 -v -8.83495 6.56042 -4.82582 -v -7.98390 6.56045 -2.20649 -v -10.21204 6.56045 -0.58765 -v -12.44017 6.56045 -2.20649 -v -11.43121 23.09310 -4.60851 -v -8.99282 23.09310 -4.60851 -v -8.23934 23.09310 -2.28949 -v -10.21204 23.09310 -0.85625 -v -12.18472 23.09310 -2.28949 -v -11.27573 39.37548 -4.39451 -v -9.14831 39.37548 -4.39451 -v -8.49092 39.37548 -2.37123 -v -10.21204 39.37548 -1.12079 -v -11.93314 39.37548 -2.37123 -v -11.11975 55.70899 -4.17982 -v -9.30432 55.70899 -4.17982 -v -8.74332 55.70899 -2.45323 -v -10.21204 55.70899 -1.38616 -v -11.68077 55.70899 -2.45323 -v -11.01142 70.82254 -4.03070 -v -9.41267 70.82251 -4.03070 -v -8.91861 70.82251 -2.51020 -v -10.21204 70.82254 -1.57046 -v -11.50546 70.82251 -2.51020 -v -11.39955 79.11594 -2.54462 -v -10.94596 79.11594 -3.94060 -v -9.47813 79.11594 -3.94060 -v -9.02454 79.11594 -2.54462 -v -10.21204 79.11594 -1.68184 -v -10.90572 79.95095 -2.70508 -v -10.64075 79.95095 -3.52052 -v -9.78334 79.95095 -3.52052 -v -9.51837 79.95095 -2.70508 -v -10.21204 79.95095 -2.20107 -# 41 verticies -vt 0.00882 0.00248 -vt 0.20816 0.00248 -vt 0.20837 0.25885 -vt 0.00960 0.25885 -vt 0.40766 0.00248 -vt 0.40730 0.25885 -vt 0.60721 0.00248 -vt 0.60629 0.25885 -vt 0.80675 0.00248 -vt 0.80525 0.25885 -vt 0.99610 0.00248 -vt 0.99417 0.25885 -vt 0.20874 0.69230 -vt 0.01093 0.69230 -vt 0.99090 0.69230 -vt 0.80271 0.69230 -vt 0.60471 0.69230 -vt 0.40669 0.69230 -vt 0.20874 0.25885 -vt 0.40669 0.25885 -vt 0.40610 0.69230 -vt 0.20909 0.69230 -vt 0.01093 0.25885 -vt 0.01224 0.69230 -vt 0.80271 0.25885 -vt 0.99090 0.25885 -vt 0.98769 0.69230 -vt 0.80021 0.69230 -vt 0.60471 0.25885 -vt 0.60316 0.69230 -vt 0.20909 0.25885 -vt 0.40610 0.25885 -vt 0.40550 0.69230 -vt 0.20945 0.69230 -vt 0.01224 0.25885 -vt 0.01355 0.69230 -vt 0.80021 0.25885 -vt 0.98769 0.25885 -vt 0.98446 0.69230 -vt 0.79770 0.69230 -vt 0.60316 0.25885 -vt 0.60161 0.69230 -vt 0.20945 0.25885 -vt 0.40550 0.25885 -vt 0.40508 0.69230 -vt 0.20969 0.69230 -vt 0.01355 0.25885 -vt 0.01446 0.69230 -vt 0.79770 0.25885 -vt 0.98446 0.25885 -vt 0.98222 0.69230 -vt 0.79596 0.69230 -vt 0.60161 0.25885 -vt 0.60053 0.69230 -vt 0.40483 0.95418 -vt 0.20985 0.95418 -vt 0.01501 0.95418 -vt 0.98087 0.95418 -vt 0.79491 0.95418 -vt 0.59988 0.95418 -vt 0.59981 0.98055 -vt 0.40481 0.98055 -vt 0.20986 0.98055 -vt 0.01506 0.98055 -vt 0.98073 0.98055 -vt 0.79480 0.98055 -vt 0.50228 0.99888 -vt 0.30732 0.99888 -vt 0.11246 0.99888 -vt 0.89217 0.99888 -vt 0.69726 0.99888 -# 71 texture verticies -vn 0.58771 0.01624 -0.80891 -vn -0.58771 0.01624 -0.80891 -vn -0.95093 0.01624 0.30898 -vn 0.00000 0.01624 0.99987 -vn 0.95093 0.01624 0.30898 -vn -0.95096 0.01422 0.30899 -vn -0.58773 0.01422 -0.80893 -vn 0.58773 0.01422 -0.80893 -vn 0.95096 0.01422 0.30899 -vn 0.00000 0.01422 0.99990 -vn -0.95098 0.01281 0.30899 -vn -0.58774 0.01281 -0.80895 -vn 0.58774 0.01281 -0.80895 -vn 0.95098 0.01281 0.30899 -vn 0.00000 0.01281 0.99992 -vn -0.91082 0.28780 0.29594 -vn -0.56292 0.28780 -0.77479 -vn 0.56292 0.28780 -0.77479 -vn 0.91082 0.28780 0.29594 -vn 0.00000 0.28780 0.95769 -vn 0.00000 0.66934 0.74296 -vn -0.70659 0.66934 0.22959 -vn -0.43670 0.66934 -0.60106 -vn 0.43670 0.66934 -0.60107 -vn 0.70659 0.66934 0.22959 -vn 0.00000 1.00000 0.00000 -# 26 normals -usemtl trunk -f 1/1/1 2/2/2 7/3/2 8/4/1 -f 2/2/2 3/5/3 11/6/3 7/3/2 -f 3/5/3 4/7/4 10/8/4 11/6/3 -f 4/7/4 5/9/5 9/10/5 10/8/4 -f 5/9/5 1/11/1 8/12/1 9/10/5 -f 8/4/1 7/3/2 12/13/2 13/14/1 -f 9/10/5 8/12/1 13/15/1 14/16/5 -f 10/8/4 9/10/5 14/16/5 15/17/4 -f 11/6/3 10/8/4 15/17/4 16/18/3 -f 7/3/2 11/6/3 16/18/3 12/13/2 -f 12/19/2 16/20/3 21/21/3 17/22/2 -f 13/23/1 12/19/2 17/22/2 18/24/1 -f 14/25/5 13/26/1 18/27/1 19/28/5 -f 15/29/4 14/25/5 19/28/5 20/30/4 -f 16/20/3 15/29/4 20/30/4 21/21/3 -f 17/31/2 21/32/3 26/33/6 22/34/7 -f 18/35/1 17/31/2 22/34/7 23/36/8 -f 19/37/5 18/38/1 23/39/8 24/40/9 -f 20/41/4 19/37/5 24/40/9 25/42/10 -f 21/32/3 20/41/4 25/42/10 26/33/6 -f 22/43/7 26/44/6 31/45/11 27/46/12 -f 23/47/8 22/43/7 27/46/12 28/48/13 -f 24/49/9 23/50/8 28/51/13 29/52/14 -f 25/53/10 24/49/9 29/52/14 30/54/15 -f 26/44/6 25/53/10 30/54/15 31/45/11 -f 27/46/12 31/45/11 32/55/16 33/56/17 -f 28/48/13 27/46/12 33/56/17 34/57/18 -f 29/52/14 28/51/13 34/58/18 35/59/19 -f 30/54/15 29/52/14 35/59/19 36/60/20 -f 31/45/11 30/54/15 36/60/20 32/55/16 -f 32/55/16 36/60/20 41/61/21 37/62/22 -f 33/56/17 32/55/16 37/62/22 38/63/23 -f 34/57/18 33/56/17 38/63/23 39/64/24 -f 35/59/19 34/58/18 39/65/24 40/66/25 -f 36/60/20 35/59/19 40/66/25 41/61/21 -f 37/62/22 41/61/21 6/67/26 -f 38/63/23 37/62/22 6/68/26 -f 39/64/24 38/63/23 6/69/26 -f 40/66/25 39/65/24 6/70/26 -f 41/61/21 40/66/25 6/71/26 -# object branches -g branches -v -11.05663 77.74021 -2.10114 -v -11.26176 77.74021 -3.47744 -v -10.01621 77.74021 -4.09785 -v -9.04127 77.74021 -3.10496 -v -9.68429 77.74021 -1.87091 -v -9.23841 75.59010 -0.97575 -v -11.77021 75.59010 -1.40044 -v -12.14866 75.59010 -3.93958 -v -9.85076 75.59010 -5.08413 -v -8.05212 75.59010 -3.25240 -v -10.83597 75.93787 -4.03160 -v -9.35760 75.93785 -3.86412 -v -9.06002 75.93785 -2.40637 -v -10.35448 75.93785 -1.67287 -v -11.45209 75.93787 -2.67733 -v -12.77567 73.63890 -2.40713 -v -11.50195 73.63890 -5.20690 -v -8.44564 73.63890 -4.86069 -v -7.83038 73.63890 -1.84698 -v -10.50652 73.63890 -0.33060 -v -10.83439 74.31125 -4.02879 -v -9.35978 74.31125 -3.86176 -v -9.06296 74.31125 -2.40771 -v -10.35411 74.31125 -1.67608 -v -11.44891 74.31125 -2.67796 -v -13.33074 71.17724 -2.29380 -v -11.78126 71.17724 -5.69980 -v -8.06316 71.17724 -5.27864 -v -7.31473 71.17724 -1.61238 -v -10.57029 71.17724 0.23234 -v -11.33779 72.94446 -2.56466 -v -10.90780 72.94446 -3.88808 -v -9.51626 72.94446 -3.88808 -v -9.08626 72.94446 -2.56466 -v -10.21204 72.94446 -1.74675 -v -10.21204 70.79429 -0.93680 -v -12.10811 70.79429 -2.31437 -v -11.38387 70.79429 -4.54336 -v -9.04019 70.79429 -4.54336 -v -8.31593 70.79429 -2.31437 -v -9.11367 80.43781 -8.40148 -v -10.41826 80.10879 -2.29146 -v -8.04930 79.71304 1.76858 -v 4.51683 105.92171 -2.48684 -v 0.37867 99.75526 2.31485 -v -1.41593 101.47883 -2.07057 -v -0.68567 100.48005 -7.85521 -v -4.34154 93.96910 2.39651 -v -5.40588 94.69389 -7.77355 -v -7.91483 91.56149 -1.91627 -v -8.10608 87.81622 -7.98110 -v -7.04174 87.09143 2.18895 -v -11.98434 77.51724 -9.10888 -v -10.45024 79.35303 -2.18030 -v -6.92884 77.79002 1.78223 -v 15.85508 75.23794 -14.89268 -v 12.95666 79.67103 -7.49546 -v 11.44113 81.37733 -12.85399 -v 7.90118 79.39826 -18.38657 -v 6.60249 83.02436 -4.62991 -v 1.54695 82.75159 -15.52102 -v 0.52206 84.59418 -7.63416 -v -5.62169 81.81547 -12.16999 -v -0.56619 82.08826 -1.27888 -v -17.02436 78.03161 -5.03824 -v -10.44911 79.59388 -2.20034 -v -5.18215 78.14430 -3.03877 -v -6.07297 78.77526 -31.36686 -v -1.62672 82.46600 -24.33968 -v -6.91461 84.33246 -25.91336 -v -13.46893 82.35331 -26.33915 -v -2.86593 85.02013 -17.14436 -v -14.70811 84.90747 -19.14384 -v -8.78627 86.17479 -13.66906 -v -15.98310 83.09277 -11.49033 -v -4.14090 83.20547 -9.49081 -v -10.81806 77.63146 4.93402 -v -10.44750 79.35308 -2.18124 -v -12.69193 77.63146 -6.92923 -v -39.08638 74.40070 2.89772 -v -34.41140 78.87335 -3.49851 -v -34.48272 80.67763 2.03878 -v -32.53751 78.87335 8.36474 -v -27.62609 82.42902 -4.57029 -v -25.75223 82.42902 7.29295 -v -22.65945 84.24153 -0.04170 -v -17.91231 81.72346 6.05461 -v -19.78623 81.72346 -5.80863 -v -3.68979 77.50339 -4.32905 -v -10.45000 79.35324 -2.18279 -v -14.26733 77.50339 1.35988 -v 3.53422 71.75230 22.66019 -v -3.84187 76.72159 20.74406 -v 1.48446 78.43244 19.12390 -v 6.73569 76.72159 15.05510 -v -6.92739 80.89281 15.00713 -v 3.65018 80.89284 9.31815 -v -4.20728 83.08314 8.98512 -v -0.12423 80.91883 2.30043 -v -10.70176 80.91881 7.98937 -v -10.60846 79.90497 1.23941 -v -6.86051 79.97896 -6.80915 -v -10.48453 80.20817 -2.78929 -v 5.14176 93.45529 4.20633 -v -8.26459 86.71403 -1.80671 -v -2.43025 91.49276 5.15420 -v 1.31765 91.56674 -2.89436 -v -8.62495 85.88551 2.21804 -v -4.87702 85.95950 -5.83051 -v -1.37437 92.90131 1.29285 -v -13.98663 80.00150 -4.80289 -v -8.70345 80.36693 2.32350 -v -10.48842 80.20848 -2.78860 -v -22.83237 95.65346 6.02545 -v -11.81802 86.98116 -2.02487 -v -20.25218 92.70101 -0.80912 -v -14.96897 93.06645 6.31727 -v -15.24785 86.22156 -4.18684 -v -9.96464 86.58700 2.93954 -v -17.24301 94.13455 1.81742 -v -6.59875 80.34489 -4.54704 -v -15.95678 80.84172 -4.33749 -v -10.48666 80.20905 -2.79334 -v -10.09485 99.81196 -14.53510 -v -10.20166 87.53377 -2.68154 -v -5.90981 95.20588 -9.01531 -v -15.26786 95.70271 -8.80575 -v -6.23921 87.06605 -4.42649 -v -15.59727 87.56287 -4.21693 -v -9.99668 96.51910 -7.73255 -v -3.41593 78.63473 -0.24334 -v -10.44784 79.35353 -2.18343 -v -15.16517 76.53673 -1.58572 -v -11.26426 69.32049 25.55064 -v -17.14397 73.70178 20.16502 -v -12.22412 76.22914 21.98966 -v -5.39473 75.79981 21.50738 -v -17.28167 78.40235 14.02356 -v -5.53244 80.50040 15.36594 -v -12.16268 81.84328 10.79603 -v -4.76883 81.27479 7.47208 -v -16.51807 79.17680 6.12973 -v -3.62709 76.47528 -1.23117 -v -10.44834 78.98860 -2.17059 -v -15.48086 76.90851 -3.11501 -v -13.17132 53.71509 12.64775 -v -18.17725 61.08748 10.21307 -v -13.06983 61.53149 12.97697 -v -6.32350 60.65422 12.09693 -v -17.59756 68.39125 8.24513 -v -5.74381 67.95802 10.12896 -v -12.11844 72.99809 8.28681 -v -4.84470 74.12721 5.89032 -v -16.69846 74.56046 4.00646 -v -14.71226 76.47528 3.24138 -v -10.44516 78.98860 -2.16265 -v -7.08030 76.90851 -6.02219 -v -21.83902 53.71509 -12.02053 -v -17.20296 61.08748 -15.10186 -v -22.17426 61.53149 -12.09993 -v -24.83495 60.65419 -5.83827 -v -15.80035 68.39125 -13.60471 -v -23.43233 67.95802 -4.34112 -v -18.61332 72.99809 -8.90259 -v -20.23419 74.12721 -1.41772 -v -12.60220 74.56046 -10.68128 -v -12.94932 76.47528 -8.58134 -v -10.45363 78.98860 -2.16391 -v -8.83198 76.90851 2.69288 -v 3.81918 53.71509 -6.98945 -v 4.12565 61.08748 -1.43128 -v 4.05750 61.53149 -7.23820 -v 0.00827 60.65422 -12.70553 -v 2.12415 68.39125 -0.98101 -v -1.99323 67.95802 -12.25522 -v -0.50352 72.99809 -5.78912 -v -6.13427 74.12721 -10.97999 -v -2.01692 74.56046 0.29425 -v -10.21204 78.39401 -2.89509 -v -5.26171 48.18827 -2.73619 -v -4.42912 52.53621 -2.75786 -v -7.61212 76.93153 -2.87997 -v -5.69444 52.96737 0.97144 -v -6.74019 72.16529 0.94606 -v -10.21204 77.05724 0.93604 -v -5.77671 52.99540 -6.22879 -v -6.81012 72.11992 -6.24944 -v -10.21204 76.97034 -6.25756 -v -8.07379 75.73182 0.93993 -v -8.10377 75.65381 -6.25441 -v -5.66441 72.86312 -2.85627 -v -10.21204 78.39401 -2.89509 -v -11.33979 48.18827 -7.71785 -v -11.57622 52.53621 -8.51648 -v -10.87034 76.93153 -5.41030 -v -7.64647 52.96737 -8.25946 -v -7.40033 72.16529 -7.24280 -v -6.51143 77.05724 -3.88664 -v -14.58008 52.99540 -6.31645 -v -14.33255 72.11992 -5.31289 -v -13.45996 76.97034 -2.02481 -v -7.06109 75.73182 -5.95304 -v -14.00254 75.65381 -4.06203 -v -11.35155 72.86312 -7.29782 -v -10.21204 78.39401 -2.89509 -v -14.57858 48.18827 -0.55754 -v -15.28877 52.53621 -0.12246 -v -12.47115 76.93153 -1.60820 -v -16.05761 52.96737 -3.98479 -v -15.13929 72.16529 -4.48569 -v -12.12759 77.05724 -6.21294 -v -12.38628 52.99540 2.20965 -v -11.48100 72.11992 1.71082 -v -8.53077 76.97034 0.01692 -v -13.98132 75.73182 -5.14717 -v -10.35816 75.65381 1.06830 -v -14.16978 72.86312 -0.65490 -v -10.44903 79.77632 -3.62446 -v 24.50405 64.78104 -3.11306 -v -10.12760 77.01504 -9.58943 -v -10.12760 77.01504 3.53948 -v 4.06179 78.82862 -3.43684 -v -1.55534 77.31634 -9.58943 -v -1.55534 77.31637 3.53948 -v 8.37491 75.02855 -9.58943 -v 8.37491 75.02855 3.53948 -v 18.61311 71.49373 -3.22649 -v 16.75584 69.44512 -9.58943 -v 16.75584 69.44512 3.53948 -v -10.38275 79.69398 -2.99172 -v 9.66596 89.74811 -18.75913 -v -11.84035 79.13151 -8.50859 -v -4.61295 79.13148 0.35798 -v -4.92321 89.81444 -7.23102 -v -9.59605 85.53781 -10.33799 -v -2.36865 85.53781 -1.47142 -v -4.71765 90.59598 -14.31453 -v 2.50975 90.59598 -5.44793 -v 4.66857 92.82192 -14.81317 -v 1.24351 90.76253 -19.17366 -v 8.47093 90.76253 -10.30709 -v -10.38391 79.69290 -2.99219 -v -18.32011 91.23226 -31.17001 -v -16.87472 79.04730 -3.86447 -v -4.30157 79.04730 -7.64395 -v -12.48737 91.30843 -10.64154 -v -17.83139 86.40004 -7.04697 -v -5.25824 86.40004 -10.82645 -v -19.91086 92.20540 -13.96475 -v -7.33769 92.20540 -17.74420 -v -16.32519 94.76021 -24.13948 -v -22.45190 92.39657 -22.41788 -v -9.87872 92.39657 -26.19736 -v -10.38275 79.45189 -2.97089 -v -41.32091 83.91205 -6.58549 -v -13.44662 78.19869 2.71689 -v -12.13738 78.19869 -10.34657 -v -20.71376 88.91924 -4.19482 -v -18.35498 84.58398 2.22495 -v -17.04576 84.58398 -10.83850 -v -26.68326 88.56215 1.39031 -v -25.37401 88.56215 -11.67319 -v -35.06999 89.03370 -5.84500 -v -35.27212 86.70753 0.52953 -v -33.96289 86.70753 -12.53395 -v -10.38278 79.69298 -2.99251 -v -25.67569 81.06716 24.47323 -v -6.23248 78.20169 1.89216 -v -17.80556 78.20169 -4.30724 -v -15.87573 88.09097 6.86440 -v -8.84715 84.07065 6.77325 -v -20.42026 84.07065 0.57382 -v -12.96508 87.20599 14.46055 -v -24.53815 87.20599 8.26109 -v -22.85625 86.78320 19.45012 -v -16.93507 84.51105 21.87173 -v -28.50815 84.51105 15.67233 -v -10.38433 79.69290 -2.99200 -v 9.09273 82.58592 21.55190 -v -4.24081 78.31685 -4.90835 -v -14.39043 78.31685 3.41953 -v -3.63871 88.62683 5.52499 -v -0.91261 84.44678 -0.85212 -v -11.06226 84.44678 7.47579 -v 4.51643 88.00030 5.76453 -v -5.63322 88.00030 14.09243 -v 5.35620 88.01668 16.81914 -v 9.92593 85.71520 12.35737 -v -0.22374 85.71520 20.68525 -v -10.38625 79.45452 -2.96728 -v 5.78933 69.27960 -24.34362 -v -13.84824 77.37615 -7.03819 -v -4.61298 77.37615 -0.28825 -v -3.13302 81.58288 -12.61416 -v -9.95018 79.78129 -12.37152 -v -0.71491 79.78129 -5.62162 -v -5.22000 78.81336 -18.84339 -v 4.01524 78.81336 -12.09343 -v 3.65394 75.26327 -21.58948 -v -1.64994 73.75260 -23.72795 -v 7.58538 73.75260 -16.97804 -v -10.38746 79.08742 -2.95808 -v 12.18477 68.91248 11.50196 -v -6.59878 77.00903 -6.72688 -v -12.60827 77.00903 3.00645 -v -0.20454 81.21575 3.52107 -v -0.97780 79.41417 -3.25642 -v -6.98728 79.41417 6.47690 -v 5.84311 78.44620 0.95487 -v -0.16644 78.44620 10.68822 -v 9.27257 74.89615 9.58774 -v 10.99111 73.38548 4.13333 -v 4.98162 73.38545 13.86668 -v -10.38012 79.08742 -2.95868 -v -30.80250 68.91248 14.40571 -v -7.88225 77.00903 1.76555 -v -15.43589 77.00903 -6.82482 -v -19.55100 81.21572 4.88773 -v -12.84318 79.41417 6.12775 -v -20.39685 79.41417 -2.46260 -v -18.86306 78.44620 11.42116 -v -26.41674 78.44620 2.83079 -v -28.12118 74.89615 12.17959 -v -23.40659 73.38548 15.41633 -v -30.96022 73.38545 6.82595 -v -10.38018 79.08742 -2.95258 -v -29.90984 68.91248 -21.31531 -v -14.79703 77.00903 0.05559 -v -7.10081 77.00903 -8.40729 -v -19.19862 81.21572 -11.19315 -v -19.68432 79.41417 -4.38896 -v -11.98810 79.41417 -12.85183 -v -25.61489 78.44620 -9.78228 -v -17.91865 78.44623 -18.24513 -v -27.39910 74.89615 -18.89843 -v -30.09093 73.38548 -13.85285 -v -22.39474 73.38545 -22.31569 -v -13.94389 81.89546 -8.34133 -v -10.75563 79.18687 -2.68627 -v -7.56074 76.47060 0.26535 -v 18.08783 78.57141 -7.49491 -v 11.53546 79.41725 -2.11762 -v 14.44077 82.88506 -5.49890 -v 14.40379 87.31975 -10.65513 -v 6.09564 81.89030 -0.66531 -v 6.03060 90.30315 -9.23667 -v 2.39890 85.56259 -3.41956 -v -4.50957 88.46229 -8.51762 -v -1.09321 80.89403 0.07931 -v -5.96901 84.04305 -0.95795 -v -10.75563 79.18687 -2.68627 -v -13.11209 74.67113 -3.28014 -v -12.75513 59.73576 19.06470 -v -16.41584 64.10811 12.73656 -v -15.34132 65.06978 18.19734 -v -12.36734 68.96122 22.91608 -v -17.41462 69.40550 9.77726 -v -12.86132 76.62742 18.22472 -v -15.48089 74.92661 10.49518 -v -10.42160 82.38032 9.50964 -v -16.07644 73.48321 3.87746 -v -13.62152 82.98376 1.05449 -v -10.75563 79.18687 -2.68627 -v -9.99257 76.17702 -5.82036 -v -21.44165 80.57317 -25.42474 -v -15.48481 79.57203 -21.27486 -v -17.79927 83.41570 -23.14028 -v -20.52369 88.51360 -22.23264 -v -12.37074 81.05634 -17.26374 -v -16.60054 90.37240 -15.81994 -v -12.58876 84.77310 -13.82152 -v -14.09346 88.50004 -7.14094 -v -10.38914 79.91440 -11.41872 -v -11.41969 74.17125 0.43367 -v -9.95504 74.17125 -1.40291 -v -11.70722 72.93552 0.79423 -v -11.70722 72.93552 -1.66780 -v -9.63590 72.93552 -1.80311 -v -9.30692 72.93552 0.24639 -v -11.41969 71.69978 0.43367 -v -11.41969 71.69978 -1.30723 -v -9.95504 71.69978 -1.40291 -v -9.72242 71.69978 0.04628 -v -10.72552 74.68313 -0.43680 -v -10.72552 71.18792 -0.43680 -v -8.30409 75.35542 -0.36239 -v -7.56989 74.32461 -2.34143 -v -8.13975 74.54718 0.66694 -v -8.94506 73.13096 -1.17894 -v -7.10146 73.08943 -2.13188 -v -6.13122 74.27412 -0.73053 -v -7.68716 73.33425 0.91921 -v -8.25662 72.33281 -0.38604 -v -6.95298 72.30344 -1.05986 -v -6.26693 73.14116 -0.06894 -v -8.08386 75.28546 -1.56578 -v -7.21143 72.42710 0.24665 -v -10.05874 76.53522 1.07535 -v -9.32457 75.50441 -0.90369 -v -9.89443 75.72701 2.10466 -v -10.69974 74.31076 0.25880 -v -8.85614 74.26922 -0.69414 -v -7.88590 75.45392 0.70721 -v -9.44186 74.51404 2.35695 -v -10.01130 73.51261 1.05171 -v -8.70768 73.48327 0.37788 -v -8.02158 74.32096 1.36880 -v -9.83853 76.46526 -0.12804 -v -8.96613 73.60690 1.68439 -v -11.50827 76.65575 -0.79205 -v -9.64321 75.32249 -0.27995 -v -12.62497 75.98267 -0.59288 -v -11.05484 74.39134 -1.62440 -v -9.98739 74.09717 0.13133 -v -11.13855 75.38901 1.27788 -v -13.00936 74.78608 -0.19266 -v -11.89913 73.66086 -0.92205 -v -11.14431 73.45286 0.31945 -v -11.95833 74.36632 1.13016 -v -10.31343 76.41105 -0.67349 -v -12.43632 73.76698 0.17419 -v -7.26605 78.10896 -1.40938 -v -8.94688 76.47087 -1.31060 -v -6.31075 77.84249 -0.53984 -v -8.42733 77.32295 0.60546 -v -8.68775 75.52587 -0.40016 -v -6.94869 75.67746 -1.52328 -v -6.01535 76.93286 0.36847 -v -7.51200 76.56548 1.17831 -v -7.69615 75.29475 0.46723 -v -6.46646 75.40195 -0.32694 -v -8.32168 77.57616 -1.73076 -v -6.55293 75.91289 0.78348 -v -10.48845 78.86225 -0.28447 -v -9.85976 77.20328 -1.82420 -v -9.98650 78.59989 0.90672 -v -10.72999 76.43578 -0.00185 -v -9.09742 76.25373 -1.27081 -v -8.21270 78.04518 -0.70808 -v -9.23775 77.68614 1.49335 -v -9.76345 76.15590 0.85091 -v -8.60903 76.02716 -0.04638 -v -7.98347 77.29391 0.35153 -v -10.44950 78.31956 -1.38242 -v -8.68073 76.65630 1.13179 -v -10.88037 72.83527 -1.53919 -v -9.10554 72.81712 -3.07801 -v -10.63794 72.00218 -0.54575 -v -9.87107 70.85765 -2.58626 -v -8.12796 71.97654 -2.72196 -v -8.49618 73.11696 -1.02714 -v -9.69865 71.16193 -0.15652 -v -9.15641 70.35264 -1.59937 -v -7.92383 71.14378 -1.69533 -v -8.18422 71.95023 -0.49692 -v -10.28395 73.17321 -2.55488 -v -8.61272 70.80678 -0.59948 -v -14.18259 77.38483 -5.18894 -v -11.91544 78.24130 -4.54852 -v -14.06587 76.22170 -5.97282 -v -12.17170 77.84125 -6.80439 -v -10.85964 77.43290 -5.06717 -v -12.24455 76.00573 -4.09175 -v -13.05902 75.39484 -6.50531 -v -11.71964 76.54003 -7.09331 -v -10.79184 76.25129 -5.86489 -v -11.77113 75.24212 -5.17518 -v -13.34077 78.20289 -4.61277 -v -11.75177 75.38861 -6.47440 -v -13.30918 75.30115 -5.65502 -v -11.17811 75.95102 -4.50615 -v -13.58175 73.93551 -5.45064 -v -10.99222 74.09704 -5.86368 -v -10.56796 74.85458 -3.82594 -v -12.67881 74.83903 -3.15485 -v -13.01757 72.82504 -4.79521 -v -11.18652 72.93926 -5.08726 -v -10.88652 73.47493 -3.64636 -v -12.37910 73.46393 -3.17184 -v -12.35953 76.12198 -5.28859 -v -11.94718 72.62024 -4.07263 -v -13.40178 77.87250 -3.96943 -v -11.15559 77.70621 -2.86916 -v -14.24710 76.84039 -3.52084 -v -11.88075 75.74394 -3.83780 -v -11.07049 76.60522 -1.96485 -v -12.93231 77.66433 -1.40075 -v -14.21049 75.74300 -2.64030 -v -12.53721 74.96766 -2.86440 -v -11.96428 75.57670 -1.54003 -v -13.28078 76.32561 -1.14115 -v -12.16970 78.23472 -3.72321 -v -13.31339 75.22314 -1.84356 -# 493 verticies -vt 0.82950 0.57913 -vt 0.82950 0.37951 -vt 0.97984 0.37967 -vt 0.97984 0.57920 -vt 0.82950 0.77869 -vt 0.97984 0.77866 -vt 0.82950 0.99484 -vt 0.97984 0.99471 -vt 0.82950 0.17990 -vt 0.82950 0.00013 -vt 0.97984 0.00047 -vt 0.97984 0.18017 -vt 0.00000 0.85764 -vt 0.27783 0.86187 -vt 0.18484 0.99936 -vt 0.00000 0.99936 -vt 0.00000 0.75516 -vt 0.18484 0.75516 -vt 0.55870 0.75516 -vt 0.73255 0.86879 -vt 0.55870 0.86614 -vt 0.55870 0.99936 -vt 0.37083 0.75516 -vt 0.37083 0.99936 -vt 0.00000 0.62496 -vt 0.17401 0.62748 -vt 0.17401 0.75452 -vt 0.00000 0.75452 -vt 0.00000 0.53210 -vt 0.17401 0.53210 -vt 0.43401 0.53210 -vt 0.63144 0.63410 -vt 0.43401 0.63124 -vt 0.43401 0.75452 -vt 0.00000 0.14459 -vt 0.07538 0.14417 -vt 0.07538 0.23867 -vt 0.00000 0.23876 -vt 0.68493 0.23796 -vt 0.19374 0.23854 -vt 0.19374 0.14351 -vt 0.68493 0.14075 -vt 0.79316 0.14014 -vt 0.68493 0.03631 -vt 0.19374 0.03702 -vt 0.00000 0.03730 -vt 0.07538 0.03719 -vt 0.00000 0.40942 -vt 0.29098 0.40582 -vt 0.18139 0.52380 -vt 0.00000 0.52380 -vt 0.00000 0.27205 -vt 0.18139 0.27205 -vt 0.40058 0.52380 -vt 0.40058 0.27205 -vt 0.61722 0.40179 -vt 0.61722 0.52380 -vt 0.61722 0.27205 -vt 0.79316 0.39961 -vt 0.69040 0.68226 -vt 0.74054 0.68298 -vt 0.74312 0.74410 -vt 0.66780 0.73186 -vt 0.73796 0.62185 -vt 0.66806 0.63410 -vt 0.68638 0.58258 -vt 0.73128 0.55511 -vt 0.74980 0.81085 -vt 0.68882 0.79212 -vt 0.79068 0.68369 -vt 0.77408 0.74211 -vt 0.77055 0.62558 -vt 0.79226 0.57383 -vt 0.79470 0.78338 -vt 0.81302 0.73186 -vt 0.81328 0.63410 -# 76 texture verticies -vn -0.64697 0.42174 0.63527 -vn 0.40426 0.42174 0.81161 -vn -0.80411 0.42174 -0.41899 -vn 0.15000 0.42174 -0.89422 -vn 0.89681 0.42174 -0.13367 -vn -0.42505 0.50661 -0.75012 -vn -0.84475 0.50661 0.17244 -vn 0.58206 0.50661 -0.63604 -vn 0.78478 0.50662 0.35702 -vn -0.09704 0.50662 0.85669 -vn -0.42034 0.52252 -0.74181 -vn -0.83540 0.52252 0.17053 -vn 0.57561 0.52252 -0.62900 -vn 0.77609 0.52252 0.35307 -vn -0.09596 0.52252 0.84721 -vn -0.89000 0.35252 0.28918 -vn 0.00000 0.35252 0.93580 -vn -0.55005 0.35252 -0.75708 -vn 0.55005 0.35252 -0.75708 -vn 0.89000 0.35252 0.28918 -vn -0.97221 0.17468 0.15584 -vn -0.91283 0.37570 0.15996 -vn -0.94592 0.27666 -0.16939 -vn -0.97208 0.18722 -0.14143 -vn -0.88628 0.14668 0.43931 -vn -0.85181 0.22575 0.47272 -vn -0.62720 0.63189 0.45534 -vn -0.58613 0.79656 0.14816 -vn -0.70461 0.69306 0.15227 -vn -0.71045 0.68383 -0.16623 -vn -0.78047 0.42165 0.46160 -vn -0.86642 0.47338 -0.15883 -vn -0.39569 0.89659 0.19889 -vn -0.06842 0.99673 0.04310 -vn -0.37050 0.91847 -0.13836 -vn -0.49037 0.87123 -0.02227 -vn -0.27786 0.86948 0.40841 -vn -0.11353 0.91074 0.39707 -vn 0.61052 0.79199 -0.00472 -vn 0.71554 0.62081 -0.32031 -vn 0.52311 0.81831 -0.23817 -vn 0.40288 0.79323 -0.45659 -vn 0.21683 0.95381 0.20794 -vn -0.01463 0.95853 -0.28462 -vn -0.06400 0.84125 0.53685 -vn -0.00842 0.98130 0.19231 -vn -0.32829 0.88530 0.32934 -vn -0.29986 0.82003 0.48747 -vn 0.17560 0.81324 0.55480 -vn 0.25877 0.87065 0.41834 -vn 0.33642 0.84573 -0.41421 -vn 0.13612 0.70432 -0.69671 -vn 0.09424 0.87728 -0.47063 -vn -0.15378 0.85374 -0.49748 -vn 0.28888 0.95625 0.04615 -vn -0.24837 0.96784 -0.04005 -vn 0.40595 0.90855 -0.09871 -vn 0.04540 0.99815 -0.04050 -vn 0.28836 0.93232 0.21824 -vn 0.43697 0.88846 0.14036 -vn 0.35117 0.87548 -0.33200 -vn 0.18881 0.91089 -0.36692 -vn -0.61355 0.76953 -0.17713 -vn -0.79567 0.59732 0.10054 -vn -0.59456 0.80092 0.07083 -vn -0.53824 0.78201 0.31426 -vn -0.18201 0.94363 -0.27648 -vn -0.09511 0.96077 0.26051 -vn -0.18698 0.94294 -0.27552 -vn -0.00972 0.99863 0.05142 -vn 0.15173 0.95140 -0.26797 -vn 0.02752 0.92231 -0.38546 -vn -0.39053 0.90838 -0.14947 -vn -0.36860 0.92942 0.01760 -vn 0.06788 0.71319 0.69768 -vn 0.38220 0.52122 0.76306 -vn 0.29696 0.74262 0.60028 -vn 0.50732 0.72540 0.46521 -vn -0.16004 0.92710 0.33893 -vn 0.31881 0.94436 0.08085 -vn -0.87065 0.34774 -0.34791 -vn -0.75734 0.58138 -0.29738 -vn -0.58054 0.55557 -0.59524 -vn -0.69016 0.33323 -0.64236 -vn -0.94711 0.32070 -0.01189 -vn -0.84270 0.53719 0.03570 -vn -0.46628 0.86383 0.19075 -vn -0.08624 0.99627 0.00344 -vn -0.35500 0.92756 -0.11666 -vn -0.20411 0.88826 -0.41150 -vn 0.74834 0.21583 -0.62721 -vn 0.67133 0.46405 -0.57790 -vn 0.84625 0.45452 -0.27797 -vn 0.91954 0.21808 -0.32692 -vn 0.48773 0.18779 -0.85256 -vn 0.41598 0.41774 -0.80775 -vn 0.13110 0.79688 -0.58974 -vn 0.12707 0.97485 -0.18310 -vn 0.35344 0.86679 -0.35179 -vn 0.53677 0.84044 -0.07442 -vn 0.07061 -0.01974 0.99731 -vn 0.07989 0.24286 0.96677 -vn -0.26567 0.24703 0.93188 -vn -0.27287 -0.00339 0.96205 -vn 0.40565 -0.03373 0.91341 -vn 0.41519 0.20948 0.88529 -vn 0.41231 0.66225 0.62564 -vn 0.08860 0.89705 0.43295 -vn 0.09023 0.72575 0.68201 -vn -0.24229 0.70867 0.66264 -vn -0.17460 0.94936 -0.26121 -vn -0.21947 0.96921 0.11162 -vn 0.09605 0.99344 -0.06207 -vn 0.06446 0.97080 -0.23108 -vn -0.40345 0.87237 -0.27605 -vn -0.48102 0.86774 -0.12506 -vn -0.45809 0.59096 0.66402 -vn -0.20225 0.42634 0.88166 -vn -0.22319 0.66097 0.71645 -vn 0.02565 0.68945 0.72388 -vn -0.48662 0.83508 0.25659 -vn 0.04240 0.94707 0.31822 -vn -0.06201 0.90567 0.41942 -vn -0.12912 0.64262 0.75523 -vn 0.16580 0.73745 0.65473 -vn 0.13283 0.88687 0.44251 -vn -0.25445 0.88929 0.38003 -vn -0.37199 0.74260 0.55693 -vn -0.43860 0.15537 0.88515 -vn -0.18365 -0.03899 0.98222 -vn -0.17452 0.15606 0.97221 -vn 0.10303 0.14469 0.98410 -vn -0.43039 0.44552 0.78503 -vn 0.13423 0.43640 0.88968 -vn -0.33012 0.90567 -0.26604 -vn -0.58559 0.64262 -0.49409 -vn -0.64844 0.73745 -0.18892 -vn -0.44879 0.88687 -0.10977 -vn -0.19864 0.88929 -0.41196 -vn -0.29156 0.74260 -0.60294 -vn -0.54073 0.15537 -0.82672 -vn -0.75362 -0.03899 -0.65615 -vn -0.74962 0.15606 -0.64320 -vn -0.90055 0.14469 -0.40997 -vn -0.45858 0.44552 -0.76890 -vn -0.83498 0.43640 -0.33521 -vn 0.39665 0.90567 -0.14974 -vn 0.72273 0.64262 -0.25437 -vn 0.49151 0.73745 -0.46323 -vn 0.32209 0.88687 -0.33123 -vn 0.45581 0.88929 0.03757 -vn 0.66754 0.74260 0.05426 -vn 0.98673 0.15537 -0.04712 -vn 0.94759 -0.03899 -0.31709 -vn 0.93441 0.15606 -0.32020 -vn 0.80985 0.14469 -0.56852 -vn 0.89525 0.44552 -0.00561 -vn 0.71217 0.43640 -0.54988 -vn 0.50756 0.86112 -0.02930 -vn 0.75186 0.65870 -0.02876 -vn 0.70481 0.61423 -0.35493 -vn 0.47584 0.80381 -0.35704 -vn 0.93007 -0.06200 -0.36212 -vn 0.91688 0.21448 -0.33663 -vn 0.97299 0.22951 -0.02486 -vn 0.99761 -0.06502 -0.02320 -vn 0.98189 -0.18814 -0.02245 -vn 0.94599 -0.06028 0.31854 -vn 0.93118 0.22143 0.28962 -vn 0.48259 0.82224 0.30171 -vn 0.71566 0.63023 0.30107 -vn -0.15967 0.86111 -0.48269 -vn -0.22238 0.65869 -0.71880 -vn -0.52525 0.61423 -0.58893 -vn -0.46803 0.80381 -0.36721 -vn -0.59050 -0.06200 -0.80465 -vn -0.56247 0.21448 -0.79851 -vn -0.27584 0.22951 -0.93340 -vn -0.28061 -0.06502 -0.95762 -vn -0.27582 -0.18814 -0.94262 -vn 0.06284 -0.06028 -0.99620 -vn 0.03875 0.22143 -0.97441 -vn 0.16652 0.82224 -0.54424 -vn 0.10559 0.63023 -0.76920 -vn -0.42491 0.86112 0.27916 -vn -0.63675 0.65870 0.40084 -vn -0.43292 0.61423 0.65978 -vn -0.23357 0.80381 0.54712 -vn -0.62440 -0.06200 0.77864 -vn -0.62573 0.21448 0.74997 -vn -0.83020 0.22951 0.50803 -vn -0.85236 -0.06502 0.51890 -vn -0.83911 -0.18814 0.51039 -vn -0.97852 -0.06028 0.19713 -vn -0.95123 0.22143 0.21477 -vn -0.56879 0.82224 -0.01999 -vn -0.77031 0.63023 0.09709 -vn 0.02818 0.99931 -0.02438 -vn 0.25408 0.96698 -0.01988 -vn 0.11766 0.91883 -0.37671 -vn 0.02908 0.93862 -0.34373 -vn 0.02431 0.95440 0.29754 -vn 0.11726 0.93562 0.33296 -vn 0.34172 0.87021 -0.35492 -vn 0.34314 0.88224 0.32234 -vn 0.62765 0.77841 -0.01149 -vn 0.59048 0.72671 -0.35103 -vn 0.58994 0.73723 0.32935 -vn 0.75166 0.65946 -0.01072 -vn -0.67910 0.51031 0.52764 -vn -0.46202 0.81309 0.35416 -vn -0.76753 0.61394 0.18433 -vn -0.81586 0.49192 0.30394 -vn -0.49543 0.49345 0.71488 -vn -0.36937 0.62157 0.69080 -vn -0.48158 0.87636 0.00824 -vn -0.12847 0.88280 0.45184 -vn 0.10368 0.99006 -0.09499 -vn -0.05500 0.95652 -0.28645 -vn 0.25576 0.96131 0.10235 -vn 0.33192 0.90046 -0.28107 -vn 0.22826 0.51031 0.82914 -vn 0.15085 0.81309 0.56226 -vn -0.12280 0.61394 0.77974 -vn -0.03071 0.49192 0.87010 -vn 0.47146 0.49345 0.73091 -vn 0.49735 0.62157 0.60522 -vn -0.17632 0.87636 0.44822 -vn 0.36852 0.88280 0.29131 -vn -0.04819 0.99006 -0.13210 -vn -0.28574 0.95652 -0.05857 -vn 0.19227 0.96131 -0.19728 -vn -0.13299 0.90046 -0.41411 -vn 0.71290 0.69525 0.09164 -vn 0.37453 0.92558 0.05502 -vn 0.51333 0.76177 0.39523 -vn 0.65703 0.66919 0.34714 -vn 0.71953 0.67328 -0.17019 -vn 0.58683 0.77183 -0.24478 -vn 0.13510 0.94012 0.31292 -vn 0.19653 0.94790 -0.25071 -vn -0.36445 0.93079 -0.02837 -vn -0.37956 0.89862 0.22003 -vn -0.32641 0.90439 -0.27485 -vn -0.62892 0.77553 -0.05484 -vn 0.32303 0.76257 -0.56048 -vn 0.15003 0.95830 -0.24323 -vn 0.52467 0.81220 -0.25504 -vn 0.53910 0.73367 -0.41365 -vn 0.08465 0.73879 -0.66860 -vn -0.03923 0.82313 -0.56650 -vn 0.29674 0.95186 0.07690 -vn -0.20107 0.96008 -0.19445 -vn -0.20782 0.89032 0.40515 -vn 0.01745 0.85926 0.51124 -vn -0.41989 0.86534 0.27363 -vn -0.32548 0.70966 0.62486 -vn -0.41753 0.73040 -0.54054 -vn -0.19668 0.94338 -0.26713 -vn -0.05988 0.78839 -0.61225 -vn -0.19844 0.70286 -0.68309 -vn -0.60778 0.70748 -0.36066 -vn -0.56343 0.79891 -0.21046 -vn 0.15526 0.94724 -0.28040 -vn -0.28590 0.95526 0.07573 -vn 0.26741 0.91130 0.31310 -vn 0.45245 0.87965 0.14661 -vn 0.06563 0.88559 0.45981 -vn 0.43088 0.74290 0.51229 -vn -0.15530 0.97162 0.17843 -vn 0.07780 0.98762 -0.13623 -vn -0.31033 0.93789 -0.15511 -vn -0.35824 0.93349 0.01582 -vn 0.05837 0.94263 0.32871 -vn 0.20825 0.95137 0.22700 -vn -0.05020 0.89097 -0.45128 -vn 0.42146 0.90056 -0.10659 -vn 0.41958 0.69060 -0.58909 -vn 0.18854 0.66160 -0.72576 -vn 0.61994 0.66927 -0.40957 -vn 0.50270 0.50300 -0.70306 -vn -0.19000 0.97162 -0.14092 -vn 0.14188 0.98762 0.06694 -vn 0.13044 0.93789 -0.32148 -vn -0.04370 0.93349 -0.35592 -vn -0.32316 0.94263 0.08381 -vn -0.21008 0.95137 0.22531 -vn 0.44599 0.89097 -0.08522 -vn 0.13912 0.90056 0.41187 -vn 0.62000 0.69060 0.37238 -vn 0.73825 0.66160 0.13140 -vn 0.45665 0.66927 0.58613 -vn 0.74010 0.50300 0.44636 -vn 0.19027 0.97162 -0.14055 -vn -0.10546 0.98762 0.11614 -vn 0.26936 0.93789 0.21865 -vn 0.35316 0.93350 0.06216 -vn 0.01423 0.94262 -0.33355 -vn -0.15412 0.95137 -0.26673 -vn -0.04876 0.89097 0.45144 -vn -0.43455 0.90056 0.01275 -vn -0.53724 0.69060 0.48420 -vn -0.34129 0.66160 0.66768 -vn -0.69395 0.66927 0.26554 -vn -0.64307 0.50300 0.57746 -vn 0.16085 0.97162 0.17344 -vn -0.12716 0.98762 -0.09188 -vn -0.18731 0.93789 0.29202 -vn -0.02246 0.93349 0.35789 -vn 0.33306 0.94263 -0.02298 -vn 0.24791 0.95137 -0.18285 -vn -0.45406 0.89097 0.00179 -vn -0.06104 0.90056 -0.43043 -vn -0.54099 0.69060 -0.48000 -vn -0.70152 0.66160 -0.26486 -vn -0.34113 0.66927 -0.66008 -vn -0.64545 0.50300 -0.57480 -vn -0.33174 0.64399 0.68937 -vn -0.02286 0.69552 0.71814 -vn -0.22674 0.73662 0.63717 -vn -0.34879 0.65580 0.66953 -vn -0.31442 0.63164 0.70864 -vn -0.15951 0.62423 0.76478 -vn 0.50160 0.43102 0.75008 -vn 0.72993 0.34377 0.59078 -vn 0.53917 0.52177 0.66110 -vn 0.56743 0.60386 0.55980 -vn 0.16663 0.62751 0.76057 -vn 0.10408 0.75792 0.64400 -vn -0.78604 0.60080 -0.14553 -vn -0.90142 0.42401 0.08755 -vn -0.79781 0.60290 0.00343 -vn -0.76879 0.62349 -0.14220 -vn -0.80265 0.57761 -0.14874 -vn -0.88549 0.45956 -0.06869 -vn -0.94981 -0.12780 0.28553 -vn -0.82576 -0.32547 0.46064 -vn -0.91251 -0.07641 0.40186 -vn -0.85877 -0.02331 0.51182 -vn -0.95700 0.24051 0.16217 -vn -0.88709 0.39222 0.24340 -vn 0.92721 0.36385 0.08889 -vn 0.88599 0.40837 -0.21968 -vn 0.88227 0.47072 -0.00541 -vn 0.91789 0.38140 0.10960 -vn 0.93576 0.34601 0.06810 -vn 0.94166 0.32285 -0.09511 -vn 0.68352 0.15888 -0.71243 -vn 0.44835 0.13556 -0.88352 -vn 0.62317 0.27523 -0.73205 -vn 0.55137 0.38747 -0.73883 -vn 0.84989 0.33360 -0.40792 -vn 0.80518 0.49472 -0.32701 -vn -0.46321 0.66936 0.58085 -vn -0.61372 0.17637 0.76957 -vn 0.80345 0.13888 0.57894 -vn 0.02765 0.99902 -0.03467 -vn -0.74321 0.13888 -0.65448 -vn 0.44087 0.70711 -0.55284 -vn 0.61410 0.17287 -0.77006 -vn -0.42882 -0.72592 0.53773 -vn 0.57104 -0.70661 0.41787 -vn -0.53446 -0.70661 -0.46374 -vn 0.42136 -0.73708 -0.52837 -vn -0.00321 -0.99999 0.00403 -vn -0.39927 0.87341 0.27881 -vn -0.35166 0.57617 0.73781 -vn 0.88699 0.46069 0.03176 -vn -0.23550 0.79754 -0.55540 -vn -0.92613 -0.27593 -0.25719 -vn 0.04450 0.26799 -0.96239 -vn 0.26468 -0.29083 -0.91944 -vn -0.03376 -0.29185 0.95587 -vn 0.83352 -0.32748 0.44497 -vn -0.46244 -0.85399 0.23844 -vn 0.39519 -0.89933 -0.18714 -vn 0.24799 -0.81553 0.52289 -vn -0.39927 0.87341 0.27880 -vn -0.23550 0.79753 -0.55541 -vn 0.04449 0.26798 -0.96240 -vn -0.18330 0.92803 -0.32430 -vn -0.67438 0.69208 -0.25736 -vn 0.09574 0.39907 0.91191 -vn 0.64198 0.73058 -0.23262 -vn 0.14968 -0.24379 -0.95821 -vn 0.99088 0.13360 -0.01734 -vn 0.88699 -0.42824 0.17279 -vn -0.98697 -0.15879 0.02612 -vn -0.42517 -0.32144 0.84611 -vn -0.38661 -0.78094 -0.49058 -vn 0.08887 -0.94115 0.32609 -vn -0.61145 -0.75356 0.24140 -vn 0.19284 0.83661 -0.51273 -vn 0.61504 0.77034 -0.16826 -vn 0.37153 -0.49774 -0.78372 -vn -0.53729 0.44448 -0.71677 -vn -0.58123 0.56255 0.58797 -vn -0.86378 -0.15660 -0.47892 -vn -0.79222 -0.60457 -0.08294 -vn 0.85947 0.13417 0.49326 -vn 0.67710 -0.73564 0.01931 -vn -0.00390 0.02222 0.99975 -vn -0.11054 -0.82202 0.55862 -vn 0.50973 -0.47228 0.71911 -vn -0.53756 0.84321 0.00547 -vn -0.35268 0.77908 0.51832 -vn 0.75366 0.55049 -0.35910 -vn -0.49369 0.44409 -0.74770 -vn -0.86837 -0.48655 0.09596 -vn -0.16860 -0.16288 -0.97213 -vn 0.17611 -0.61332 -0.76995 -vn 0.18329 0.14028 0.97300 -vn 0.94512 0.01365 0.32644 -vn -0.21425 -0.72759 0.65170 -vn 0.55387 -0.82802 0.08724 -vn 0.50467 -0.47223 0.72271 -vn -0.88136 0.45893 0.11220 -vn -0.82802 0.12701 0.54613 -vn 0.41306 0.82155 0.39298 -vn -0.44417 0.67604 -0.58795 -vn -0.47287 -0.63424 -0.61166 -vn 0.19614 0.47328 -0.85880 -vn 0.66150 0.10944 -0.74192 -vn -0.17255 -0.48617 0.85666 -vn 0.67664 0.04164 0.73514 -vn 0.04341 -0.99891 0.01706 -vn 0.86302 -0.50425 -0.03034 -vn 0.47425 -0.67700 0.56282 -vn -0.95711 0.25124 0.14430 -vn -0.96540 -0.20322 -0.16344 -vn -0.03747 -0.43289 0.90067 -vn -0.38551 0.76897 0.50997 -vn 0.00652 0.67549 -0.73734 -vn 0.33828 0.77514 0.53359 -vn 0.81717 0.46696 0.33791 -vn -0.31279 -0.78274 -0.53804 -vn 0.31185 -0.91927 0.24019 -vn 0.34329 -0.12704 -0.93060 -vn 0.92524 -0.32527 -0.19525 -vn 0.42137 -0.75631 -0.50045 -vn -0.70561 0.43584 -0.55872 -vn -0.85631 -0.08960 -0.50863 -vn -0.48350 0.36694 0.79472 -vn -0.07275 0.94945 -0.30537 -vn 0.53493 -0.08111 -0.84099 -vn 0.52296 0.84721 0.09355 -vn 0.81823 0.41766 0.39505 -vn -0.50445 -0.85986 -0.07856 -vn -0.26091 -0.49569 0.82838 -vn 0.46703 -0.81594 -0.34077 -vn 0.65602 -0.51682 0.55003 -vn 0.10618 -0.94020 0.32365 -vn -0.46047 0.58977 -0.66343 -vn -0.82794 0.20771 -0.52093 -vn -0.23161 0.68875 0.68701 -vn 0.34607 0.80372 -0.48401 -vn 0.40336 -0.47088 -0.78458 -vn 0.85045 0.52405 -0.04599 -vn 0.93559 0.07425 0.34519 -vn -0.83890 -0.54052 0.06396 -vn -0.41732 -0.15807 0.89491 -vn 0.03654 -0.98693 -0.15694 -vn 0.37956 -0.63999 0.66809 -vn -0.31125 -0.80711 0.50170 -# 464 normals -usemtl branches -f 48/72/27 47/73/28 46/74/28 42/75/27 -f 49/76/29 48/72/27 42/75/27 43/77/29 -f 50/78/30 49/76/29 43/77/29 44/79/30 -f 51/80/31 50/81/30 44/82/30 45/83/31 -f 47/73/28 51/80/31 45/83/31 46/74/28 -f 58/72/32 57/73/33 56/74/33 52/75/32 -f 59/76/34 58/72/32 52/75/32 53/77/34 -f 60/78/35 59/76/34 53/77/34 54/79/35 -f 61/80/36 60/81/35 54/82/35 55/83/36 -f 57/73/33 61/80/36 55/83/36 56/74/33 -f 68/72/37 67/73/38 66/74/38 62/75/37 -f 69/76/39 68/72/37 62/75/37 63/77/39 -f 70/78/40 69/76/39 63/77/39 64/79/40 -f 71/80/41 70/81/40 64/82/40 65/83/41 -f 67/73/38 71/80/41 65/83/41 66/74/38 -f 78/72/42 77/73/43 76/74/43 72/75/42 -f 79/76/44 78/72/42 72/75/42 73/77/44 -f 80/78/45 79/76/44 73/77/44 74/79/45 -f 81/80/46 80/81/45 74/82/45 75/83/46 -f 77/73/43 81/80/46 75/83/46 76/74/43 -f 83/84/47 91/85/48 92/86/49 82/87/50 -f 84/88/51 93/89/52 91/85/48 83/84/47 -f 86/90/53 85/91/54 87/92/55 -f 88/93/56 87/92/55 85/91/54 -f 89/94/57 86/90/53 87/92/55 91/85/48 -f 90/95/58 91/85/48 87/92/55 88/93/56 -f 93/89/52 89/94/57 91/85/48 -f 92/86/49 91/85/48 90/95/58 -f 95/84/59 103/85/60 104/86/61 94/87/62 -f 96/88/63 105/89/64 103/85/60 95/84/59 -f 98/90/65 97/91/66 99/92/67 -f 100/93/68 99/92/67 97/91/66 -f 101/94/69 98/90/65 99/92/67 103/85/60 -f 102/95/70 103/85/60 99/92/67 100/93/68 -f 105/89/64 101/94/69 103/85/60 -f 104/86/61 103/85/60 102/95/70 -f 107/84/71 115/85/72 116/86/73 106/87/74 -f 108/88/75 117/89/76 115/85/72 107/84/71 -f 110/90/77 109/91/78 111/92/79 -f 112/93/80 111/92/79 109/91/78 -f 113/94/81 110/90/77 111/92/79 115/85/72 -f 114/95/82 115/85/72 111/92/79 112/93/80 -f 117/89/76 113/94/81 115/85/72 -f 116/86/73 115/85/72 114/95/82 -f 119/84/83 127/85/84 128/86/85 118/87/86 -f 120/88/87 129/89/88 127/85/84 119/84/83 -f 122/90/89 121/91/90 123/92/91 -f 124/93/92 123/92/91 121/91/90 -f 125/94/93 122/90/89 123/92/91 127/85/84 -f 126/95/94 127/85/84 123/92/91 124/93/92 -f 129/89/88 125/94/93 127/85/84 -f 128/86/85 127/85/84 126/95/94 -f 131/84/95 139/85/96 140/86/97 130/87/98 -f 132/88/99 141/89/100 139/85/96 131/84/95 -f 134/90/101 133/91/102 135/92/103 -f 136/93/104 135/92/103 133/91/102 -f 137/94/105 134/90/101 135/92/103 139/85/96 -f 138/95/106 139/85/96 135/92/103 136/93/104 -f 141/89/100 137/94/105 139/85/96 -f 140/86/97 139/85/96 138/95/106 -f 144/96/107 146/97/108 150/98/109 143/99/110 -f 142/100/111 149/101/112 146/97/108 144/96/107 -f 147/102/113 145/103/114 151/104/115 -f 148/105/116 151/104/115 145/103/114 -f 149/101/112 147/102/113 151/104/115 146/97/108 -f 150/98/109 146/97/108 151/104/115 148/105/116 -f 154/96/117 156/97/118 160/98/119 153/99/120 -f 152/100/121 159/101/122 156/97/118 154/96/117 -f 157/102/123 155/103/124 161/104/125 -f 158/105/126 161/104/125 155/103/124 -f 159/101/122 157/102/123 161/104/125 156/97/118 -f 160/98/119 156/97/118 161/104/125 158/105/126 -f 164/96/127 166/97/128 170/98/129 163/99/130 -f 162/100/131 169/101/132 166/97/128 164/96/127 -f 167/102/133 165/103/134 171/104/135 -f 168/105/136 171/104/135 165/103/134 -f 169/101/132 167/102/133 171/104/135 166/97/128 -f 170/98/129 166/97/128 171/104/135 168/105/136 -f 173/84/137 181/85/138 182/86/139 172/87/140 -f 174/88/141 183/89/142 181/85/138 173/84/137 -f 176/90/143 175/91/144 177/92/145 -f 178/93/146 177/92/145 175/91/144 -f 179/94/147 176/90/143 177/92/145 181/85/138 -f 180/95/148 181/85/138 177/92/145 178/93/146 -f 183/89/142 179/94/147 181/85/138 -f 182/86/139 181/85/138 180/95/148 -f 185/84/149 193/85/150 194/86/151 184/87/152 -f 186/88/153 195/89/154 193/85/150 185/84/149 -f 188/90/155 187/91/156 189/92/157 -f 190/93/158 189/92/157 187/91/156 -f 191/94/159 188/90/155 189/92/157 193/85/150 -f 192/95/160 193/85/150 189/92/157 190/93/158 -f 195/89/154 191/94/159 193/85/150 -f 194/86/151 193/85/150 192/95/160 -f 197/84/161 205/85/162 206/86/163 196/87/164 -f 198/88/165 207/89/166 205/85/162 197/84/161 -f 200/90/167 199/91/168 201/92/169 -f 202/93/170 201/92/169 199/91/168 -f 203/94/171 200/90/167 201/92/169 205/85/162 -f 204/95/172 205/85/162 201/92/169 202/93/170 -f 207/89/166 203/94/171 205/85/162 -f 206/86/163 205/85/162 204/95/172 -f 209/84/173 217/85/174 218/86/175 208/87/176 -f 210/88/177 219/89/178 217/85/174 209/84/173 -f 212/90/179 211/91/180 213/92/181 -f 214/93/182 213/92/181 211/91/180 -f 215/94/183 212/90/179 213/92/181 217/85/174 -f 216/95/184 217/85/174 213/92/181 214/93/182 -f 219/89/178 215/94/183 217/85/174 -f 218/86/175 217/85/174 216/95/184 -f 220/106/185 223/107/186 231/108/187 229/109/188 -f 227/110/189 228/111/190 232/112/191 222/113/192 -f 221/114/193 227/110/189 222/113/192 -f 222/113/192 224/115/194 221/114/193 -f 232/112/191 225/116/195 224/115/194 222/113/192 -f 226/117/196 230/118/197 223/107/186 220/106/185 -f 232/112/191 223/107/186 230/118/197 225/116/195 -f 228/111/190 231/108/187 223/107/186 232/112/191 -f 233/106/198 236/107/199 244/108/200 242/109/201 -f 240/110/202 241/111/203 245/112/204 235/113/205 -f 234/114/206 240/110/202 235/113/205 -f 235/113/205 237/115/207 234/114/206 -f 245/112/204 238/116/208 237/115/207 235/113/205 -f 239/117/209 243/118/210 236/107/199 233/106/198 -f 245/112/204 236/107/199 243/118/210 238/116/208 -f 241/111/203 244/108/200 236/107/199 245/112/204 -f 246/106/211 249/107/212 257/108/213 255/109/214 -f 253/110/215 254/111/216 258/112/217 248/113/218 -f 247/114/219 253/110/215 248/113/218 -f 248/113/218 250/115/220 247/114/219 -f 258/112/217 251/116/221 250/115/220 248/113/218 -f 252/117/222 256/118/223 249/107/212 246/106/211 -f 258/112/217 249/107/212 256/118/223 251/116/221 -f 254/111/216 257/108/213 249/107/212 258/112/217 -f 259/119/224 263/120/225 264/121/226 261/122/227 -f 262/123/228 265/124/229 263/120/225 259/119/224 -f 264/121/226 263/120/225 266/125/230 -f 263/120/225 265/124/229 267/126/231 -f 266/125/230 263/120/225 268/127/232 269/128/233 -f 263/120/225 267/126/231 270/129/234 268/127/232 -f 269/128/233 268/127/232 260/130/235 -f 268/127/232 270/129/234 260/130/235 -f 271/119/236 275/120/237 276/121/238 273/122/239 -f 274/123/240 277/124/241 275/120/237 271/119/236 -f 276/121/238 275/120/237 278/125/242 -f 275/120/237 277/124/241 279/126/243 -f 278/125/242 275/120/237 280/127/244 281/128/245 -f 275/120/237 279/126/243 282/129/246 280/127/244 -f 281/128/245 280/127/244 272/130/247 -f 280/127/244 282/129/246 272/130/247 -f 283/119/248 287/120/249 288/121/250 285/122/251 -f 286/123/252 289/124/253 287/120/249 283/119/248 -f 288/121/250 287/120/249 290/125/254 -f 287/120/249 289/124/253 291/126/255 -f 290/125/254 287/120/249 292/127/256 293/128/257 -f 287/120/249 291/126/255 294/129/258 292/127/256 -f 293/128/257 292/127/256 284/130/259 -f 292/127/256 294/129/258 284/130/259 -f 295/119/260 299/120/261 300/121/262 297/122/263 -f 298/123/264 301/124/265 299/120/261 295/119/260 -f 300/121/262 299/120/261 302/125/266 -f 299/120/261 301/124/265 303/126/267 -f 302/125/266 299/120/261 304/127/268 305/128/269 -f 299/120/261 303/126/267 306/129/270 304/127/268 -f 305/128/269 304/127/268 296/130/271 -f 304/127/268 306/129/270 296/130/271 -f 307/119/272 311/120/273 312/121/274 309/122/275 -f 310/123/276 313/124/277 311/120/273 307/119/272 -f 312/121/274 311/120/273 314/125/278 -f 311/120/273 313/124/277 315/126/279 -f 314/125/278 311/120/273 316/127/280 317/128/281 -f 311/120/273 315/126/279 318/129/282 316/127/280 -f 317/128/281 316/127/280 308/130/283 -f 316/127/280 318/129/282 308/130/283 -f 319/119/284 323/120/285 324/121/286 321/122/287 -f 322/123/288 325/124/289 323/120/285 319/119/284 -f 324/121/286 323/120/285 326/125/290 -f 323/120/285 325/124/289 327/126/291 -f 326/125/290 323/120/285 328/127/292 329/128/293 -f 323/120/285 327/126/291 330/129/294 328/127/292 -f 329/128/293 328/127/292 320/130/295 -f 328/127/292 330/129/294 320/130/295 -f 331/119/296 335/120/297 336/121/298 333/122/299 -f 334/123/300 337/124/301 335/120/297 331/119/296 -f 336/121/298 335/120/297 338/125/302 -f 335/120/297 337/124/301 339/126/303 -f 338/125/302 335/120/297 340/127/304 341/128/305 -f 335/120/297 339/126/303 342/129/306 340/127/304 -f 341/128/305 340/127/304 332/130/307 -f 340/127/304 342/129/306 332/130/307 -f 343/119/308 347/120/309 348/121/310 345/122/311 -f 346/123/312 349/124/313 347/120/309 343/119/308 -f 348/121/310 347/120/309 350/125/314 -f 347/120/309 349/124/313 351/126/315 -f 350/125/314 347/120/309 352/127/316 353/128/317 -f 347/120/309 351/126/315 354/129/318 352/127/316 -f 353/128/317 352/127/316 344/130/319 -f 352/127/316 354/129/318 344/130/319 -f 355/119/320 359/120/321 360/121/322 357/122/323 -f 358/123/324 361/124/325 359/120/321 355/119/320 -f 360/121/322 359/120/321 362/125/326 -f 359/120/321 361/124/325 363/126/327 -f 362/125/326 359/120/321 364/127/328 365/128/329 -f 359/120/321 363/126/327 366/129/330 364/127/328 -f 365/128/329 364/127/328 356/130/331 -f 364/127/328 366/129/330 356/130/331 -f 367/119/332 371/120/333 372/121/334 369/122/335 -f 370/123/336 373/124/337 371/120/333 367/119/332 -f 372/121/334 371/120/333 374/125/338 -f 371/120/333 373/124/337 375/126/339 -f 374/125/338 371/120/333 376/127/340 377/128/341 -f 371/120/333 375/126/339 378/129/342 376/127/340 -f 377/128/341 376/127/340 368/130/343 -f 376/127/340 378/129/342 368/130/343 -f 380/84/344 388/85/345 389/86/346 379/87/347 -f 381/88/348 390/89/349 388/85/345 380/84/344 -f 383/90/350 382/91/351 384/92/352 -f 385/93/353 384/92/352 382/91/351 -f 386/94/354 383/90/350 384/92/352 388/85/345 -f 387/95/355 388/85/345 384/92/352 385/93/353 -f 390/89/349 386/94/354 388/85/345 -f 389/86/346 388/85/345 387/95/355 -f 392/84/356 400/85/357 401/86/358 391/87/359 -f 393/88/360 402/89/361 400/85/357 392/84/356 -f 395/90/362 394/91/363 396/92/364 -f 397/93/365 396/92/364 394/91/363 -f 398/94/366 395/90/362 396/92/364 400/85/357 -f 399/95/367 400/85/357 396/92/364 397/93/365 -f 402/89/361 398/94/366 400/85/357 -f 401/86/358 400/85/357 399/95/367 -f 404/84/368 412/85/369 413/86/370 403/87/371 -f 405/88/372 414/89/373 412/85/369 404/84/368 -f 407/90/374 406/91/375 408/92/376 -f 409/93/377 408/92/376 406/91/375 -f 410/94/378 407/90/374 408/92/376 412/85/369 -f 411/95/379 412/85/369 408/92/376 409/93/377 -f 414/89/373 410/94/378 412/85/369 -f 413/86/370 412/85/369 411/95/379 -f 415/131/380 417/132/381 420/133/382 425/134/383 -f 418/135/384 417/132/381 415/131/380 425/136/383 -f 416/137/385 419/138/386 418/135/384 425/136/383 -f 420/133/382 419/139/386 416/140/385 425/134/383 -f 420/133/382 417/132/381 421/141/387 424/142/388 -f 417/132/381 418/135/384 422/143/389 421/141/387 -f 418/135/384 419/138/386 423/144/390 422/143/389 -f 419/139/386 420/133/382 424/142/388 423/145/390 -f 424/142/388 421/141/387 426/146/391 -f 421/141/387 422/143/389 426/147/391 -f 422/143/389 423/144/390 426/147/391 -f 423/145/390 424/142/388 426/146/391 -f 427/131/392 429/132/393 432/133/394 437/134/395 -f 430/135/396 429/132/393 427/131/392 437/136/395 -f 428/137/397 431/138/398 430/135/396 437/136/395 -f 432/133/394 431/139/398 428/140/397 437/134/395 -f 432/133/394 429/132/393 433/141/399 436/142/400 -f 429/132/393 430/135/396 434/143/401 433/141/399 -f 430/135/396 431/138/398 435/144/402 434/143/401 -f 431/139/398 432/133/394 436/142/400 435/145/402 -f 436/142/400 433/141/399 438/146/403 -f 433/141/399 434/143/401 438/147/403 -f 434/143/401 435/144/402 438/147/403 -f 435/145/402 436/142/400 438/146/403 -f 439/131/404 441/132/393 444/133/394 449/134/405 -f 442/135/396 441/132/393 439/131/404 449/136/405 -f 440/137/406 443/138/398 442/135/396 449/136/405 -f 444/133/394 443/139/398 440/140/406 449/134/405 -f 444/133/394 441/132/393 445/141/399 448/142/400 -f 441/132/393 442/135/396 446/143/401 445/141/399 -f 442/135/396 443/138/398 447/144/402 446/143/401 -f 443/139/398 444/133/394 448/142/400 447/145/402 -f 448/142/400 445/141/399 450/146/403 -f 445/141/399 446/143/401 450/147/403 -f 446/143/401 447/144/402 450/147/403 -f 447/145/402 448/142/400 450/146/403 -f 451/131/407 453/132/408 456/133/409 461/134/410 -f 454/135/411 453/132/408 451/131/407 461/136/410 -f 452/137/412 455/138/413 454/135/411 461/136/410 -f 456/133/409 455/139/413 452/140/412 461/134/410 -f 456/133/409 453/132/408 457/141/414 460/142/415 -f 453/132/408 454/135/411 458/143/416 457/141/414 -f 454/135/411 455/138/413 459/144/417 458/143/416 -f 455/139/413 456/133/409 460/142/415 459/145/417 -f 460/142/415 457/141/414 462/146/418 -f 457/141/414 458/143/416 462/147/418 -f 458/143/416 459/144/417 462/147/418 -f 459/145/417 460/142/415 462/146/418 -f 463/131/419 465/132/420 468/133/421 473/134/422 -f 466/135/423 465/132/420 463/131/419 473/136/422 -f 464/137/424 467/138/425 466/135/423 473/136/422 -f 468/133/421 467/139/425 464/140/424 473/134/422 -f 468/133/421 465/132/420 469/141/426 472/142/427 -f 465/132/420 466/135/423 470/143/428 469/141/426 -f 466/135/423 467/138/425 471/144/429 470/143/428 -f 467/139/425 468/133/421 472/142/427 471/145/429 -f 472/142/427 469/141/426 474/146/430 -f 469/141/426 470/143/428 474/147/430 -f 470/143/428 471/144/429 474/147/430 -f 471/145/429 472/142/427 474/146/430 -f 475/131/431 477/132/432 480/133/433 485/134/434 -f 478/135/435 477/132/432 475/131/431 485/136/434 -f 476/137/436 479/138/437 478/135/435 485/136/434 -f 480/133/433 479/139/437 476/140/436 485/134/434 -f 480/133/433 477/132/432 481/141/438 484/142/439 -f 477/132/432 478/135/435 482/143/440 481/141/438 -f 478/135/435 479/138/437 483/144/441 482/143/440 -f 479/139/437 480/133/433 484/142/439 483/145/441 -f 484/142/439 481/141/438 486/146/442 -f 481/141/438 482/143/440 486/147/442 -f 482/143/440 483/144/441 486/147/442 -f 483/145/441 484/142/439 486/146/442 -f 487/131/443 489/132/444 492/133/445 497/134/446 -f 490/135/447 489/132/444 487/131/443 497/136/446 -f 488/137/448 491/138/449 490/135/447 497/136/446 -f 492/133/445 491/139/449 488/140/448 497/134/446 -f 492/133/445 489/132/444 493/141/450 496/142/451 -f 489/132/444 490/135/447 494/143/452 493/141/450 -f 490/135/447 491/138/449 495/144/453 494/143/452 -f 491/139/449 492/133/445 496/142/451 495/145/453 -f 496/142/451 493/141/450 498/146/454 -f 493/141/450 494/143/452 498/147/454 -f 494/143/452 495/144/453 498/147/454 -f 495/145/453 496/142/451 498/146/454 -f 499/131/455 501/132/456 504/133/457 509/134/458 -f 502/135/459 501/132/456 499/131/455 509/136/458 -f 500/137/460 503/138/461 502/135/459 509/136/458 -f 504/133/457 503/139/461 500/140/460 509/134/458 -f 504/133/457 501/132/456 505/141/462 508/142/463 -f 501/132/456 502/135/459 506/143/464 505/141/462 -f 502/135/459 503/138/461 507/144/465 506/143/464 -f 503/139/461 504/133/457 508/142/463 507/145/465 -f 508/142/463 505/141/462 510/146/466 -f 505/141/462 506/143/464 510/147/466 -f 506/143/464 507/144/465 510/147/466 -f 507/145/465 508/142/463 510/146/466 -f 511/131/467 513/132/468 516/133/469 521/134/470 -f 514/135/471 513/132/468 511/131/467 521/136/470 -f 512/137/472 515/138/473 514/135/471 521/136/470 -f 516/133/469 515/139/473 512/140/472 521/134/470 -f 516/133/469 513/132/468 517/141/474 520/142/475 -f 513/132/468 514/135/471 518/143/476 517/141/474 -f 514/135/471 515/138/473 519/144/477 518/143/476 -f 515/139/473 516/133/469 520/142/475 519/145/477 -f 520/142/475 517/141/474 522/146/478 -f 517/141/474 518/143/476 522/147/478 -f 518/143/476 519/144/477 522/147/478 -f 519/145/477 520/142/475 522/146/478 -f 523/131/479 525/132/480 528/133/481 533/134/482 -f 526/135/483 525/132/480 523/131/479 533/136/482 -f 524/137/484 527/138/485 526/135/483 533/136/482 -f 528/133/481 527/139/485 524/140/484 533/134/482 -f 528/133/481 525/132/480 529/141/486 532/142/487 -f 525/132/480 526/135/483 530/143/488 529/141/486 -f 526/135/483 527/138/485 531/144/489 530/143/488 -f 527/139/485 528/133/481 532/142/487 531/145/489 -f 532/142/487 529/141/486 534/146/490 -f 529/141/486 530/143/488 534/147/490 -f 530/143/488 531/144/489 534/147/490 -f 531/145/489 532/142/487 534/146/490 diff --git a/examples/assets/3d/palm/palm_bark.png b/examples/assets/3d/palm/palm_bark.png deleted file mode 100644 index 5807ac6..0000000 Binary files a/examples/assets/3d/palm/palm_bark.png and /dev/null differ diff --git a/examples/assets/3d/palm/palm_bark_norm.png b/examples/assets/3d/palm/palm_bark_norm.png deleted file mode 100644 index d4189e6..0000000 Binary files a/examples/assets/3d/palm/palm_bark_norm.png and /dev/null differ diff --git a/examples/assets/3d/palm/palm_bark_spec.png b/examples/assets/3d/palm/palm_bark_spec.png deleted file mode 100644 index 08d5432..0000000 Binary files a/examples/assets/3d/palm/palm_bark_spec.png and /dev/null differ diff --git a/examples/assets/3d/tree/tree.bin b/examples/assets/3d/tree/tree.bin new file mode 100644 index 0000000..6703a66 Binary files /dev/null and b/examples/assets/3d/tree/tree.bin differ diff --git a/examples/assets/3d/tree/tree.js b/examples/assets/3d/tree/tree.js new file mode 100644 index 0000000..39c64a5 --- /dev/null +++ b/examples/assets/3d/tree/tree.js @@ -0,0 +1,29 @@ +{ + + "metadata" : + { + "formatVersion" : 3.1, + "sourceFile" : "tree.obj", + "generatedBy" : "OBJConverter", + "vertices" : 413, + "faces" : 760, + "normals" : 472, + "uvs" : 1496, + "materials" : 1 + }, + + "materials": [ { + "DbgColor" : 15658734, + "DbgIndex" : 0, + "DbgName" : "bark", + "colorAmbient" : [0.117647, 0.117647, 0.117647], + "colorDiffuse" : [1.0, 1.0, 1.0], + "colorSpecular" : [0.752941, 0.752941, 0.752941], + "illumination" : 2, + "mapDiffuse" : "bark.png", + "specularCoef" : 8.0 + }], + + "buffers": "tree.bin" + +} diff --git a/examples/assets/css/styles.css b/examples/assets/css/styles.css new file mode 100644 index 0000000..3c8a25e --- /dev/null +++ b/examples/assets/css/styles.css @@ -0,0 +1,23 @@ +/* reset */ +html, body { + margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; +} + +#main { + width: 100%; + height: 100%; +} + +header { + position: fixed; + width: 100%; + padding: 24px; + background: rgba( 0, 0, 0, 0.5 ); + color: #fff; + font-size: 1.5em; + z-index: 9999; +} + +header a { + color: #fff; +} diff --git a/examples/assets/img/deviantart-hero_walk_cycle_spritesheet_by_mrnoobtastic-d3defej.png b/examples/assets/img/deviantart-hero_walk_cycle_spritesheet_by_mrnoobtastic-d3defej.png new file mode 100644 index 0000000..4286393 Binary files /dev/null and b/examples/assets/img/deviantart-hero_walk_cycle_spritesheet_by_mrnoobtastic-d3defej.png differ diff --git a/examples/assets/img/skysphere.jpg b/examples/assets/img/skysphere.jpg new file mode 100644 index 0000000..fd63641 Binary files /dev/null and b/examples/assets/img/skysphere.jpg differ diff --git a/examples/assets/img/sprite_king.png b/examples/assets/img/sprite_king.png new file mode 100755 index 0000000..80e934f Binary files /dev/null and b/examples/assets/img/sprite_king.png differ diff --git a/examples/assets/img/terrain/heightmap.png b/examples/assets/img/terrain/heightmap.png index 3ec8c35..fb037ec 100644 Binary files a/examples/assets/img/terrain/heightmap.png and b/examples/assets/img/terrain/heightmap.png differ diff --git a/examples/assets/img/waternormals.jpg b/examples/assets/img/waternormals.jpg new file mode 100644 index 0000000..9dfe03c Binary files /dev/null and b/examples/assets/img/waternormals.jpg differ diff --git a/examples/assets/js/ShaderTerrain.js b/examples/assets/js/ShaderTerrain.js deleted file mode 100644 index 23514ae..0000000 --- a/examples/assets/js/ShaderTerrain.js +++ /dev/null @@ -1,377 +0,0 @@ -/** - * @author alteredq / http://alteredqualia.com/ - * - */ - -THREE.ShaderTerrain = { - - /* ------------------------------------------------------------------------- - // Dynamic terrain shader - // - Blinn-Phong - // - height + normal + diffuse1 + diffuse2 + specular + detail maps - // - point, directional and hemisphere lights (use with "lights: true" material option) - // - shadow maps receiving - ------------------------------------------------------------------------- */ - - 'terrain' : { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - THREE.UniformsLib[ "shadowmap" ], - - { - - "enableDiffuse1" : { type: "i", value: 0 }, - "enableDiffuse2" : { type: "i", value: 0 }, - "enableSpecular" : { type: "i", value: 0 }, - "enableReflection": { type: "i", value: 0 }, - - "tDiffuse1" : { type: "t", value: null }, - "tDiffuse2" : { type: "t", value: null }, - "tDetail" : { type: "t", value: null }, - "tNormal" : { type: "t", value: null }, - "tSpecular" : { type: "t", value: null }, - "tDisplacement": { type: "t", value: null }, - - "uNormalScale": { type: "f", value: 1.0 }, - - "uDisplacementBias": { type: "f", value: 0.0 }, - "uDisplacementScale": { type: "f", value: 1.0 }, - - "uDiffuseColor": { type: "c", value: new THREE.Color( 0xeeeeee ) }, - "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) }, - "uAmbientColor": { type: "c", value: new THREE.Color( 0x050505 ) }, - "uShininess": { type: "f", value: 30 }, - "uOpacity": { type: "f", value: 1 }, - - "uRepeatBase" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, - "uRepeatOverlay" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, - - "uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) } - - } - - ] ), - - fragmentShader: [ - - "uniform vec3 uAmbientColor;", - "uniform vec3 uDiffuseColor;", - "uniform vec3 uSpecularColor;", - "uniform float uShininess;", - "uniform float uOpacity;", - - "uniform bool enableDiffuse1;", - "uniform bool enableDiffuse2;", - "uniform bool enableSpecular;", - - "uniform sampler2D tDiffuse1;", - "uniform sampler2D tDiffuse2;", - "uniform sampler2D tDetail;", - "uniform sampler2D tNormal;", - "uniform sampler2D tSpecular;", - "uniform sampler2D tDisplacement;", - - "uniform float uNormalScale;", - - "uniform vec2 uRepeatOverlay;", - "uniform vec2 uRepeatBase;", - - "uniform vec2 uOffset;", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "uniform vec3 ambientLightColor;", - - "#if MAX_DIR_LIGHTS > 0", - - "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", - "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];", - "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", - "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", - "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", - - "#endif", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - - "void main() {", - - "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );", - - "vec3 specularTex = vec3( 1.0 );", - - "vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;", - "vec2 uvBase = uRepeatBase * vUv;", - - "vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;", - "normalTex.xy *= uNormalScale;", - "normalTex = normalize( normalTex );", - - "if( enableDiffuse1 && enableDiffuse2 ) {", - - "vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );", - "vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );", - - "#ifdef GAMMA_INPUT", - - "colDiffuse1.xyz *= colDiffuse1.xyz;", - "colDiffuse2.xyz *= colDiffuse2.xyz;", - - "#endif", - - "gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", - - " } else if( enableDiffuse1 ) {", - - "gl_FragColor = gl_FragColor * texture2D( tDiffuse1, uvOverlay );", - - "} else if( enableDiffuse2 ) {", - - "gl_FragColor = gl_FragColor * texture2D( tDiffuse2, uvOverlay );", - - "}", - - "if( enableSpecular )", - "specularTex = texture2D( tSpecular, uvOverlay ).xyz;", - - "mat3 tsb = mat3( vTangent, vBinormal, vNormal );", - "vec3 finalNormal = tsb * normalTex;", - - "vec3 normal = normalize( finalNormal );", - "vec3 viewPosition = normalize( vViewPosition );", - - // point lights - - "#if MAX_POINT_LIGHTS > 0", - - "vec3 pointDiffuse = vec3( 0.0 );", - "vec3 pointSpecular = vec3( 0.0 );", - - "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", - - "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", - "vec3 lVector = lPosition.xyz + vViewPosition.xyz;", - - "float lDistance = 1.0;", - "if ( pointLightDistance[ i ] > 0.0 )", - "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );", - - "lVector = normalize( lVector );", - - "vec3 pointHalfVector = normalize( lVector + viewPosition );", - "float pointDistance = lDistance;", - - "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", - "float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );", - - "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );", - - "pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;", - "pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;", - - "}", - - "#endif", - - // directional lights - - "#if MAX_DIR_LIGHTS > 0", - - "vec3 dirDiffuse = vec3( 0.0 );", - "vec3 dirSpecular = vec3( 0.0 );", - - "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", - - "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", - - "vec3 dirVector = normalize( lDirection.xyz );", - "vec3 dirHalfVector = normalize( dirVector + viewPosition );", - - "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", - "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - - "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );", - - "dirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;", - "dirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;", - - "}", - - "#endif", - - // hemisphere lights - - "#if MAX_HEMI_LIGHTS > 0", - - "vec3 hemiDiffuse = vec3( 0.0 );", - "vec3 hemiSpecular = vec3( 0.0 );" , - - "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {", - - "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );", - "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );", - - // diffuse - - "float dotProduct = dot( normal, lVector );", - "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - - "hemiDiffuse += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - // specular (sky light) - - "float hemiSpecularWeight = 0.0;", - - "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );", - "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;", - "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );", - - // specular (ground light) - - "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );", - - "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );", - "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", - "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );", - - "hemiSpecular += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", - - "}", - - "#endif", - - // all lights contribution summation - - "vec3 totalDiffuse = vec3( 0.0 );", - "vec3 totalSpecular = vec3( 0.0 );", - - "#if MAX_DIR_LIGHTS > 0", - - "totalDiffuse += dirDiffuse;", - "totalSpecular += dirSpecular;", - - "#endif", - - "#if MAX_HEMI_LIGHTS > 0", - - "totalDiffuse += hemiDiffuse;", - "totalSpecular += hemiSpecular;", - - "#endif", - - "#if MAX_POINT_LIGHTS > 0", - - "totalDiffuse += pointDiffuse;", - "totalSpecular += pointSpecular;", - - "#endif", - - //"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;", - "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );", - - THREE.ShaderChunk[ "shadowmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join("\n"), - - vertexShader: [ - - "attribute vec4 tangent;", - - "uniform vec2 uRepeatBase;", - - "uniform sampler2D tNormal;", - - "#ifdef VERTEX_TEXTURES", - - "uniform sampler2D tDisplacement;", - "uniform float uDisplacementScale;", - "uniform float uDisplacementBias;", - - "#endif", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - - "void main() {", - - "vNormal = normalize( normalMatrix * normal );", - - // tangent and binormal vectors - - "vTangent = normalize( normalMatrix * tangent.xyz );", - - "vBinormal = cross( vNormal, vTangent ) * tangent.w;", - "vBinormal = normalize( vBinormal );", - - // texture coordinates - - "vUv = uv;", - - "vec2 uvBase = uv * uRepeatBase;", - - // displacement mapping - - "#ifdef VERTEX_TEXTURES", - - "vec3 dv = texture2D( tDisplacement, uvBase ).xyz;", - "float df = uDisplacementScale * dv.x + uDisplacementBias;", - "vec3 displacedPosition = normal * df + position;", - - "vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );", - "vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );", - - "#else", - - "vec4 mPosition = modelMatrix * vec4( position, 1.0 );", - "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - "#endif", - - "gl_Position = projectionMatrix * mvPosition;", - - "vViewPosition = -mvPosition.xyz;", - - "vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;", - "vNormal = normalMatrix * normalTex;", - - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join("\n") - - } - -}; diff --git a/examples/assets/js/helpers/lookaround.js b/examples/assets/js/helpers/lookaround.js index 7bbbb56..a5e33eb 100644 --- a/examples/assets/js/helpers/lookaround.js +++ b/examples/assets/js/helpers/lookaround.js @@ -3,17 +3,19 @@ // variables var mouseX = 0; var mouseY = 0; - -LookArround = function(e){ - - // the 3d environment is passed as target + +LookAround = function(e){ + + // the 3d environment is passed as target var $3d = e.target; - + + // start when the active camera is set + if( !$3d.active.camera ) return; $3d.active.camera.lookAt( $3d.active.scene.position ); - + $3d.active.camera.position.x += ( mouseX - $3d.active.camera.position.x ) * 0.05; $3d.active.camera.position.y += ( - mouseY - $3d.active.camera.position.y ) * 0.05; - + } // add mouse tracking @@ -23,7 +25,7 @@ function onDocumentMouseMove(event) { mouseX = ( event.clientX - (window.innerWidth / 2) ) * 4; mouseY = ( event.clientY - (window.innerHeight / 2) ) * 4; - + } - + })(); diff --git a/examples/assets/js/helpers/three.bin.js b/examples/assets/js/helpers/three.bin.js new file mode 100644 index 0000000..08a8f74 --- /dev/null +++ b/examples/assets/js/helpers/three.bin.js @@ -0,0 +1,41 @@ +(function(){ + + // Requires the BinaryLoader extension + Three.prototype.fn.webgl.obj = function( options, callback ){ + // define the group (once) + if( !this.groups['obj'] ) this.groups['obj'] = "objects"; + + // model + var self = this; + + loader = new THREE.BinaryLoader( true ); + + loader.load( options.src, function ( geometry, materials ) { + for( var i in materials ){ + //console.log(); + materials[i].side = THREE.DoubleSide; + //materials[i].transparent = true; + //materials[i].depthTest = false; + if( materials[i].transparent ){ + // smooth antialias + materials[i].renderDepth = true; + materials[i].depthWrite = false; + } + } + var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial(materials) ); + + object.geometry = geometry; + object.material = new THREE.MeshFaceMaterial(materials); + //object.material.side = THREE.DoubleSide; + // save id as name + if( options.id ) object.name = options.id; + + self.active.scene.add( object ); + + callback( object ); + + }); + + } + +})(); diff --git a/examples/assets/js/helpers/three.obj.js b/examples/assets/js/helpers/three.obj.js deleted file mode 100644 index 88c27fe..0000000 --- a/examples/assets/js/helpers/three.obj.js +++ /dev/null @@ -1,25 +0,0 @@ -(function(){ - - Three.prototype.fn.webgl.obj = function( attributes ){ - // model - var self = this; - var object = {}; - var texture = ( attributes.map ) ? this.webglTexture( map ) : false; - - var loader = new THREE.OBJMTLLoader(); - loader.addEventListener( 'load', function ( event ) { - - object = event.content; - - self.active.scene.add( object ); - - }); - // - if( attributes.src ){ - loader.load( attributes.src, attributes.mtl ); - - } - return object; - } - -})(); diff --git a/examples/assets/js/helpers/three.water.js b/examples/assets/js/helpers/three.water.js new file mode 100644 index 0000000..be3bc9d --- /dev/null +++ b/examples/assets/js/helpers/three.water.js @@ -0,0 +1,87 @@ +(function(){ + + // Requires the BinaryLoader extension + Three.prototype.fn.webgl.water = function( attributes, callback ){ + // define the group (once) + if( !this.groups['water'] ) this.groups['water'] = "objects"; + // var self = this; + // plane - by default a 1x1 square + var defaults = { + width: 1, + height: 1, + //color: 0x000000, + wireframe: false, + scene: this.active.scene + }; + // extend options + var options = $.extend(defaults, attributes); + // load normals + var waterNormals; + if( THREE.REVISION < 70 ){ + waterNormals = new THREE.ImageUtils.loadTexture('assets/img/waternormals.jpg'); + } else { + var textureLoader = new THREE.TextureLoader(); // requires THREE > v7x + waterNormals = textureLoader.load('assets/img/waternormals.jpg'); + } + waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping; + // add a light to see the water reflection + /*var directionalLight = new THREE.DirectionalLight(0xffff55, 1); // light color as option... + directionalLight.position.set(-600, 300, 600); // position as option... + /*var directionalLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1 ); + directionalLight.color.setHSL( 0.6, 1, 0.6 ); + directionalLight.groundColor.setHSL( 0.095, 1, 0.75 ); + directionalLight.position.set( 0, 500, 0 );*/ + //this.active.scene.add(directionalLight); + // generate geometry + var Constructor = ( THREE.REVISION < 70 ) ? THREE.PlaneGeometry : THREE.PlaneBufferGeometry; + var geometry = new Constructor( options.width, options.height, 10, 10); // polygon density as option... + // make this optional? + //geometry.dynamic = true; + // Create the water effect + var water = new THREE.Water(this.renderer, this.active.camera, this.active.scene, { + textureWidth: 256, + textureHeight: 256, + waterNormals: waterNormals, + alpha: 1.0, + //sunDirection: directionalLight.position.normalize(), + sunColor: 0xffffff, + waterColor: 0x001e0f, + betaVersion: 0, + side: THREE.DoubleSide + }); + + var mesh = new THREE.Mesh( geometry, water.material ); + // preserve reference to water object + mesh.add(water); + + //new THREE.PlaneBufferGeometry(2000, 2000, 10, 10), + + // set attributes + mesh.name = "water"; // use tagName instead? + if( options.id ) mesh.name += options.id; + + // add object to scene (will be done later when an Object3D is created) + //this.active.scene.add( mesh ); + + // events + $(this.el).on('update', function(e){ + var $3d = e.target; + // loop to find the water object(s) + for( var i in $3d.objects ){ + var obj = $3d.objects[i]; + // use .find() instead? + if(obj.name.search('water') === 0){ + var water = obj.children[0].children[0]; // not expecting any other objects here? + water.material.uniforms.time.value += 1.0 / 60.0; + water.render(); + $3d.renderer.render($3d.active.scene, $3d.active.camera); + } + } + }); + + // return using callback + callback( mesh ); + + } + +})(); diff --git a/examples/assets/js/libs/BinaryLoader.js b/examples/assets/js/libs/BinaryLoader.js new file mode 100644 index 0000000..28734b2 --- /dev/null +++ b/examples/assets/js/libs/BinaryLoader.js @@ -0,0 +1,719 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.BinaryLoader = function ( manager ) { + + if ( typeof manager === 'boolean' ) { + + console.warn( 'THREE.BinaryLoader: showStatus parameter has been removed from constructor.' ); + manager = undefined; + + } + + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + +}; + +THREE.BinaryLoader.prototype = { + + constructor: THREE.BinaryLoader, + + // Deprecated + + get statusDomElement () { + + if ( this._statusDomElement === undefined ) { + + this._statusDomElement = document.createElement( 'div' ); + + } + + console.warn( 'THREE.BinaryLoader: .statusDomElement has been removed.' ); + return this._statusDomElement; + + }, + + // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary) + // - binary models consist of two files: JS and BIN + // - parameters + // - url (required) + // - callback (required) + // - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file) + // - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file) + load: function ( url, onLoad, onProgress, onError ) { + + // todo: unify load API to for easier SceneLoader use + + var texturePath = this.texturePath || THREE.Loader.prototype.extractUrlBase( url ); + var binaryPath = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url ); + + // #1 load JS part via web worker + + var scope = this; + + var jsonloader = new THREE.XHRLoader( this.manager ); + jsonloader.load( url, function ( data ) { + + var json = JSON.parse( data ); + + var bufferUrl = binaryPath + json.buffers; + + var bufferLoader = new THREE.XHRLoader( scope.manager ); + bufferLoader.setResponseType( 'arraybuffer' ); + bufferLoader.load( bufferUrl, function ( bufData ) { + + // IEWEBGL needs this ??? + //buffer = ( new Uint8Array( xhr.responseBody ) ).buffer; + + //// iOS and other XMLHttpRequest level 1 ??? + + scope.parse( bufData, onLoad, texturePath, json.materials ); + + }, onProgress, onError ); + + }, onProgress, onError ); + + }, + + setBinaryPath: function ( value ) { + + this.binaryPath = value; + + }, + + setCrossOrigin: function ( value ) { + + this.crossOrigin = value; + + }, + + setTexturePath: function ( value ) { + + this.texturePath = value; + + }, + + parse: function ( data, callback, texturePath, jsonMaterials ) { + + var Model = function ( texturePath ) { + + var scope = this, + currentOffset = 0, + md, + normals = [], + uvs = [], + start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv, + start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv, + tri_size, quad_size, + len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv, + len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv; + + + THREE.Geometry.call( this ); + + md = parseMetaData( data, currentOffset ); + + currentOffset += md.header_bytes; + /* + md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT; + md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT; + md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT; + md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT; + */ + // buffers sizes + + tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes; + quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes; + + len_tri_flat = md.ntri_flat * ( tri_size ); + len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 ); + len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 ); + len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 ); + + len_quad_flat = md.nquad_flat * ( quad_size ); + len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 ); + len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 ); + len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 ); + + // read buffers + + currentOffset += init_vertices( currentOffset ); + + currentOffset += init_normals( currentOffset ); + currentOffset += handlePadding( md.nnormals * 3 ); + + currentOffset += init_uvs( currentOffset ); + + start_tri_flat = currentOffset; + start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 ); + start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 ); + start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 ); + + start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 ); + start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 ); + start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 ); + start_quad_smooth_uv = start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 ); + + // have to first process faces with uvs + // so that face and uv indices match + + init_triangles_flat_uv( start_tri_flat_uv ); + init_triangles_smooth_uv( start_tri_smooth_uv ); + + init_quads_flat_uv( start_quad_flat_uv ); + init_quads_smooth_uv( start_quad_smooth_uv ); + + // now we can process untextured faces + + init_triangles_flat( start_tri_flat ); + init_triangles_smooth( start_tri_smooth ); + + init_quads_flat( start_quad_flat ); + init_quads_smooth( start_quad_smooth ); + + this.computeFaceNormals(); + + function handlePadding( n ) { + + return ( n % 4 ) ? ( 4 - n % 4 ) : 0; + + } + + function parseMetaData( data, offset ) { + + var metaData = { + + 'signature' : parseString( data, offset, 12 ), + 'header_bytes' : parseUChar8( data, offset + 12 ), + + 'vertex_coordinate_bytes' : parseUChar8( data, offset + 13 ), + 'normal_coordinate_bytes' : parseUChar8( data, offset + 14 ), + 'uv_coordinate_bytes' : parseUChar8( data, offset + 15 ), + + 'vertex_index_bytes' : parseUChar8( data, offset + 16 ), + 'normal_index_bytes' : parseUChar8( data, offset + 17 ), + 'uv_index_bytes' : parseUChar8( data, offset + 18 ), + 'material_index_bytes' : parseUChar8( data, offset + 19 ), + + 'nvertices' : parseUInt32( data, offset + 20 ), + 'nnormals' : parseUInt32( data, offset + 20 + 4 * 1 ), + 'nuvs' : parseUInt32( data, offset + 20 + 4 * 2 ), + + 'ntri_flat' : parseUInt32( data, offset + 20 + 4 * 3 ), + 'ntri_smooth' : parseUInt32( data, offset + 20 + 4 * 4 ), + 'ntri_flat_uv' : parseUInt32( data, offset + 20 + 4 * 5 ), + 'ntri_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 6 ), + + 'nquad_flat' : parseUInt32( data, offset + 20 + 4 * 7 ), + 'nquad_smooth' : parseUInt32( data, offset + 20 + 4 * 8 ), + 'nquad_flat_uv' : parseUInt32( data, offset + 20 + 4 * 9 ), + 'nquad_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 10 ) + + }; + /* + console.log( "signature: " + metaData.signature ); + + console.log( "header_bytes: " + metaData.header_bytes ); + console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes ); + console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes ); + console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes ); + + console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes ); + console.log( "normal_index_bytes: " + metaData.normal_index_bytes ); + console.log( "uv_index_bytes: " + metaData.uv_index_bytes ); + console.log( "material_index_bytes: " + metaData.material_index_bytes ); + + console.log( "nvertices: " + metaData.nvertices ); + console.log( "nnormals: " + metaData.nnormals ); + console.log( "nuvs: " + metaData.nuvs ); + + console.log( "ntri_flat: " + metaData.ntri_flat ); + console.log( "ntri_smooth: " + metaData.ntri_smooth ); + console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv ); + console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv ); + + console.log( "nquad_flat: " + metaData.nquad_flat ); + console.log( "nquad_smooth: " + metaData.nquad_smooth ); + console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv ); + console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv ); + + var total = metaData.header_bytes + + metaData.nvertices * metaData.vertex_coordinate_bytes * 3 + + metaData.nnormals * metaData.normal_coordinate_bytes * 3 + + metaData.nuvs * metaData.uv_coordinate_bytes * 2 + + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes ) + + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 ) + + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 ) + + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 ) + + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes ) + + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 ) + + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 ) + + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 ); + console.log( "total bytes: " + total ); + */ + + return metaData; + + } + + function parseString( data, offset, length ) { + + var charArray = new Uint8Array( data, offset, length ); + + var text = ""; + + for ( var i = 0; i < length; i ++ ) { + + text += String.fromCharCode( charArray[ offset + i ] ); + + } + + return text; + + } + + function parseUChar8( data, offset ) { + + var charArray = new Uint8Array( data, offset, 1 ); + + return charArray[ 0 ]; + + } + + function parseUInt32( data, offset ) { + + var intArray = new Uint32Array( data, offset, 1 ); + + return intArray[ 0 ]; + + } + + function init_vertices( start ) { + + var nElements = md.nvertices; + + var coordArray = new Float32Array( data, start, nElements * 3 ); + + var i, x, y, z; + + for ( i = 0; i < nElements; i ++ ) { + + x = coordArray[ i * 3 ]; + y = coordArray[ i * 3 + 1 ]; + z = coordArray[ i * 3 + 2 ]; + + scope.vertices.push( new THREE.Vector3( x, y, z ) ); + + } + + return nElements * 3 * Float32Array.BYTES_PER_ELEMENT; + + } + + function init_normals( start ) { + + var nElements = md.nnormals; + + if ( nElements ) { + + var normalArray = new Int8Array( data, start, nElements * 3 ); + + var i, x, y, z; + + for ( i = 0; i < nElements; i ++ ) { + + x = normalArray[ i * 3 ]; + y = normalArray[ i * 3 + 1 ]; + z = normalArray[ i * 3 + 2 ]; + + normals.push( x / 127, y / 127, z / 127 ); + + } + + } + + return nElements * 3 * Int8Array.BYTES_PER_ELEMENT; + + } + + function init_uvs( start ) { + + var nElements = md.nuvs; + + if ( nElements ) { + + var uvArray = new Float32Array( data, start, nElements * 2 ); + + var i, u, v; + + for ( i = 0; i < nElements; i ++ ) { + + u = uvArray[ i * 2 ]; + v = uvArray[ i * 2 + 1 ]; + + uvs.push( u, v ); + + } + + } + + return nElements * 2 * Float32Array.BYTES_PER_ELEMENT; + + } + + function init_uvs3( nElements, offset ) { + + var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3; + + var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + uva = uvIndexBuffer[ i * 3 ]; + uvb = uvIndexBuffer[ i * 3 + 1 ]; + uvc = uvIndexBuffer[ i * 3 + 2 ]; + + u1 = uvs[ uva * 2 ]; + v1 = uvs[ uva * 2 + 1 ]; + + u2 = uvs[ uvb * 2 ]; + v2 = uvs[ uvb * 2 + 1 ]; + + u3 = uvs[ uvc * 2 ]; + v3 = uvs[ uvc * 2 + 1 ]; + + scope.faceVertexUvs[ 0 ].push( [ + new THREE.Vector2( u1, v1 ), + new THREE.Vector2( u2, v2 ), + new THREE.Vector2( u3, v3 ) + ] ); + + } + + } + + function init_uvs4( nElements, offset ) { + + var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4; + + var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + uva = uvIndexBuffer[ i * 4 ]; + uvb = uvIndexBuffer[ i * 4 + 1 ]; + uvc = uvIndexBuffer[ i * 4 + 2 ]; + uvd = uvIndexBuffer[ i * 4 + 3 ]; + + u1 = uvs[ uva * 2 ]; + v1 = uvs[ uva * 2 + 1 ]; + + u2 = uvs[ uvb * 2 ]; + v2 = uvs[ uvb * 2 + 1 ]; + + u3 = uvs[ uvc * 2 ]; + v3 = uvs[ uvc * 2 + 1 ]; + + u4 = uvs[ uvd * 2 ]; + v4 = uvs[ uvd * 2 + 1 ]; + + scope.faceVertexUvs[ 0 ].push( [ + new THREE.Vector2( u1, v1 ), + new THREE.Vector2( u2, v2 ), + new THREE.Vector2( u4, v4 ) + ] ); + + scope.faceVertexUvs[ 0 ].push( [ + new THREE.Vector2( u2, v2 ), + new THREE.Vector2( u3, v3 ), + new THREE.Vector2( u4, v4 ) + ] ); + + } + + } + + function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) { + + var i, a, b, c, m; + + var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements ); + var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + a = vertexIndexBuffer[ i * 3 ]; + b = vertexIndexBuffer[ i * 3 + 1 ]; + c = vertexIndexBuffer[ i * 3 + 2 ]; + + m = materialIndexBuffer[ i ]; + + scope.faces.push( new THREE.Face3( a, b, c, null, null, m ) ); + + } + + } + + function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) { + + var i, a, b, c, d, m; + + var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements ); + var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + a = vertexIndexBuffer[ i * 4 ]; + b = vertexIndexBuffer[ i * 4 + 1 ]; + c = vertexIndexBuffer[ i * 4 + 2 ]; + d = vertexIndexBuffer[ i * 4 + 3 ]; + + m = materialIndexBuffer[ i ]; + + scope.faces.push( new THREE.Face3( a, b, d, null, null, m ) ); + scope.faces.push( new THREE.Face3( b, c, d, null, null, m ) ); + + } + + } + + function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) { + + var i, a, b, c, m; + var na, nb, nc; + + var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements ); + var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements ); + var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + a = vertexIndexBuffer[ i * 3 ]; + b = vertexIndexBuffer[ i * 3 + 1 ]; + c = vertexIndexBuffer[ i * 3 + 2 ]; + + na = normalIndexBuffer[ i * 3 ]; + nb = normalIndexBuffer[ i * 3 + 1 ]; + nc = normalIndexBuffer[ i * 3 + 2 ]; + + m = materialIndexBuffer[ i ]; + + var nax = normals[ na * 3 ], + nay = normals[ na * 3 + 1 ], + naz = normals[ na * 3 + 2 ], + + nbx = normals[ nb * 3 ], + nby = normals[ nb * 3 + 1 ], + nbz = normals[ nb * 3 + 2 ], + + ncx = normals[ nc * 3 ], + ncy = normals[ nc * 3 + 1 ], + ncz = normals[ nc * 3 + 2 ]; + + scope.faces.push( new THREE.Face3( a, b, c, [ + new THREE.Vector3( nax, nay, naz ), + new THREE.Vector3( nbx, nby, nbz ), + new THREE.Vector3( ncx, ncy, ncz ) + ], null, m ) ); + + } + + } + + function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) { + + var i, a, b, c, d, m; + var na, nb, nc, nd; + + var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements ); + var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements ); + var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements ); + + for ( i = 0; i < nElements; i ++ ) { + + a = vertexIndexBuffer[ i * 4 ]; + b = vertexIndexBuffer[ i * 4 + 1 ]; + c = vertexIndexBuffer[ i * 4 + 2 ]; + d = vertexIndexBuffer[ i * 4 + 3 ]; + + na = normalIndexBuffer[ i * 4 ]; + nb = normalIndexBuffer[ i * 4 + 1 ]; + nc = normalIndexBuffer[ i * 4 + 2 ]; + nd = normalIndexBuffer[ i * 4 + 3 ]; + + m = materialIndexBuffer[ i ]; + + var nax = normals[ na * 3 ], + nay = normals[ na * 3 + 1 ], + naz = normals[ na * 3 + 2 ], + + nbx = normals[ nb * 3 ], + nby = normals[ nb * 3 + 1 ], + nbz = normals[ nb * 3 + 2 ], + + ncx = normals[ nc * 3 ], + ncy = normals[ nc * 3 + 1 ], + ncz = normals[ nc * 3 + 2 ], + + ndx = normals[ nd * 3 ], + ndy = normals[ nd * 3 + 1 ], + ndz = normals[ nd * 3 + 2 ]; + + scope.faces.push( new THREE.Face3( a, b, d, [ + new THREE.Vector3( nax, nay, naz ), + new THREE.Vector3( nbx, nby, nbz ), + new THREE.Vector3( ndx, ndy, ndz ) + ], null, m ) ); + + scope.faces.push( new THREE.Face3( b, c, d, [ + new THREE.Vector3( nbx, nby, nbz ), + new THREE.Vector3( ncx, ncy, ncz ), + new THREE.Vector3( ndx, ndy, ndz ) + ], null, m ) ); + + } + + } + + function init_triangles_flat( start ) { + + var nElements = md.ntri_flat; + + if ( nElements ) { + + var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + init_faces3_flat( nElements, start, offsetMaterials ); + + } + + } + + function init_triangles_flat_uv( start ) { + + var nElements = md.ntri_flat_uv; + + if ( nElements ) { + + var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + + init_faces3_flat( nElements, start, offsetMaterials ); + init_uvs3( nElements, offsetUvs ); + + } + + } + + function init_triangles_smooth( start ) { + + var nElements = md.ntri_smooth; + + if ( nElements ) { + + var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + + init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials ); + + } + + } + + function init_triangles_smooth_uv( start ) { + + var nElements = md.ntri_smooth_uv; + + if ( nElements ) { + + var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3; + + init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials ); + init_uvs3( nElements, offsetUvs ); + + } + + } + + function init_quads_flat( start ) { + + var nElements = md.nquad_flat; + + if ( nElements ) { + + var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + init_faces4_flat( nElements, start, offsetMaterials ); + + } + + } + + function init_quads_flat_uv( start ) { + + var nElements = md.nquad_flat_uv; + + if ( nElements ) { + + var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + + init_faces4_flat( nElements, start, offsetMaterials ); + init_uvs4( nElements, offsetUvs ); + + } + + } + + function init_quads_smooth( start ) { + + var nElements = md.nquad_smooth; + + if ( nElements ) { + + var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + + init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials ); + + } + + } + + function init_quads_smooth_uv( start ) { + + var nElements = md.nquad_smooth_uv; + + if ( nElements ) { + + var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4; + + init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials ); + init_uvs4( nElements, offsetUvs ); + + } + + } + + }; + + Model.prototype = Object.create( THREE.Geometry.prototype ); + Model.prototype.constructor = Model; + + var geometry = new Model( texturePath ); + var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin ); + // FIX: register materials with transparency + for( var i in jsonMaterials ){ + if( jsonMaterials[i].transparent === true ){ + materials[i].transparent = true; + } + } + + callback( geometry, materials ); + + } + +}; diff --git a/examples/assets/js/libs/FirstPersonControls.js b/examples/assets/js/libs/FirstPersonControls.js new file mode 100644 index 0000000..2cceb2d --- /dev/null +++ b/examples/assets/js/libs/FirstPersonControls.js @@ -0,0 +1,284 @@ +/** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author paulirish / http://paulirish.com/ + */ + +THREE.FirstPersonControls = function ( object, domElement ) { + + this.object = object; + this.target = new THREE.Vector3( 0, 0, 0 ); + + this.domElement = ( domElement !== undefined ) ? domElement : document; + + this.movementSpeed = 1.0; + this.lookSpeed = 0.005; + + this.lookVertical = true; + this.autoForward = false; + // this.invertVertical = false; + + this.activeLook = true; + + this.heightSpeed = false; + this.heightCoef = 1.0; + this.heightMin = 0.0; + this.heightMax = 1.0; + + this.constrainVertical = false; + this.verticalMin = 0; + this.verticalMax = Math.PI; + + this.autoSpeedFactor = 0.0; + + this.mouseX = 0; + this.mouseY = 0; + + this.lat = 0; + this.lon = 0; + this.phi = 0; + this.theta = 0; + + this.moveForward = false; + this.moveBackward = false; + this.moveLeft = false; + this.moveRight = false; + this.freeze = false; + + this.mouseDragOn = false; + + this.viewHalfX = 0; + this.viewHalfY = 0; + + if ( this.domElement !== document ) { + + this.domElement.setAttribute( 'tabindex', -1 ); + + } + + // + + this.handleResize = function () { + + if ( this.domElement === document ) { + + this.viewHalfX = window.innerWidth / 2; + this.viewHalfY = window.innerHeight / 2; + + } else { + + this.viewHalfX = this.domElement.offsetWidth / 2; + this.viewHalfY = this.domElement.offsetHeight / 2; + + } + + }; + + this.onMouseDown = function ( event ) { + + if ( this.domElement !== document ) { + + this.domElement.focus(); + + } + + event.preventDefault(); + event.stopPropagation(); + + if ( this.activeLook ) { + + switch ( event.button ) { + + case 0: this.moveForward = true; break; + case 2: this.moveBackward = true; break; + + } + + } + + this.mouseDragOn = true; + + }; + + this.onMouseUp = function ( event ) { + + event.preventDefault(); + event.stopPropagation(); + + if ( this.activeLook ) { + + switch ( event.button ) { + + case 0: this.moveForward = false; break; + case 2: this.moveBackward = false; break; + + } + + } + + this.mouseDragOn = false; + + }; + + this.onMouseMove = function ( event ) { + + if ( this.domElement === document ) { + + this.mouseX = event.pageX - this.viewHalfX; + this.mouseY = event.pageY - this.viewHalfY; + + } else { + + this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; + this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; + + } + + }; + + this.onKeyDown = function ( event ) { + + //event.preventDefault(); + + switch ( event.keyCode ) { + + case 38: /*up*/ + case 87: /*W*/ this.moveForward = true; break; + + case 37: /*left*/ + case 65: /*A*/ this.moveLeft = true; break; + + case 40: /*down*/ + case 83: /*S*/ this.moveBackward = true; break; + + case 39: /*right*/ + case 68: /*D*/ this.moveRight = true; break; + + case 82: /*R*/ this.moveUp = true; break; + case 70: /*F*/ this.moveDown = true; break; + + case 81: /*Q*/ this.freeze = !this.freeze; break; + + } + + }; + + this.onKeyUp = function ( event ) { + + switch( event.keyCode ) { + + case 38: /*up*/ + case 87: /*W*/ this.moveForward = false; break; + + case 37: /*left*/ + case 65: /*A*/ this.moveLeft = false; break; + + case 40: /*down*/ + case 83: /*S*/ this.moveBackward = false; break; + + case 39: /*right*/ + case 68: /*D*/ this.moveRight = false; break; + + case 82: /*R*/ this.moveUp = false; break; + case 70: /*F*/ this.moveDown = false; break; + + } + + }; + + this.update = function( delta ) { + + if ( this.freeze ) { + + return; + + } + + if ( this.heightSpeed ) { + + var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax ); + var heightDelta = y - this.heightMin; + + this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef ); + + } else { + + this.autoSpeedFactor = 0.0; + + } + + var actualMoveSpeed = delta * this.movementSpeed; + + if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) ); + if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed ); + + if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed ); + if ( this.moveRight ) this.object.translateX( actualMoveSpeed ); + + if ( this.moveUp ) this.object.translateY( actualMoveSpeed ); + if ( this.moveDown ) this.object.translateY( - actualMoveSpeed ); + + var actualLookSpeed = delta * this.lookSpeed; + + if ( !this.activeLook ) { + + actualLookSpeed = 0; + + } + + var verticalLookRatio = 1; + + if ( this.constrainVertical ) { + + verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin ); + + } + + this.lon += this.mouseX * actualLookSpeed; + if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio; + + this.lat = Math.max( - 85, Math.min( 85, this.lat ) ); + this.phi = THREE.Math.degToRad( 90 - this.lat ); + + this.theta = THREE.Math.degToRad( this.lon ); + + if ( this.constrainVertical ) { + + this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax ); + + } + + var targetPosition = this.target, + position = this.object.position; + + targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta ); + targetPosition.y = position.y + 100 * Math.cos( this.phi ); + targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta ); + + this.object.lookAt( targetPosition ); + + }; + + + this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); + + this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false ); + this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false ); + this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false ); + + window.addEventListener( 'keydown', bind( this, this.onKeyDown ), false ); + window.addEventListener( 'keyup', bind( this, this.onKeyUp ), false ); + + function bind( scope, fn ) { + + return function () { + + fn.apply( scope, arguments ); + + }; + + }; + + this.handleResize(); + +}; diff --git a/examples/assets/js/libs/FlyControls.js b/examples/assets/js/libs/FlyControls.js index 75563ef..2a033ad 100644 --- a/examples/assets/js/libs/FlyControls.js +++ b/examples/assets/js/libs/FlyControls.js @@ -19,8 +19,6 @@ THREE.FlyControls = function ( object, domElement ) { // disable default target object behavior - this.object.useQuaternion = true; - // internals this.tmpQuaternion = new THREE.Quaternion(); @@ -130,11 +128,13 @@ THREE.FlyControls = function ( object, domElement ) { switch ( event.button ) { - case 0: this.object.moveForward = true; break; - case 2: this.object.moveBackward = true; break; + case 0: this.moveState.forward = 1; break; + case 2: this.moveState.back = 1; break; } + this.updateMovementVector(); + } }; @@ -171,11 +171,13 @@ THREE.FlyControls = function ( object, domElement ) { switch ( event.button ) { - case 0: this.moveForward = false; break; - case 2: this.moveBackward = false; break; + case 0: this.moveState.forward = 0; break; + case 2: this.moveState.back = 0; break; } + this.updateMovementVector(); + } this.updateRotationVector(); @@ -194,13 +196,10 @@ THREE.FlyControls = function ( object, domElement ) { this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize(); this.object.quaternion.multiply( this.tmpQuaternion ); - this.object.matrix.setPosition( this.object.position ); - this.object.matrix.setRotationFromQuaternion( this.object.quaternion ); - this.object.matrixWorldNeedsUpdate = true; - - // reflect rotation to the objects properties - this.object.rotation.setEulerFromRotationMatrix( this.object.matrix ); - + // expose the rotation vector for convenience + this.object.rotation.setFromQuaternion( this.object.quaternion, this.object.rotation.order ); + + }; this.updateMovementVector = function() { @@ -255,12 +254,14 @@ THREE.FlyControls = function ( object, domElement ) { }; + this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); + this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false ); this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false ); this.domElement.addEventListener( 'mouseup', bind( this, this.mouseup ), false ); - this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false ); - this.domElement.addEventListener( 'keyup', bind( this, this.keyup ), false ); + window.addEventListener( 'keydown', bind( this, this.keydown ), false ); + window.addEventListener( 'keyup', bind( this, this.keyup ), false ); this.updateMovementVector(); this.updateRotationVector(); diff --git a/examples/assets/js/libs/OBJMTLLoader.js b/examples/assets/js/libs/OBJMTLLoader.js index 82cc8e8..6a18402 100644 --- a/examples/assets/js/libs/OBJMTLLoader.js +++ b/examples/assets/js/libs/OBJMTLLoader.js @@ -5,169 +5,49 @@ * @author angelxuanchang */ -THREE.OBJMTLLoader = function () { - - THREE.EventDispatcher.call( this ); - -}; +THREE.OBJMTLLoader = function () {}; THREE.OBJMTLLoader.prototype = { constructor: THREE.OBJMTLLoader, - /** - * Load a Wavefront OBJ file with materials (MTL file) - * - * Loading progress is indicated by the following events: - * "load" event (successful loading): type = 'load', content = THREE.Object3D - * "error" event (error loading): type = 'load', message - * "progress" event (progress loading): type = 'progress', loaded, total - * - * If the MTL file cannot be loaded, then a MeshLambertMaterial is used as a default - * @param url - Location of OBJ file to load - * @param mtlfileurl - MTL file to load (optional, if not specified, attempts to use MTL specified in OBJ file) - * @param options - Options on how to interpret the material (see THREE.MTLLoader.MaterialCreator ) - */ - - load: function ( url, mtlfileurl, options ) { + load: function ( url, mtlurl, onLoad, onProgress, onError ) { var scope = this; - var xhr = new XMLHttpRequest(); - - var mtlDone; // Is the MTL done (true if no MTL, error loading MTL, or MTL actually loaded) - var obj3d; // Loaded model (from obj file) - var materialsCreator; // Material creator is created when MTL file is loaded - - // Loader for MTL - - var mtlLoader = new THREE.MTLLoader( url.substr( 0, url.lastIndexOf( "/" ) + 1 ), options ); - mtlLoader.addEventListener( 'load', waitReady ); - mtlLoader.addEventListener( 'error', waitReady ); - // Try to load mtlfile + var mtlLoader = new THREE.MTLLoader( url.substr( 0, url.lastIndexOf( "/" ) + 1 ) ); + mtlLoader.load( mtlurl, function ( materials ) { - if ( mtlfileurl ) { + var materialsCreator = materials; + materialsCreator.preload(); - mtlLoader.load( mtlfileurl ); - mtlDone = false; + var loader = new THREE.XHRLoader( scope.manager ); + loader.setCrossOrigin( this.crossOrigin ); + loader.load( url, function ( text ) { - } else { + var object = scope.parse( text ); - mtlDone = true; + object.traverse( function ( object ) { - } - - function waitReady( event ) { - - if ( event.type === 'load' ) { - - if ( event.content instanceof THREE.MTLLoader.MaterialCreator ) { - - // MTL file is loaded - - mtlDone = true; - materialsCreator = event.content; - materialsCreator.preload(); - - } else { + if ( object instanceof THREE.Mesh ) { - // OBJ file is loaded + if ( object.material.name ) { - if ( event.target.status === 200 || event.target.status === 0 ) { + var material = materialsCreator.create( object.material.name ); - var objContent = event.target.responseText; - - if ( mtlfileurl ) { - - // Parse with passed in MTL file - - obj3d = scope.parse( objContent ); - - } else { - - // No passed in MTL file, look for mtlfile in obj file - - obj3d = scope.parse( objContent, function( mtlfile ) { - - mtlDone = false; - mtlLoader.load( mtlLoader.baseUrl + mtlfile ); - - } ); + if ( material ) object.material = material; } - } else { - - // Error loading OBJ file.... - - scope.dispatchEvent( { - type: 'error', - message: 'Couldn\'t load URL [' + url + ']', - response: event.target.responseText } ); - } - } - - } else if ( event.type === 'error' ) { - - // MTL failed to load -- oh well, we will just not have material ... + } ); - mtlDone = true; - - } + onLoad( object ); - if ( mtlDone && obj3d ) { + } ); - // MTL file is loaded and OBJ file is loaded - // Apply materials to model - - if ( materialsCreator ) { -console.log(obj3d); - obj3d.traverse( function( object ) { - - if ( object instanceof THREE.Mesh ) { - - if ( object.material.name ) { - - var material = materialsCreator.create( object.material.name ); - if ( material ) { - - object.material = material; - - } - - } - - } - - } ); - - } - - // Notify listeners - - scope.dispatchEvent( { type: 'load', content: obj3d } ); - } - - } - - xhr.addEventListener( 'load', waitReady, false ); - - xhr.addEventListener( 'progress', function ( event ) { - - scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } ); - - }, false ); - - xhr.addEventListener( 'error', function () { - - scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } ); - - }, false ); - - xhr.open( 'GET', url, true ); - xhr.send( null ); + } ); }, @@ -180,12 +60,6 @@ console.log(obj3d); parse: function ( data, mtllibCallback ) { - // fixes - - data = data.replace( /\ \\\r\n/g, '' ); // rhino adds ' \\r\n' some times. - - // - function vector( x, y, z ) { return new THREE.Vector3( x, y, z ); @@ -204,18 +78,15 @@ console.log(obj3d); } - function face4( a, b, c, d, normals ) { - - return new THREE.Face4( a, b, c, d, normals ); - - } + var face_offset = 0; function meshN( meshName, materialName ) { - if ( geometry.vertices.length > 0 ) { + if ( vertices.length > 0 ) { + + geometry.vertices = vertices; geometry.mergeVertices(); - geometry.computeCentroids(); geometry.computeFaceNormals(); geometry.computeBoundingSphere(); @@ -224,11 +95,10 @@ console.log(obj3d); geometry = new THREE.Geometry(); mesh = new THREE.Mesh( geometry, material ); - verticesCount = 0; - } if ( meshName !== undefined ) mesh.name = meshName; + if ( materialName !== undefined ) { material = new THREE.MeshLambertMaterial(); @@ -248,37 +118,109 @@ console.log(obj3d); var mesh = new THREE.Mesh( geometry, material ); var vertices = []; - var verticesCount = 0; var normals = []; var uvs = []; + function add_face( a, b, c, normals_inds ) { + + if ( normals_inds === undefined ) { + + geometry.faces.push( face3( + parseInt( a ) - (face_offset + 1), + parseInt( b ) - (face_offset + 1), + parseInt( c ) - (face_offset + 1) + ) ); + + } else { + + geometry.faces.push( face3( + parseInt( a ) - (face_offset + 1), + parseInt( b ) - (face_offset + 1), + parseInt( c ) - (face_offset + 1), + [ + normals[ parseInt( normals_inds[ 0 ] ) - 1 ].clone(), + normals[ parseInt( normals_inds[ 1 ] ) - 1 ].clone(), + normals[ parseInt( normals_inds[ 2 ] ) - 1 ].clone() + ] + ) ); + + } + + } + + function add_uvs( a, b, c ) { + + geometry.faceVertexUvs[ 0 ].push( [ + uvs[ parseInt( a ) - 1 ].clone(), + uvs[ parseInt( b ) - 1 ].clone(), + uvs[ parseInt( c ) - 1 ].clone() + ] ); + + } + + function handle_face_line(faces, uvs, normals_inds) { + + if ( faces[ 3 ] === undefined ) { + + add_face( faces[ 0 ], faces[ 1 ], faces[ 2 ], normals_inds ); + + if (!(uvs === undefined) && uvs.length > 0) { + add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 2 ] ); + } + + } else { + + if (!(normals_inds === undefined) && normals_inds.length > 0) { + + add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ], [ normals_inds[ 0 ], normals_inds[ 1 ], normals_inds[ 3 ] ]); + add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ], [ normals_inds[ 1 ], normals_inds[ 2 ], normals_inds[ 3 ] ]); + + } else { + + add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ]); + add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ]); + + } + + if (!(uvs === undefined) && uvs.length > 0) { + + add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ); + add_uvs( uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ); + + } + + } + + } + + // v float float float - var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/; + var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; // vn float float float - var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/; + var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; // vt float float - var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/; + var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; // f vertex vertex vertex ... - var face_pattern1 = /f( +[\d]+)( [\d]+)( [\d]+)( [\d]+)?/; + var face_pattern1 = /f( +\d+)( +\d+)( +\d+)( +\d+)?/; // f vertex/uv vertex/uv vertex/uv ... - var face_pattern2 = /f( +([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))?/; + var face_pattern2 = /f( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))?/; // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... - var face_pattern3 = /f( +([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))?/; + var face_pattern3 = /f( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))?/; - // f vertex//normal vertex//normal vertex//normal ... + // f vertex//normal vertex//normal vertex//normal ... - var face_pattern4 = /f( +([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))?/; + var face_pattern4 = /f( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))?/ // @@ -289,8 +231,6 @@ console.log(obj3d); var line = lines[ i ]; line = line.trim(); - // temporary variable storing pattern matching result - var result; if ( line.length === 0 || line.charAt( 0 ) === '#' ) { @@ -330,215 +270,61 @@ console.log(obj3d); // ["f 1 2 3", "1", "2", "3", undefined] - if ( result[ 4 ] === undefined ) { - - geometry.vertices.push( - vertices[ parseInt( result[ 1 ] ) - 1 ], - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 3 ] ) - 1 ] - ); - - geometry.faces.push( face3( - verticesCount ++, - verticesCount ++, - verticesCount ++ - ) ); - - } else { - - geometry.vertices.push( - vertices[ parseInt( result[ 1 ] ) - 1 ], - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 3 ] ) - 1 ], - vertices[ parseInt( result[ 4 ] ) - 1 ] - ); - - geometry.faces.push( face4( - verticesCount ++, - verticesCount ++, - verticesCount ++, - verticesCount ++ - ) ); - - } + handle_face_line([ result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ] ]); } else if ( ( result = face_pattern2.exec( line ) ) !== null ) { // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] - - if ( result[ 10 ] === undefined ) { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 5 ] ) - 1 ], - vertices[ parseInt( result[ 8 ] ) - 1 ] - ); - - geometry.faces.push( face3( - verticesCount ++, - verticesCount ++, - verticesCount ++ - ) ); - - geometry.faceVertexUvs[ 0 ].push( [ - uvs[ parseInt( result[ 3 ] ) - 1 ], - uvs[ parseInt( result[ 6 ] ) - 1 ], - uvs[ parseInt( result[ 9 ] ) - 1 ] - ] ); - - } else { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 5 ] ) - 1 ], - vertices[ parseInt( result[ 8 ] ) - 1 ], - vertices[ parseInt( result[ 11 ] ) - 1 ] - ); - - geometry.faces.push( face4( - verticesCount ++, - verticesCount ++, - verticesCount ++, - verticesCount ++ - ) ); - - geometry.faceVertexUvs[ 0 ].push( [ - uvs[ parseInt( result[ 3 ] ) - 1 ], - uvs[ parseInt( result[ 6 ] ) - 1 ], - uvs[ parseInt( result[ 9 ] ) - 1 ], - uvs[ parseInt( result[ 12 ] ) - 1 ] - ] ); - - } + + handle_face_line( + [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces + [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //uv + ); } else if ( ( result = face_pattern3.exec( line ) ) !== null ) { // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined] - if ( result[ 13 ] === undefined ) { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 6 ] ) - 1 ], - vertices[ parseInt( result[ 10 ] ) - 1 ] - ); - - geometry.faces.push( face3( - verticesCount ++, - verticesCount ++, - verticesCount ++, - [ - normals[ parseInt( result[ 4 ] ) - 1 ], - normals[ parseInt( result[ 8 ] ) - 1 ], - normals[ parseInt( result[ 12 ] ) - 1 ] - ] - ) ); - - geometry.faceVertexUvs[ 0 ].push( [ - uvs[ parseInt( result[ 3 ] ) - 1 ], - uvs[ parseInt( result[ 7 ] ) - 1 ], - uvs[ parseInt( result[ 11 ] ) - 1 ] - ] ); - - } else { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 6 ] ) - 1 ], - vertices[ parseInt( result[ 10 ] ) - 1 ], - vertices[ parseInt( result[ 14 ] ) - 1 ] - ); - - geometry.faces.push( face4( - verticesCount ++, - verticesCount ++, - verticesCount ++, - verticesCount ++, - [ - normals[ parseInt( result[ 4 ] ) - 1 ], - normals[ parseInt( result[ 8 ] ) - 1 ], - normals[ parseInt( result[ 12 ] ) - 1 ], - normals[ parseInt( result[ 16 ] ) - 1 ] - ] - ) ); - - geometry.faceVertexUvs[ 0 ].push( [ - uvs[ parseInt( result[ 3 ] ) - 1 ], - uvs[ parseInt( result[ 7 ] ) - 1 ], - uvs[ parseInt( result[ 11 ] ) - 1 ], - uvs[ parseInt( result[ 15 ] ) - 1 ] - ] ); - - } + handle_face_line( + [ result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ] ], //faces + [ result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ] ], //uv + [ result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ] ] //normal + ); } else if ( ( result = face_pattern4.exec( line ) ) !== null ) { // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] - if ( result[ 10 ] === undefined ) { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 5 ] ) - 1 ], - vertices[ parseInt( result[ 8 ] ) - 1 ] - ); - - geometry.faces.push( face3( - verticesCount ++, - verticesCount ++, - verticesCount ++, - [ - normals[ parseInt( result[ 3 ] ) - 1 ], - normals[ parseInt( result[ 6 ] ) - 1 ], - normals[ parseInt( result[ 9 ] ) - 1 ] - ] - ) ); - - } else { - - geometry.vertices.push( - vertices[ parseInt( result[ 2 ] ) - 1 ], - vertices[ parseInt( result[ 5 ] ) - 1 ], - vertices[ parseInt( result[ 8 ] ) - 1 ], - vertices[ parseInt( result[ 11 ] ) - 1 ] - ); - - geometry.faces.push( face4( - verticesCount ++, - verticesCount ++, - verticesCount ++, - verticesCount ++, - [ - normals[ parseInt( result[ 3 ] ) - 1 ], - normals[ parseInt( result[ 6 ] ) - 1 ], - normals[ parseInt( result[ 9 ] ) - 1 ], - normals[ parseInt( result[ 12 ] ) - 1 ] - ] - ) ); + handle_face_line( + [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces + [ ], //uv + [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //normal + ); - } - - } else if ( line.startsWith( "o " ) ) { + } else if ( /^o /.test( line ) ) { // object - + + meshN(); + face_offset = face_offset + vertices.length; + vertices = []; object = new THREE.Object3D(); object.name = line.substring( 2 ).trim(); group.add( object ); - } else if ( line.startsWith( "g " ) ) { + } else if ( /^g /.test( line ) ) { // group meshN( line.substring( 2 ).trim(), undefined ); - } else if ( line.startsWith( "usemtl " ) ) { + } else if ( /^usemtl /.test( line ) ) { // material meshN( undefined, line.substring( 7 ).trim() ); - } else if ( line.startsWith( "mtllib ") ) { + } else if ( /^mtllib /.test( line ) ) { // mtl file @@ -550,7 +336,7 @@ console.log(obj3d); } - } else if ( line.startsWith( "s ") ) { + } else if ( /^s /.test( line ) ) { // Smooth shading @@ -562,8 +348,13 @@ console.log(obj3d); } + //Add last object + meshN(undefined, undefined); + return group; } }; + +THREE.EventDispatcher.prototype.apply( THREE.OBJMTLLoader.prototype ); diff --git a/examples/assets/js/libs/OculusRiftEffect.js b/examples/assets/js/libs/OculusRiftEffect.js new file mode 100644 index 0000000..d496334 --- /dev/null +++ b/examples/assets/js/libs/OculusRiftEffect.js @@ -0,0 +1,207 @@ +/** + * @author troffmo5 / http://github.com/troffmo5 + * + * Effect to render the scene in stereo 3d side by side with lens distortion. + * It is written to be used with the Oculus Rift (http://www.oculusvr.com/) but + * it works also with other HMD using the same technology + */ + +THREE.OculusRiftEffect = function ( renderer, options ) { + // worldFactor indicates how many units is 1 meter + var worldFactor = (options && options.worldFactor) ? options.worldFactor: 1.0; + + // Specific HMD parameters + var HMD = (options && options.HMD) ? options.HMD: { + // Parameters from the Oculus Rift DK1 + hResolution: 1280, + vResolution: 800, + hScreenSize: 0.14976, + vScreenSize: 0.0936, + interpupillaryDistance: 0.064, + lensSeparationDistance: 0.064, + eyeToScreenDistance: 0.041, + distortionK : [1.0, 0.22, 0.24, 0.0], + chromaAbParameter: [ 0.996, -0.004, 1.014, 0.0] + }; + + // Perspective camera + var pCamera = new THREE.PerspectiveCamera(); + pCamera.matrixAutoUpdate = false; + pCamera.target = new THREE.Vector3(); + + // Orthographic camera + var oCamera = new THREE.OrthographicCamera( -1, 1, 1, -1, 1, 1000 ); + oCamera.position.z = 1; + + // pre-render hooks + this.preLeftRender = function() {}; + this.preRightRender = function() {}; + + renderer.autoClear = false; + var emptyColor = new THREE.Color("black"); + + // Render target + var RTParams = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat }; + var renderTarget = new THREE.WebGLRenderTarget( 640, 800, RTParams ); + var RTMaterial = new THREE.ShaderMaterial( { + uniforms: { + "texid": { type: "t", value: renderTarget }, + "scale": { type: "v2", value: new THREE.Vector2(1.0,1.0) }, + "scaleIn": { type: "v2", value: new THREE.Vector2(1.0,1.0) }, + "lensCenter": { type: "v2", value: new THREE.Vector2(0.0,0.0) }, + "hmdWarpParam": { type: "v4", value: new THREE.Vector4(1.0,0.0,0.0,0.0) }, + "chromAbParam": { type: "v4", value: new THREE.Vector4(1.0,0.0,0.0,0.0) } + }, + vertexShader: [ + "varying vec2 vUv;", + "void main() {", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + "}" + ].join("\n"), + + fragmentShader: [ + "uniform vec2 scale;", + "uniform vec2 scaleIn;", + "uniform vec2 lensCenter;", + "uniform vec4 hmdWarpParam;", + 'uniform vec4 chromAbParam;', + "uniform sampler2D texid;", + "varying vec2 vUv;", + "void main()", + "{", + " vec2 uv = (vUv*2.0)-1.0;", // range from [0,1] to [-1,1] + " vec2 theta = (uv-lensCenter)*scaleIn;", + " float rSq = theta.x*theta.x + theta.y*theta.y;", + " vec2 rvector = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq);", + ' vec2 rBlue = rvector * (chromAbParam.z + chromAbParam.w * rSq);', + " vec2 tcBlue = (lensCenter + scale * rBlue);", + " tcBlue = (tcBlue+1.0)/2.0;", // range from [-1,1] to [0,1] + " if (any(bvec2(clamp(tcBlue, vec2(0.0,0.0), vec2(1.0,1.0))-tcBlue))) {", + " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", + " return;}", + " vec2 tcGreen = lensCenter + scale * rvector;", + " tcGreen = (tcGreen+1.0)/2.0;", // range from [-1,1] to [0,1] + " vec2 rRed = rvector * (chromAbParam.x + chromAbParam.y * rSq);", + " vec2 tcRed = lensCenter + scale * rRed;", + " tcRed = (tcRed+1.0)/2.0;", // range from [-1,1] to [0,1] + " gl_FragColor = vec4(texture2D(texid, tcRed).r, texture2D(texid, tcGreen).g, texture2D(texid, tcBlue).b, 1);", + "}" + ].join("\n") + } ); + + var mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), RTMaterial ); + + // Final scene + var finalScene = new THREE.Scene(); + finalScene.add( oCamera ); + finalScene.add( mesh ); + + var left = {}, right = {}; + var distScale = 1.0; + this.setHMD = function(v) { + HMD = v; + // Compute aspect ratio and FOV + var aspect = HMD.hResolution / (2*HMD.vResolution); + + // Fov is normally computed with: + // THREE.Math.radToDeg( 2*Math.atan2(HMD.vScreenSize,2*HMD.eyeToScreenDistance) ); + // But with lens distortion it is increased (see Oculus SDK Documentation) + var r = -1.0 - (4 * (HMD.hScreenSize/4 - HMD.lensSeparationDistance/2) / HMD.hScreenSize); + distScale = (HMD.distortionK[0] + HMD.distortionK[1] * Math.pow(r,2) + HMD.distortionK[2] * Math.pow(r,4) + HMD.distortionK[3] * Math.pow(r,6)); + var fov = THREE.Math.radToDeg(2*Math.atan2(HMD.vScreenSize*distScale, 2*HMD.eyeToScreenDistance)); + + // Compute camera projection matrices + var proj = (new THREE.Matrix4()).makePerspective( fov, aspect, 0.3, 10000 ); + var h = 4 * (HMD.hScreenSize/4 - HMD.interpupillaryDistance/2) / HMD.hScreenSize; + left.proj = ((new THREE.Matrix4()).makeTranslation( h, 0.0, 0.0 )).multiply(proj); + right.proj = ((new THREE.Matrix4()).makeTranslation( -h, 0.0, 0.0 )).multiply(proj); + + // Compute camera transformation matrices + left.tranform = (new THREE.Matrix4()).makeTranslation( -worldFactor * HMD.interpupillaryDistance/2, 0.0, 0.0 ); + right.tranform = (new THREE.Matrix4()).makeTranslation( worldFactor * HMD.interpupillaryDistance/2, 0.0, 0.0 ); + + // Compute Viewport + left.viewport = [0, 0, HMD.hResolution/2, HMD.vResolution]; + right.viewport = [HMD.hResolution/2, 0, HMD.hResolution/2, HMD.vResolution]; + + // Distortion shader parameters + var lensShift = 4 * (HMD.hScreenSize/4 - HMD.lensSeparationDistance/2) / HMD.hScreenSize; + left.lensCenter = new THREE.Vector2(lensShift, 0.0); + right.lensCenter = new THREE.Vector2(-lensShift, 0.0); + + RTMaterial.uniforms['hmdWarpParam'].value = new THREE.Vector4(HMD.distortionK[0], HMD.distortionK[1], HMD.distortionK[2], HMD.distortionK[3]); + RTMaterial.uniforms['chromAbParam'].value = new THREE.Vector4(HMD.chromaAbParameter[0], HMD.chromaAbParameter[1], HMD.chromaAbParameter[2], HMD.chromaAbParameter[3]); + RTMaterial.uniforms['scaleIn'].value = new THREE.Vector2(1.0,1.0/aspect); + RTMaterial.uniforms['scale'].value = new THREE.Vector2(1.0/distScale, 1.0*aspect/distScale); + + // Create render target + if ( renderTarget ) renderTarget.dispose(); + renderTarget = new THREE.WebGLRenderTarget( HMD.hResolution*distScale/2, HMD.vResolution*distScale, RTParams ); + RTMaterial.uniforms[ "texid" ].value = renderTarget; + + } + this.getHMD = function() {return HMD}; + + this.setHMD(HMD); + + this.setSize = function ( width, height ) { + left.viewport = [width/2 - HMD.hResolution/2, height/2 - HMD.vResolution/2, HMD.hResolution/2, HMD.vResolution]; + right.viewport = [width/2, height/2 - HMD.vResolution/2, HMD.hResolution/2, HMD.vResolution]; + + renderer.setSize( width, height ); + }; + + this.render = function ( scene, camera ) { + var cc = renderer.getClearColor().clone(); + + // Clear + renderer.setClearColor(emptyColor); + renderer.clear(); + renderer.setClearColor(cc); + + // camera parameters + if (camera.matrixAutoUpdate) camera.updateMatrix(); + + // Render left + this.preLeftRender(); + + pCamera.projectionMatrix.copy(left.proj); + + pCamera.matrix.copy(camera.matrix).multiply(left.tranform); + pCamera.matrixWorldNeedsUpdate = true; + + renderer.setViewport(left.viewport[0], left.viewport[1], left.viewport[2], left.viewport[3]); + + RTMaterial.uniforms['lensCenter'].value = left.lensCenter; + renderer.render( scene, pCamera, renderTarget, true ); + + renderer.render( finalScene, oCamera ); + + // Render right + this.preRightRender(); + + pCamera.projectionMatrix.copy(right.proj); + + pCamera.matrix.copy(camera.matrix).multiply(right.tranform); + pCamera.matrixWorldNeedsUpdate = true; + + renderer.setViewport(right.viewport[0], right.viewport[1], right.viewport[2], right.viewport[3]); + + RTMaterial.uniforms['lensCenter'].value = right.lensCenter; + + renderer.render( scene, pCamera, renderTarget, true ); + renderer.render( finalScene, oCamera ); + + }; + + this.dispose = function() { + if ( RTMaterial ) { + RTMaterial.dispose(); + } + if ( renderTarget ) { + renderTarget.dispose(); + } + }; + +}; diff --git a/examples/assets/js/libs/OrbitControls.js b/examples/assets/js/libs/OrbitControls.js new file mode 100644 index 0000000..e150b58 --- /dev/null +++ b/examples/assets/js/libs/OrbitControls.js @@ -0,0 +1,706 @@ +/** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + */ +/*global THREE, console */ + +// This set of controls performs orbiting, dollying (zooming), and panning. It maintains +// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is +// supported. +// +// Orbit - left mouse / touch: one finger move +// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish +// Pan - right mouse, or arrow keys / touch: three finter swipe + +THREE.OrbitControls = function ( object, domElement ) { + + this.object = object; + this.domElement = ( domElement !== undefined ) ? domElement : document; + + // API + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the control orbits around + // and where it pans with respect to. + this.target = new THREE.Vector3(); + + // center is old, deprecated; use "target" instead + this.center = this.target; + + // This option actually enables dollying in and out; left as "zoom" for + // backwards compatibility + this.noZoom = false; + this.zoomSpeed = 1.0; + + // Limits to how far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + + // Limits to how far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // Set to true to disable this control + this.noRotate = false; + this.rotateSpeed = 1.0; + + // Set to true to disable this control + this.noPan = false; + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + + // Set to true to automatically rotate around the target + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to disable use of the keys + this.noKeys = false; + + // The four arrow keys + this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; + + // Mouse buttons + this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; + + //////////// + // internals + + var scope = this; + + var EPS = 0.000001; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + var panOffset = new THREE.Vector3(); + + var offset = new THREE.Vector3(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + var theta; + var phi; + var phiDelta = 0; + var thetaDelta = 0; + var scale = 1; + var pan = new THREE.Vector3(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; + + var state = STATE.NONE; + + // for reset + + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // so camera.up is the orbit axis + + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); + + // events + + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; + + this.rotateLeft = function ( angle ) { + + if ( angle === undefined ) { + + angle = getAutoRotationAngle(); + + } + + thetaDelta -= angle; + + }; + + this.rotateUp = function ( angle ) { + + if ( angle === undefined ) { + + angle = getAutoRotationAngle(); + + } + + phiDelta -= angle; + + }; + + // pass in distance in world space to move left + this.panLeft = function ( distance ) { + + var te = this.object.matrix.elements; + + // get X column of matrix + panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] ); + panOffset.multiplyScalar( - distance ); + + pan.add( panOffset ); + + }; + + // pass in distance in world space to move up + this.panUp = function ( distance ) { + + var te = this.object.matrix.elements; + + // get Y column of matrix + panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] ); + panOffset.multiplyScalar( distance ); + + pan.add( panOffset ); + + }; + + // pass in x,y of change desired in pixel space, + // right and down are positive + this.pan = function ( deltaX, deltaY ) { + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + // perspective + var position = scope.object.position; + var offset = position.clone().sub( scope.target ); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + + // we actually don't use screenWidth, since perspective camera is fixed to screen height + scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight ); + scope.panUp( 2 * deltaY * targetDistance / element.clientHeight ); + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + // orthographic + scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth ); + scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight ); + + } else { + + // camera neither orthographic or perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + + } + + }; + + this.dollyIn = function ( dollyScale ) { + + if ( dollyScale === undefined ) { + + dollyScale = getZoomScale(); + + } + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + + } + + }; + + this.dollyOut = function ( dollyScale ) { + + if ( dollyScale === undefined ) { + + dollyScale = getZoomScale(); + + } + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + + } + + }; + + this.update = function () { + + var position = this.object.position; + + offset.copy( position ).sub( this.target ); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + + // angle from z-axis around y-axis + + theta = Math.atan2( offset.x, offset.z ); + + // angle from y-axis + + phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y ); + + if ( this.autoRotate && state === STATE.NONE ) { + + this.rotateLeft( getAutoRotationAngle() ); + + } + + theta += thetaDelta; + phi += phiDelta; + + // restrict theta to be between desired limits + theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) ); + + // restrict phi to be between desired limits + phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) ); + + // restrict phi to be betwee EPS and PI-EPS + phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) ); + + var radius = offset.length() * scale; + + // restrict radius to be between desired limits + radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) ); + + // move target to panned location + this.target.add( pan ); + + offset.x = radius * Math.sin( phi ) * Math.sin( theta ); + offset.y = radius * Math.cos( phi ); + offset.z = radius * Math.sin( phi ) * Math.cos( theta ); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); + + position.copy( this.target ).add( offset ); + + this.object.lookAt( this.target ); + + thetaDelta = 0; + phiDelta = 0; + scale = 1; + pan.set( 0, 0, 0 ); + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + + if ( lastPosition.distanceToSquared( this.object.position ) > EPS + || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) { + + this.dispatchEvent( changeEvent ); + + lastPosition.copy( this.object.position ); + lastQuaternion.copy (this.object.quaternion ); + + } + + }; + + + this.reset = function () { + + state = STATE.NONE; + + this.target.copy( this.target0 ); + this.object.position.copy( this.position0 ); + this.object.zoom = this.zoom0; + + this.object.updateProjectionMatrix(); + this.dispatchEvent( changeEvent ); + + this.update(); + + }; + + this.getPolarAngle = function () { + + return phi; + + }; + + this.getAzimuthalAngle = function () { + + return theta + + }; + + function getAutoRotationAngle() { + + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + + } + + function getZoomScale() { + + return Math.pow( 0.95, scope.zoomSpeed ); + + } + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + event.preventDefault(); + + if ( event.button === scope.mouseButtons.ORBIT ) { + if ( scope.noRotate === true ) return; + + state = STATE.ROTATE; + + rotateStart.set( event.clientX, event.clientY ); + + } else if ( event.button === scope.mouseButtons.ZOOM ) { + if ( scope.noZoom === true ) return; + + state = STATE.DOLLY; + + dollyStart.set( event.clientX, event.clientY ); + + } else if ( event.button === scope.mouseButtons.PAN ) { + if ( scope.noPan === true ) return; + + state = STATE.PAN; + + panStart.set( event.clientX, event.clientY ); + + } + + if ( state !== STATE.NONE ) { + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + scope.dispatchEvent( startEvent ); + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( state === STATE.ROTATE ) { + + if ( scope.noRotate === true ) return; + + rotateEnd.set( event.clientX, event.clientY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + // rotating across whole screen goes 360 degrees around + scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + + // rotating up and down along whole screen attempts to go 360, but limited to 180 + scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + + } else if ( state === STATE.DOLLY ) { + + if ( scope.noZoom === true ) return; + + dollyEnd.set( event.clientX, event.clientY ); + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + scope.dollyIn(); + + } else if ( dollyDelta.y < 0 ) { + + scope.dollyOut(); + + } + + dollyStart.copy( dollyEnd ); + + } else if ( state === STATE.PAN ) { + + if ( scope.noPan === true ) return; + + panEnd.set( event.clientX, event.clientY ); + panDelta.subVectors( panEnd, panStart ); + + scope.pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + } + + if ( state !== STATE.NONE ) scope.update(); + + } + + function onMouseUp( /* event */ ) { + + if ( scope.enabled === false ) return; + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + scope.dispatchEvent( endEvent ); + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.noZoom === true || state !== STATE.NONE ) return; + + event.preventDefault(); + event.stopPropagation(); + + var delta = 0; + + if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9 + + delta = event.wheelDelta; + + } else if ( event.detail !== undefined ) { // Firefox + + delta = - event.detail; + + } + + if ( delta > 0 ) { + + scope.dollyOut(); + + } else if ( delta < 0 ) { + + scope.dollyIn(); + + } + + scope.update(); + scope.dispatchEvent( startEvent ); + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return; + + switch ( event.keyCode ) { + + case scope.keys.UP: + scope.pan( 0, scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.BOTTOM: + scope.pan( 0, - scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.LEFT: + scope.pan( scope.keyPanSpeed, 0 ); + scope.update(); + break; + + case scope.keys.RIGHT: + scope.pan( - scope.keyPanSpeed, 0 ); + scope.update(); + break; + + } + + } + + function touchstart( event ) { + + if ( scope.enabled === false ) return; + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.noRotate === true ) return; + + state = STATE.TOUCH_ROTATE; + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + break; + + case 2: // two-fingered touch: dolly + + if ( scope.noZoom === true ) return; + + state = STATE.TOUCH_DOLLY; + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + var distance = Math.sqrt( dx * dx + dy * dy ); + dollyStart.set( 0, distance ); + break; + + case 3: // three-fingered touch: pan + + if ( scope.noPan === true ) return; + + state = STATE.TOUCH_PAN; + + panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + break; + + default: + + state = STATE.NONE; + + } + + if ( state !== STATE.NONE ) scope.dispatchEvent( startEvent ); + + } + + function touchmove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + event.stopPropagation(); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.noRotate === true ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + // rotating across whole screen goes 360 degrees around + scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + // rotating up and down along whole screen attempts to go 360, but limited to 180 + scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + break; + + case 2: // two-fingered touch: dolly + + if ( scope.noZoom === true ) return; + if ( state !== STATE.TOUCH_DOLLY ) return; + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyEnd.set( 0, distance ); + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + scope.dollyOut(); + + } else if ( dollyDelta.y < 0 ) { + + scope.dollyIn(); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + break; + + case 3: // three-fingered touch: pan + + if ( scope.noPan === true ) return; + if ( state !== STATE.TOUCH_PAN ) return; + + panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + panDelta.subVectors( panEnd, panStart ); + + scope.pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + break; + + default: + + state = STATE.NONE; + + } + + } + + function touchend( /* event */ ) { + + if ( scope.enabled === false ) return; + + scope.dispatchEvent( endEvent ); + state = STATE.NONE; + + } + + this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); + this.domElement.addEventListener( 'mousedown', onMouseDown, false ); + this.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); + this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox + + this.domElement.addEventListener( 'touchstart', touchstart, false ); + this.domElement.addEventListener( 'touchend', touchend, false ); + this.domElement.addEventListener( 'touchmove', touchmove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + this.update(); + +}; + +THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); +THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; diff --git a/examples/assets/js/libs/ShaderTerrain.js b/examples/assets/js/libs/ShaderTerrain.js new file mode 100644 index 0000000..015180d --- /dev/null +++ b/examples/assets/js/libs/ShaderTerrain.js @@ -0,0 +1,323 @@ +/** + * @author alteredq / http://alteredqualia.com/ + * + */ + +THREE.ShaderTerrain = { + + /* ------------------------------------------------------------------------- + // Dynamic terrain shader + // - Blinn-Phong + // - height + normal + diffuse1 + diffuse2 + specular + detail maps + // - point, directional and hemisphere lights (use with "lights: true" material option) + // - shadow maps receiving + ------------------------------------------------------------------------- */ + + 'terrain' : { + + uniforms: Object.assign( + + + { + + "enableDiffuse1": { value: 0 }, + "enableDiffuse2": { value: 0 }, + "enableSpecular": { value: 0 }, + "enableReflection": { value: 0 }, + + "tDiffuse1": { value: null }, + "tDiffuse2": { value: null }, + "tDetail": { value: null }, + "tNormal": { value: null }, + "tSpecular": { value: null }, + "tDisplacement": { value: null }, + + "uNormalScale": { value: 1.0 }, + + "uDisplacementBias": { value: 0.0 }, + "uDisplacementScale": { value: 1.0 }, + + "diffuse": { value: new THREE.Color( 0xeeeeee ) }, + "specular": { value: new THREE.Color( 0x111111 ) }, + "shininess": { value: 30 }, + "opacity": { value: 1 }, + + "uRepeatBase": { value: new THREE.Vector2( 1, 1 ) }, + "uRepeatOverlay": { value: new THREE.Vector2( 1, 1 ) }, + + "uOffset": { value: new THREE.Vector2( 0, 0 ) } + + }, + + THREE.UniformsLib[ "fog" ], + THREE.UniformsLib[ "lights" ] + + ), + + fragmentShader: [ + + "uniform vec3 diffuse;", + "uniform vec3 specular;", + "uniform float shininess;", + "uniform float opacity;", + + "uniform bool enableDiffuse1;", + "uniform bool enableDiffuse2;", + "uniform bool enableSpecular;", + + "uniform sampler2D tDiffuse1;", + "uniform sampler2D tDiffuse2;", + "uniform sampler2D tDetail;", + "uniform sampler2D tNormal;", + "uniform sampler2D tSpecular;", + "uniform sampler2D tDisplacement;", + + "uniform float uNormalScale;", + + "uniform vec2 uRepeatOverlay;", + "uniform vec2 uRepeatBase;", + + "uniform vec2 uOffset;", + + "varying vec3 vTangent;", + "varying vec3 vBinormal;", + "varying vec3 vNormal;", + "varying vec2 vUv;", + + "varying vec3 vViewPosition;", + + THREE.ShaderChunk[ "common" ], + THREE.ShaderChunk[ "bsdfs" ], + THREE.ShaderChunk[ "lights_pars" ], + THREE.ShaderChunk[ "shadowmap_pars_fragment" ], + THREE.ShaderChunk[ "fog_pars_fragment" ], + + "float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {", + "if ( decayExponent > 0.0 ) {", + "return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );", + "}", + "return 1.0;", + "}", + + "void main() {", + + "vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does + "vec4 diffuseColor = vec4( diffuse, opacity );", + + "vec3 specularTex = vec3( 1.0 );", + + "vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;", + "vec2 uvBase = uRepeatBase * vUv;", + + "vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;", + "normalTex.xy *= uNormalScale;", + "normalTex = normalize( normalTex );", + + "if( enableDiffuse1 && enableDiffuse2 ) {", + + "vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );", + "vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );", + + "colDiffuse1 = GammaToLinear( colDiffuse1, float( GAMMA_FACTOR ) );", + "colDiffuse2 = GammaToLinear( colDiffuse2, float( GAMMA_FACTOR ) );", + + "diffuseColor *= mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", + + " } else if( enableDiffuse1 ) {", + + "diffuseColor *= texture2D( tDiffuse1, uvOverlay );", + + "} else if( enableDiffuse2 ) {", + + "diffuseColor *= texture2D( tDiffuse2, uvOverlay );", + + "}", + + "if( enableSpecular )", + "specularTex = texture2D( tSpecular, uvOverlay ).xyz;", + + "mat3 tsb = mat3( vTangent, vBinormal, vNormal );", + "vec3 finalNormal = tsb * normalTex;", + + "vec3 normal = normalize( finalNormal );", + "vec3 viewPosition = normalize( vViewPosition );", + + "vec3 totalDiffuseLight = vec3( 0.0 );", + "vec3 totalSpecularLight = vec3( 0.0 );", + + // point lights + + "#if NUM_POINT_LIGHTS > 0", + + "for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {", + + "vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;", + + "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", + + "lVector = normalize( lVector );", + + "vec3 pointHalfVector = normalize( lVector + viewPosition );", + + "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", + "float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );", + + "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );", + + "totalDiffuseLight += attenuation * pointLights[ i ].color * pointDiffuseWeight;", + "totalSpecularLight += attenuation * pointLights[ i ].color * specular * pointSpecularWeight * pointDiffuseWeight;", + + "}", + + "#endif", + + // directional lights + + "#if NUM_DIR_LIGHTS > 0", + + "vec3 dirDiffuse = vec3( 0.0 );", + "vec3 dirSpecular = vec3( 0.0 );", + + "for( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {", + + "vec3 dirVector = directionalLights[ i ].direction;", + "vec3 dirHalfVector = normalize( dirVector + viewPosition );", + + "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", + "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", + + "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );", + + "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", + "totalSpecularLight += directionalLights[ i ].color * specular * dirSpecularWeight * dirDiffuseWeight;", + + "}", + + "#endif", + + // hemisphere lights + + "#if NUM_HEMI_LIGHTS > 0", + + "vec3 hemiDiffuse = vec3( 0.0 );", + "vec3 hemiSpecular = vec3( 0.0 );", + + "for( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {", + + "vec3 lVector = hemisphereLightDirection[ i ];", + + // diffuse + + "float dotProduct = dot( normal, lVector );", + "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", + + "totalDiffuseLight += mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight );", + + // specular (sky light) + + "float hemiSpecularWeight = 0.0;", + + "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );", + "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;", + "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );", + + // specular (ground light) + + "vec3 lVectorGround = -lVector;", + + "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );", + "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", + "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", + + "totalSpecularLight += specular * mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", + + "}", + + "#endif", + + "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );", + + "gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects + + THREE.ShaderChunk[ "fog_fragment" ], + + "}" + + ].join( "\n" ), + + vertexShader: [ + + "attribute vec4 tangent;", + + "uniform vec2 uRepeatBase;", + + "uniform sampler2D tNormal;", + + "#ifdef VERTEX_TEXTURES", + + "uniform sampler2D tDisplacement;", + "uniform float uDisplacementScale;", + "uniform float uDisplacementBias;", + + "#endif", + + "varying vec3 vTangent;", + "varying vec3 vBinormal;", + "varying vec3 vNormal;", + "varying vec2 vUv;", + + "varying vec3 vViewPosition;", + + THREE.ShaderChunk[ "shadowmap_pars_vertex" ], + + "void main() {", + + "vNormal = normalize( normalMatrix * normal );", + + // tangent and binormal vectors + + "vTangent = normalize( normalMatrix * tangent.xyz );", + + "vBinormal = cross( vNormal, vTangent ) * tangent.w;", + "vBinormal = normalize( vBinormal );", + + // texture coordinates + + "vUv = uv;", + + "vec2 uvBase = uv * uRepeatBase;", + + // displacement mapping + + "#ifdef VERTEX_TEXTURES", + + "vec3 dv = texture2D( tDisplacement, uvBase ).xyz;", + "float df = uDisplacementScale * dv.x + uDisplacementBias;", + "vec3 displacedPosition = normal * df + position;", + + "vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );", + "vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );", + + "#else", + + "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + + "#endif", + + "gl_Position = projectionMatrix * mvPosition;", + + "vViewPosition = -mvPosition.xyz;", + + "vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;", + "vNormal = normalMatrix * normalTex;", + + THREE.ShaderChunk[ "shadowmap_vertex" ], + + "}" + + ].join( "\n" ) + + } + +}; diff --git a/examples/assets/js/libs/three.min.js b/examples/assets/js/libs/three.min.js index 9444281..47cb69e 100644 --- a/examples/assets/js/libs/three.min.js +++ b/examples/assets/js/libs/three.min.js @@ -1,699 +1,838 @@ -// three.js - http://github.com/mrdoob/three.js -'use strict';var THREE=THREE||{REVISION:"55"};self.console=self.console||{info:function(){},log:function(){},debug:function(){},warn:function(){},error:function(){}};self.Int32Array=self.Int32Array||Array;self.Float32Array=self.Float32Array||Array;String.prototype.startsWith=String.prototype.startsWith||function(a){return this.slice(0,a.length)===a};String.prototype.endsWith=String.prototype.endsWith||function(a){var a=String(a),b=this.lastIndexOf(a);return(-1>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSV:function(a,b,c){var d,e,f;0===c?this.r=this.g=this.b=0:(d=Math.floor(6*a),e=6*a-d,a=c*(1-b),f=c*(1-b*e),b=c*(1-b*(1-e)),0===d?(this.r=c,this.g=b,this.b=a):1=== -d?(this.r=f,this.g=c,this.b=a):2===d?(this.r=a,this.g=c,this.b=b):3===d?(this.r=a,this.g=f,this.b=c):4===d?(this.r=b,this.g=a,this.b=c):5===d&&(this.r=c,this.g=a,this.b=f));return this},setStyle:function(a){if(/^rgb\((\d+),(\d+),(\d+)\)$/i.test(a))return a=/^rgb\((\d+),(\d+),(\d+)\)$/i.exec(a),this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,this;if(/^rgb\((\d+)\%,(\d+)\%,(\d+)\%\)$/i.test(a))return a=/^rgb\((\d+)\%,(\d+)\%,(\d+)\%\)$/i.exec(a), -this.r=Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,this;if(/^\#([0-9a-f]{6})$/i.test(a))return a=/^\#([0-9a-f]{6})$/i.exec(a),this.setHex(parseInt(a[1],16)),this;if(/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(a))return a=/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a),this.setHex(parseInt(a[1]+a[1]+a[2]+a[2]+a[3]+a[3],16)),this;if(/^(\w+)$/i.test(a))return this.setHex(THREE.ColorKeywords[a]),this},copy:function(a){this.r=a.r; -this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},convertGammaToLinear:function(){var a=this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^ -255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getStyle:function(){return"rgb("+(255*this.r|0)+","+(255*this.g|0)+","+(255*this.b|0)+")"},getHSV:function(a){var b=this.r,c=this.g,d=this.b,e=Math.max(Math.max(b,c),d),f=Math.min(Math.min(b,c),d);if(f===e)f=b=0;else{var g=e-f,f=g/e,b=(b===e?(c-d)/g:c===e?2+(d-b)/g:4+(b-c)/g)/6;0>b&&(b+=1);1f&&c>b?(c=2*Math.sqrt(1+c-f-b),this.w=(h-g)/c,this.x=0.25*c,this.y=(a+e)/c,this.z=(d+i)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this.w=(d-i)/c,this.x=(a+e)/c,this.y=0.25*c,this.z=(g+h)/c):(c=2*Math.sqrt(1+b-c-f),this.w=(e-a)/c,this.x=(d+i)/c,this.y=(g+h)/c,this.z=0.25*c);return this},inverse:function(){this.conjugate().normalize(); -return this},conjugate:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=this.length();0===a?(this.z=this.y=this.x=0,this.w=1):(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiply:function(a,b){return void 0!==b?(console.warn("DEPRECATED: Quaternion's .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."), -this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a.x,d=a.y,e=a.z,f=a.w,g=b.x,i=b.y,h=b.z,k=b.w;this.x=c*k+f*g+d*h-e*i;this.y=d*k+f*i+e*g-c*h;this.z=e*k+f*h+c*i-d*g;this.w=f*k-c*g-d*i-e*h;return this},multiplyVector3:function(a){console.warn("DEPRECATED: Quaternion's .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)},slerp:function(a,b){var c=this.x,d=this.y,e=this.z, -f=this.w,g=f*a.w+c*a.x+d*a.y+e*a.z;0>g?(this.w=-a.w,this.x=-a.x,this.y=-a.y,this.z=-a.z,g=-g):this.copy(a);if(1<=g)return this.w=f,this.x=c,this.y=d,this.z=e,this;var i=Math.acos(g),h=Math.sqrt(1-g*g);if(0.001>Math.abs(h))return this.w=0.5*(f+this.w),this.x=0.5*(c+this.x),this.y=0.5*(d+this.y),this.z=0.5*(e+this.z),this;g=Math.sin((1-b)*i)/h;i=Math.sin(b*i)/h;this.w=f*g+this.w*i;this.x=c*g+this.x*i;this.y=d*g+this.y*i;this.z=e*g+this.z*i;return this},equals:function(a){return a.x===this.x&&a.y=== -this.y&&a.z===this.z&&a.w===this.w},clone:function(){return new THREE.Quaternion(this.x,this.y,this.z,this.w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; -THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, -b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-= -a.y;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a):this.set(0,0);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);return this}, -negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/ -b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; -THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ -a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), -this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x* -b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements,e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]); -this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z,a=a.w,i=a*b+f*d-g*c,h=a*c+g*b-e*d,k=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=i*a+b*-e+h*-g-k*-f;this.y=h*a+b*-f+k*-e-i*-g;this.z=k*a+b*-g+i*-f-h*-e;return this},applyEuler:function(a,b){var c=THREE.Vector3.__q1.setFromEuler(a,b);this.applyQuaternion(c);return this},applyAxisAngle:function(a,b){var c=THREE.Vector3.__q1.setFromAxisAngle(a, -b);this.applyQuaternion(c);return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a,this.z/=a):this.z=this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b= -this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},cross:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){this.x=a.y*b.z-a.z*b.y;this.y= -a.z*b.x-a.x*b.z;this.z=a.x*b.y-a.y*b.x;return this},angleTo:function(a){return Math.acos(this.dot(a)/this.length()/a.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y,a=this.z-a.z;return b*b+c*c+a*a},getPositionFromMatrix:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setEulerFromRotationMatrix:function(a,b){function c(a){return Math.min(Math.max(a,-1),1)}var d=a.elements, -e=d[0],f=d[4],g=d[8],i=d[1],h=d[5],k=d[9],l=d[2],m=d[6],d=d[10];void 0===b||"XYZ"===b?(this.y=Math.asin(c(g)),0.99999>Math.abs(g)?(this.x=Math.atan2(-k,d),this.z=Math.atan2(-f,e)):(this.x=Math.atan2(m,h),this.z=0)):"YXZ"===b?(this.x=Math.asin(-c(k)),0.99999>Math.abs(k)?(this.y=Math.atan2(g,d),this.z=Math.atan2(i,h)):(this.y=Math.atan2(-l,e),this.z=0)):"ZXY"===b?(this.x=Math.asin(c(m)),0.99999>Math.abs(m)?(this.y=Math.atan2(-l,d),this.z=Math.atan2(-f,h)):(this.y=0,this.z=Math.atan2(i,e))):"ZYX"=== -b?(this.y=Math.asin(-c(l)),0.99999>Math.abs(l)?(this.x=Math.atan2(m,d),this.z=Math.atan2(i,e)):(this.x=0,this.z=Math.atan2(-f,h))):"YZX"===b?(this.z=Math.asin(c(i)),0.99999>Math.abs(i)?(this.x=Math.atan2(-k,h),this.y=Math.atan2(-l,e)):(this.x=0,this.y=Math.atan2(g,d))):"XZY"===b&&(this.z=Math.asin(-c(f)),0.99999>Math.abs(f)?(this.x=Math.atan2(m,h),this.y=Math.atan2(g,e)):(this.x=Math.atan2(-k,d),this.y=0));return this},setEulerFromQuaternion:function(a,b){function c(a){return Math.min(Math.max(a, --1),1)}var d=a.x*a.x,e=a.y*a.y,f=a.z*a.z,g=a.w*a.w;void 0===b||"XYZ"===b?(this.x=Math.atan2(2*(a.x*a.w-a.y*a.z),g-d-e+f),this.y=Math.asin(c(2*(a.x*a.z+a.y*a.w))),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g+d-e-f)):"YXZ"===b?(this.x=Math.asin(c(2*(a.x*a.w-a.y*a.z))),this.y=Math.atan2(2*(a.x*a.z+a.y*a.w),g-d-e+f),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g-d+e-f)):"ZXY"===b?(this.x=Math.asin(c(2*(a.x*a.w+a.y*a.z))),this.y=Math.atan2(2*(a.y*a.w-a.z*a.x),g-d-e+f),this.z=Math.atan2(2*(a.z*a.w-a.x*a.y),g-d+e-f)): -"ZYX"===b?(this.x=Math.atan2(2*(a.x*a.w+a.z*a.y),g-d-e+f),this.y=Math.asin(c(2*(a.y*a.w-a.x*a.z))),this.z=Math.atan2(2*(a.x*a.y+a.z*a.w),g+d-e-f)):"YZX"===b?(this.x=Math.atan2(2*(a.x*a.w-a.z*a.y),g-d+e-f),this.y=Math.atan2(2*(a.y*a.w-a.x*a.z),g+d-e-f),this.z=Math.asin(c(2*(a.x*a.y+a.z*a.w)))):"XZY"===b&&(this.x=Math.atan2(2*(a.x*a.w+a.y*a.z),g-d+e-f),this.y=Math.atan2(2*(a.x*a.z+a.y*a.w),g+d-e-f),this.z=Math.asin(c(2*(a.z*a.w-a.x*a.y))));return this},getScaleFromMatrix:function(a){var b=this.set(a.elements[0], -a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length(),a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}};THREE.Vector3.__q1=new THREE.Quaternion;THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; -THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; -case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this}, -addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this}, -applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.x< -a.x&&(this.x=a.x);this.yb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z* -this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},equals:function(a){return a.x=== -this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d,a=a.elements,e=a[0];d=a[4];var f=a[8],g=a[1],i=a[5],h=a[9];c=a[2];b=a[6];var k=a[10];if(0.01>Math.abs(d-g)&&0.01>Math.abs(f-c)&&0.01>Math.abs(h-b)){if(0.1> -Math.abs(d+g)&&0.1>Math.abs(f+c)&&0.1>Math.abs(h+b)&&0.1>Math.abs(e+i+k-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;i=(i+1)/2;k=(k+1)/2;d=(d+g)/4;f=(f+c)/4;h=(h+b)/4;e>i&&e>k?0.01>e?(b=0,d=c=0.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):i>k?0.01>i?(b=0.707106781,c=0,d=0.707106781):(c=Math.sqrt(i),b=d/c,d=h/c):0.01>k?(c=b=0.707106781,d=0):(d=Math.sqrt(k),b=f/d,c=h/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-h)*(b-h)+(f-c)*(f-c)+(g-d)*(g-d));0.001>Math.abs(a)&&(a=1);this.x=(b-h)/a;this.y=(f- -c)/a;this.z=(g-d)/a;this.w=Math.acos((e+i+k-1)/2);return this}};THREE.Box2=function(a,b){this.min=void 0!==a?a:new THREE.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector2(-Infinity,-Infinity)}; -THREE.Box2.prototype={constructor:THREE.Box2,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){if(0this.max.x&&(this.max.x=b.x),b.ythis.max.y&&(this.max.y=b.y)}else this.makeEmpty();return this},setFromCenterAndSize:function(a,b){var c=THREE.Box2.__v1.copy(b).multiplyScalar(0.5);this.min.copy(a).sub(c); -this.max.copy(a).add(c);return this},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this.max.y=-Infinity;return this},empty:function(){return this.max.xthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a){return new THREE.Vector2((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/ -(this.max.y-this.min.y))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector2).copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return THREE.Box2.__v1.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a); -this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box2).copy(this)}};THREE.Box2.__v1=new THREE.Vector2;THREE.Box3=function(a,b){this.min=void 0!==a?a:new THREE.Vector3(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector3(-Infinity,-Infinity,-Infinity)}; -THREE.Box3.prototype={constructor:THREE.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){if(0this.max.x&&(this.max.x=b.x),b.ythis.max.y&&(this.max.y=b.y),b.zthis.max.z&&(this.max.z=b.z)}else this.makeEmpty();return this},setFromCenterAndSize:function(a,b){var c=THREE.Box3.__v1.copy(b).multiplyScalar(0.5); -this.min.copy(a).sub(c);this.max.copy(a).add(c);return this},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=this.min.z=Infinity;this.max.x=this.max.y=this.max.z=-Infinity;return this},empty:function(){return this.max.xthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<= -a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a){return new THREE.Vector3((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},clampPoint:function(a,b){b||new THREE.Vector3;return(new THREE.Vector3).copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return THREE.Box3.__v1.copy(a).clamp(this.min, -this.max).sub(a).length()},getBoundingSphere:function(a){a=a||new THREE.Sphere;a.center=this.center();a.radius=0.5*this.size(THREE.Box3.__v0).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},transform:function(a){a=[THREE.Box3.__v0.set(this.min.x,this.min.y,this.min.z).applyMatrix4(a),THREE.Box3.__v0.set(this.min.x,this.min.y,this.min.z).applyMatrix4(a),THREE.Box3.__v1.set(this.min.x, -this.min.y,this.max.z).applyMatrix4(a),THREE.Box3.__v2.set(this.min.x,this.max.y,this.min.z).applyMatrix4(a),THREE.Box3.__v3.set(this.min.x,this.max.y,this.max.z).applyMatrix4(a),THREE.Box3.__v4.set(this.max.x,this.min.y,this.min.z).applyMatrix4(a),THREE.Box3.__v5.set(this.max.x,this.min.y,this.max.z).applyMatrix4(a),THREE.Box3.__v6.set(this.max.x,this.max.y,this.min.z).applyMatrix4(a),THREE.Box3.__v7.set(this.max.x,this.max.y,this.max.z).applyMatrix4(a)];this.makeEmpty();this.setFromPoints(a);return this}, -translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Box3.__v0=new THREE.Vector3;THREE.Box3.__v1=new THREE.Vector3;THREE.Box3.__v2=new THREE.Vector3;THREE.Box3.__v3=new THREE.Vector3;THREE.Box3.__v4=new THREE.Vector3;THREE.Box3.__v5=new THREE.Vector3;THREE.Box3.__v6=new THREE.Vector3;THREE.Box3.__v7=new THREE.Vector3;THREE.Matrix3=function(a,b,c,d,e,f,g,i,h){this.elements=new Float32Array(9);this.set(void 0!==a?a:1,b||0,c||0,d||0,void 0!==e?e:1,f||0,g||0,i||0,void 0!==h?h:1)}; -THREE.Matrix3.prototype={constructor:THREE.Matrix3,set:function(a,b,c,d,e,f,g,i,h){var k=this.elements;k[0]=a;k[3]=b;k[6]=c;k[1]=d;k[4]=e;k[7]=f;k[2]=g;k[5]=i;k[8]=h;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},copy:function(a){a=a.elements;this.set(a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]);return this},multiplyVector3:function(a){console.warn("DEPRECATED: Matrix3's .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)}, -multiplyVector3Array:function(a){for(var b=THREE.Matrix3.__v1,c=0,d=a.length;c<=a.radius},isIntersectionPlane:function(a){return 0!=a.normal.dot(this.direction)||0==a.distanceToPoint(this.origin)?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction); -if(0==b){if(0==a.distanceToPoint(this.origin))return 0}else return-(this.origin.dot(a.normal)+a.constant)/b},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return void 0===c?void 0:this.at(c,b)},transform:function(a){this.direction.add(this.origin).applyMatrix4(a);this.origin.applyMatrix4(a);this.direction.sub(this.origin);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)},clone:function(){return(new THREE.Ray).copy(this)}}; -THREE.Ray.__v1=new THREE.Vector3;THREE.Ray.__v2=new THREE.Vector3;THREE.Sphere=function(a,b){this.center=void 0!==a?a:new THREE.Vector3;this.radius=void 0!==b?b:0}; -THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromCenterAndPoints:function(a,b){for(var c=0,d=0,e=b.length;d=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)- -this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},transform:function(a){this.center.applyMatrix4(a); -this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}};THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements,a=c[0],d=c[1],e=c[2],f=c[3],g=c[4],i=c[5],h=c[6],k=c[7],l=c[8],m=c[9],n=c[10],r=c[11],p=c[12],q=c[13],s=c[14],c=c[15];b[0].setComponents(f-a,k-g,r-l,c-p).normalize();b[1].setComponents(f+a,k+g,r+l, -c+p).normalize();b[2].setComponents(f+d,k+i,r+m,c+q).normalize();b[3].setComponents(f-d,k-i,r-m,c-q).normalize();b[4].setComponents(f-e,k-h,r-n,c-s).normalize();b[5].setComponents(f+e,k+h,r+n,c+s).normalize();return this},intersectsObject:function(a){for(var b=a.matrixWorld,c=this.planes,d=b.getPosition(),a=-a.geometry.boundingSphere.radius*b.getMaxScaleOnAxis(),b=0;6>b;b++)if(c[b].distanceToPoint(d)d;d++)if(b[d].distanceToPoint(c)c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; -THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(a,b,c){b=THREE.Plane.__v1.subVectors(c,b).cross(THREE.Plane.__v2.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},copy:function(a){this.normal.copy(a.normal); +// threejs.org/license +(function(l,sa){"object"===typeof exports&&"undefined"!==typeof module?sa(exports):"function"===typeof define&&define.amd?define(["exports"],sa):sa(l.THREE=l.THREE||{})})(this,function(l){function sa(){}function B(a,b){this.x=a||0;this.y=b||0}function da(a,b,c,d,e,f,g,h,k,m){Object.defineProperty(this,"id",{value:ee++});this.uuid=T.generateUUID();this.sourceFile=this.name="";this.image=void 0!==a?a:da.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:da.DEFAULT_MAPPING;this.wrapS=void 0!==c? +c:1001;this.wrapT=void 0!==d?d:1001;this.magFilter=void 0!==e?e:1006;this.minFilter=void 0!==f?f:1008;this.anisotropy=void 0!==k?k:1;this.format=void 0!==g?g:1023;this.type=void 0!==h?h:1009;this.offset=new B(0,0);this.repeat=new B(1,1);this.generateMipmaps=!0;this.premultiplyAlpha=!1;this.flipY=!0;this.unpackAlignment=4;this.encoding=void 0!==m?m:3E3;this.version=0;this.onUpdate=null}function ga(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}function Db(a,b,c){this.uuid=T.generateUUID(); +this.width=a;this.height=b;this.scissor=new ga(0,0,a,b);this.scissorTest=!1;this.viewport=new ga(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=1006);this.texture=new da(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy,c.encoding);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.depthTexture=void 0!==c.depthTexture?c.depthTexture:null}function Eb(a,b,c){Db.call(this,a,b,c);this.activeMipMapLevel= +this.activeCubeFace=0}function ba(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function q(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function J(){this.elements=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);0= +d||0< alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); +y.compileShader(P);y.compileShader(R);y.attachShader(N,P);y.attachShader(N,R);y.linkProgram(N);M=N;u=y.getAttribLocation(M,"position");v=y.getAttribLocation(M,"uv");c=y.getUniformLocation(M,"uvOffset");d=y.getUniformLocation(M,"uvScale");e=y.getUniformLocation(M,"rotation");f=y.getUniformLocation(M,"scale");g=y.getUniformLocation(M,"color");h=y.getUniformLocation(M,"map");k=y.getUniformLocation(M,"opacity");m=y.getUniformLocation(M,"modelViewMatrix");w=y.getUniformLocation(M,"projectionMatrix");n= +y.getUniformLocation(M,"fogType");p=y.getUniformLocation(M,"fogDensity");r=y.getUniformLocation(M,"fogNear");x=y.getUniformLocation(M,"fogFar");l=y.getUniformLocation(M,"fogColor");D=y.getUniformLocation(M,"alphaTest");N=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");N.width=8;N.height=8;P=N.getContext("2d");P.fillStyle="white";P.fillRect(0,0,8,8);ca=new da(N);ca.needsUpdate=!0}y.useProgram(M);E.initAttributes();E.enableAttribute(u);E.enableAttribute(v);E.disableUnusedAttributes(); +E.disable(y.CULL_FACE);E.enable(y.BLEND);y.bindBuffer(y.ARRAY_BUFFER,H);y.vertexAttribPointer(u,2,y.FLOAT,!1,16,0);y.vertexAttribPointer(v,2,y.FLOAT,!1,16,8);y.bindBuffer(y.ELEMENT_ARRAY_BUFFER,F);y.uniformMatrix4fv(w,!1,Ka.projectionMatrix.elements);E.activeTexture(y.TEXTURE0);y.uniform1i(h,0);P=N=0;(R=q.fog)?(y.uniform3f(l,R.color.r,R.color.g,R.color.b),R&&R.isFog?(y.uniform1f(r,R.near),y.uniform1f(x,R.far),y.uniform1i(n,1),P=N=1):R&&R.isFogExp2&&(y.uniform1f(p,R.density),y.uniform1i(n,2),P=N=2)): +(y.uniform1i(n,0),P=N=0);for(var R=0,S=b.length;R<([\w\d.]+)>/g,function(a,c){var d=X[c];if(void 0===d)throw Error("Can not resolve #include <"+c+">");return Cd(d)})}function ve(a){return a.replace(/for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cb||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a} +function k(a){return T.isPowerOfTwo(a.width)&&T.isPowerOfTwo(a.height)}function m(b){return 1003===b||1004===b||1005===b?a.NEAREST:a.LINEAR}function w(b){b=b.target;b.removeEventListener("dispose",w);a:{var c=d.get(b);if(b.image&&c.__image__webglTextureCube)a.deleteTexture(c.__image__webglTextureCube);else{if(void 0===c.__webglInit)break a;a.deleteTexture(c.__webglTexture)}d["delete"](b)}q.textures--}function n(b){b=b.target;b.removeEventListener("dispose",n);var c=d.get(b),e=d.get(b.texture);if(b){void 0!== +e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b&&b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d["delete"](b.texture);d["delete"](b)}q.textures--}function p(b,g){var m=d.get(b);if(0x;x++)l[x]=p||n?n?b.image[x].image:b.image[x]:h(b.image[x],e.maxCubemapSize);var t=k(l[0]),u=f(b.format),ja=f(b.type);r(a.TEXTURE_CUBE_MAP, +b,t);for(x=0;6>x;x++)if(p)for(var B,C=l[x].mipmaps,z=0,N=C.length;zm;m++)e.__webglFramebuffer[m]=a.createFramebuffer()}else e.__webglFramebuffer=a.createFramebuffer();if(g){c.bindTexture(a.TEXTURE_CUBE_MAP,f.__webglTexture);r(a.TEXTURE_CUBE_MAP,b.texture,h);for(m=0;6>m;m++)l(e.__webglFramebuffer[m],b,a.COLOR_ATTACHMENT0,a.TEXTURE_CUBE_MAP_POSITIVE_X+m);b.texture.generateMipmaps&&h&&a.generateMipmap(a.TEXTURE_CUBE_MAP);c.bindTexture(a.TEXTURE_CUBE_MAP, +null)}else c.bindTexture(a.TEXTURE_2D,f.__webglTexture),r(a.TEXTURE_2D,b.texture,h),l(e.__webglFramebuffer,b,a.COLOR_ATTACHMENT0,a.TEXTURE_2D),b.texture.generateMipmaps&&h&&a.generateMipmap(a.TEXTURE_2D),c.bindTexture(a.TEXTURE_2D,null);if(b.depthBuffer){e=d.get(b);f=b&&b.isWebGLRenderTargetCube;if(b.depthTexture){if(f)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported!");a.bindFramebuffer(a.FRAMEBUFFER, +e.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);p(b.depthTexture,0);e=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER, +a.DEPTH_ATTACHMENT,a.TEXTURE_2D,e,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.TEXTURE_2D,e,0);else throw Error("Unknown depthTexture format");}else if(f)for(e.__webglDepthbuffer=[],f=0;6>f;f++)a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer[f]),e.__webglDepthbuffer[f]=a.createRenderbuffer(),t(e.__webglDepthbuffer[f],b);else a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer),e.__webglDepthbuffer=a.createRenderbuffer(),t(e.__webglDepthbuffer, +b);a.bindFramebuffer(a.FRAMEBUFFER,null)}};this.updateRenderTargetMipmap=function(b){var e=b.texture;e.generateMipmaps&&k(b)&&1003!==e.minFilter&&1006!==e.minFilter&&(b=b&&b.isWebGLRenderTargetCube?a.TEXTURE_CUBE_MAP:a.TEXTURE_2D,e=d.get(e).__webglTexture,c.bindTexture(b,e),a.generateMipmap(b),c.bindTexture(b,null))}}function xf(){var a={};return{get:function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c},"delete":function(b){delete a[b.uuid]},clear:function(){a={}}}}function yf(a,b,c){function d(b, +c,d){var e=new Uint8Array(4),f=a.createTexture();a.bindTexture(b,f);a.texParameteri(b,a.TEXTURE_MIN_FILTER,a.NEAREST);a.texParameteri(b,a.TEXTURE_MAG_FILTER,a.NEAREST);for(b=0;b=ia.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ia.maxTextures);da+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTarget&&(a||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."), +a=!0),b=b.texture);ua.setTexture2D(b,c)}}();this.setTexture=function(){var a=!1;return function(b,c){a||(console.warn("THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead."),a=!0);ua.setTexture2D(b,c)}}();this.setTextureCube=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTargetCube&&(a||(console.warn("THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);b&&b.isCubeTexture||Array.isArray(b.image)&& +6===b.image.length?ua.setTextureCube(b,c):ua.setTextureCubeDynamic(b,c)}}();this.getCurrentRenderTarget=function(){return V};this.setRenderTarget=function(a){(V=a)&&void 0===ea.get(a).__webglFramebuffer&&ua.setupRenderTarget(a);var b=a&&a.isWebGLRenderTargetCube,c;a?(c=ea.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,X.copy(a.scissor),fb=a.scissorTest,$a.copy(a.viewport)):(c=null,X.copy(ha).multiplyScalar(Qa),fb=la,$a.copy(fa).multiplyScalar(Qa));T!==c&&(A.bindFramebuffer(A.FRAMEBUFFER, +c),T=c);Y.scissor(X);Y.setScissorTest(fb);Y.viewport($a);b&&(b=ea.get(a.texture),A.framebufferTexture2D(A.FRAMEBUFFER,A.COLOR_ATTACHMENT0,A.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,a.activeMipMapLevel))};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!1===(a&&a.isWebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else{var g=ea.get(a).__webglFramebuffer;if(g){var h=!1;g!==T&&(A.bindFramebuffer(A.FRAMEBUFFER, +g),h=!0);try{var k=a.texture,m=k.format,n=k.type;1023!==m&&u(m)!==A.getParameter(A.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):1009===n||u(n)===A.getParameter(A.IMPLEMENTATION_COLOR_READ_TYPE)||1015===n&&(ka.get("OES_texture_float")||ka.get("WEBGL_color_buffer_float"))||1016===n&&ka.get("EXT_color_buffer_half_float")?A.checkFramebufferStatus(A.FRAMEBUFFER)===A.FRAMEBUFFER_COMPLETE?0<=b&& +b<=a.width-d&&0<=c&&c<=a.height-e&&A.readPixels(b,c,d,e,u(m),u(n),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&A.bindFramebuffer(A.FRAMEBUFFER,T)}}}}}function Ib(a,b){this.name="";this.color=new O(a);this.density=void 0!==b?b:2.5E-4}function Jb(a,b,c){this.name="";this.color= +new O(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3}function jb(){z.call(this);this.type="Scene";this.overrideMaterial=this.fog=this.background=null;this.autoUpdate=!0}function Ed(a,b,c,d,e){z.call(this);this.lensFlares=[];this.positionScreen=new q;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)}function kb(a){U.call(this);this.type="SpriteMaterial";this.color=new O(16777215);this.map=null;this.rotation=0;this.lights=this.fog=!1;this.setValues(a)}function qc(a){z.call(this); +this.type="Sprite";this.material=void 0!==a?a:new kb}function rc(){z.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function lb(a,b,c,d,e,f,g,h,k,m,w,n){da.call(this,null,f,g,h,k,m,d,e,w,n);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function bd(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new J;a=a||[];this.bones=a.slice(0); +this.useVertexTexture?(a=Math.sqrt(4*this.bones.length),a=T.nextPowerOfTwo(Math.ceil(a)),this.boneTextureHeight=this.boneTextureWidth=a=Math.max(a,4),this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4),this.boneTexture=new lb(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,1023,1015)):this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton bonInverses is the wrong length."), +this.boneInverses=[],b=0,a=this.bones.length;b=a.HAVE_CURRENT_DATA&&(w.needsUpdate=!0)}da.call(this,a,b,c,d,e,f,g,h,k);this.generateMipmaps=!1;var w=this;m()}function Lb(a,b,c,d,e,f,g,h,k,m,w,n){da.call(this,null,f,g,h,k,m,d,e,w,n);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function fd(a,b,c,d,e,f,g,h,k){da.call(this,a,b,c,d,e,f,g,h,k);this.needsUpdate=!0}function tc(a,b,c,d,e,f,g, +h,k,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");da.call(this,null,d,e,f,g,h,m,c,k);this.image={width:a,height:b};this.type=void 0!==c?c:1012;this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Mb(a){function b(a,b){return a-b}G.call(this);var c=[0,0],d={},e=["a","b","c"];if(a&&a.isGeometry){var f=a.vertices,g=a.faces,h=0,k=new Uint32Array(6*g.length); +a=0;for(var m=g.length;an;n++){c[0]=w[e[n]];c[1]=w[e[(n+1)%3]];c.sort(b);var p=c.toString();void 0===d[p]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[p]=!0,h++)}c=new Float32Array(6*h);a=0;for(m=h;an;n++)d=f[k[2*a+n]],h=6*a+3*n,c[h+0]=d.x,c[h+1]=d.y,c[h+2]=d.z;this.addAttribute("position",new C(c,3))}else if(a&&a.isBufferGeometry){if(null!==a.index){m=a.index.array;f=a.attributes.position;e=a.groups;h=0;0===e.length&&a.addGroup(0,m.length);k=new Uint32Array(2*m.length); +g=0;for(w=e.length;gn;n++)c[0]=m[a+n],c[1]=m[a+(n+1)%3],c.sort(b),p=c.toString(),void 0===d[p]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[p]=!0,h++)}c=new Float32Array(6*h);a=0;for(m=h;an;n++)h=6*a+3*n,d=k[2*a+n],c[h+0]=f.getX(d),c[h+1]=f.getY(d),c[h+2]=f.getZ(d)}else for(f=a.attributes.position.array,h=f.length/3,k=h/3,c=new Float32Array(6*h),a=0,m=k;an;n++)h=18*a+6*n,k=9*a+3*n,c[h+0]=f[k],c[h+1]=f[k+1], +c[h+2]=f[k+2],d=9*a+(n+1)%3*3,c[h+3]=f[d],c[h+4]=f[d+1],c[h+5]=f[d+2];this.addAttribute("position",new C(c,3))}}function Nb(a,b,c){G.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f,g,h,k,m,w=b+1;for(f=0;f<=c;f++)for(m=f/c,g=0;g<=b;g++)k=g/b,h=a(k,m),d.push(h.x,h.y,h.z),e.push(k,m);a=[];var n;for(f=0;fd&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}G.call(this);this.type="PolyhedronBufferGeometry";this.parameters= +{vertices:a,indices:b,radius:c,detail:d};c=c||1;var h=[],k=[];(function(a){for(var c=new q,d=new q,g=new q,h=0;he&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",ha(h,3));this.addAttribute("normal",ha(h.slice(),3));this.addAttribute("uv",ha(k,2));this.normalizeNormals();this.boundingSphere=new Ca(new q, +c)}function Ob(a,b){ua.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function vc(a,b){Q.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Ob(a,b));this.mergeVertices()}function Pb(a,b){ua.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters= +{radius:a,detail:b}}function wc(a,b){Q.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pb(a,b));this.mergeVertices()}function Qb(a,b){var c=(1+Math.sqrt(5))/2;ua.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters= +{radius:a,detail:b}}function xc(a,b){Q.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qb(a,b));this.mergeVertices()}function Rb(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;ua.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2, +6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function yc(a,b){Q.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Rb(a,b));this.mergeVertices()}function zc(a,b,c,d){Q.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d}; +this.fromBufferGeometry(new ua(a,b,c,d));this.mergeVertices()}function Sb(a,b,c,d,e){function f(e){var f=a.getPointAt(e/b),m=g.normals[e];e=g.binormals[e];for(n=0;n<=d;n++){var w=n/d*Math.PI*2,l=Math.sin(w),w=-Math.cos(w);k.x=w*m.x+l*e.x;k.y=w*m.y+l*e.y;k.z=w*m.z+l*e.z;k.normalize();r.push(k.x,k.y,k.z);h.x=f.x+c*k.x;h.y=f.y+c*k.y;h.z=f.z+c*k.z;p.push(h.x,h.y,h.z)}}G.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c|| +1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new q,k=new q,m=new B,w,n,p=[],r=[],l=[],t=[];for(w=0;w<=b;w++)for(n=0;n<=d;n++)m.x=w/b,m.y=n/d,l.push(m.x,m.y);(function(){for(n=1;n<=b;n++)for(w=1;w<=d;w++){var a=(d+1)*n+(w-1),c=(d+1)*n+w,e=(d+1)*(n-1)+w;t.push((d+1)*(n-1)+(w-1),a,e);t.push(a,c,e)}})();this.setIndex((65535p;p++){e[0]=n[g[p]];e[1]=n[g[(p+1)%3]];e.sort(c);var l=e.toString();void 0===f[l]?f[l]={vert1:e[0],vert2:e[1],face1:m,face2:void 0}:f[l].face2=m}e=[];for(l in f)if(g=f[l],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=d)m=k[g.vert1],e.push(m.x),e.push(m.y),e.push(m.z),m=k[g.vert2],e.push(m.x),e.push(m.y),e.push(m.z);this.addAttribute("position",new C(new Float32Array(e),3))}function Ua(a, +b,c,d,e,f,g,h){function k(c){var e,f,k,n=new B,p=new q,l=0,w=!0===c?a:b,I=!0===c?1:-1;f=u;for(e=1;e<=d;e++)x.setXYZ(u,0,y*I,0),t.setXYZ(u,0,I,0),n.x=.5,n.y=.5,D.setXY(u,n.x,n.y),u++;k=u;for(e=0;e<=d;e++){var z=e/d*h+g,C=Math.cos(z),z=Math.sin(z);p.x=w*z;p.y=y*I;p.z=w*C;x.setXYZ(u,p.x,p.y,p.z);t.setXYZ(u,0,I,0);n.x=.5*C+.5;n.y=.5*z*I+.5;D.setXY(u,n.x,n.y);u++}for(e=0;ethis.duration&&this.resetDuration();this.optimize()}function ud(a){this.manager=void 0!==a?a:Ga;this.textures={}}function Id(a){this.manager=void 0!==a?a:Ga}function wb(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}}function Jd(a){"boolean"=== +typeof a&&(console.warn("THREE.JSONLoader: showStatus parameter has been removed from constructor."),a=void 0);this.manager=void 0!==a?a:Ga;this.withCredentials=!1}function xe(a){this.manager=void 0!==a?a:Ga;this.texturePath=""}function ia(){}function Sa(a,b){this.v1=a;this.v2=b}function Oc(){this.curves=[];this.autoClose=!1}function Va(a,b,c,d,e,f,g,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g;this.aRotation=h||0}function xb(a){this.points= +void 0===a?[]:a}function yb(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d}function zb(a,b,c){this.v0=a;this.v1=b;this.v2=c}function Ab(){Pc.apply(this,arguments);this.holes=[]}function Pc(a){Oc.call(this);this.currentPoint=new B;a&&this.fromPoints(a)}function Kd(){this.subPaths=[];this.currentPath=null}function Ld(a){this.data=a}function ye(a){this.manager=void 0!==a?a:Ga}function Md(){void 0===Nd&&(Nd=new (window.AudioContext||window.webkitAudioContext));return Nd}function Od(a){this.manager= +void 0!==a?a:Ga}function ze(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new Ea;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new Ea;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function vd(a,b,c){z.call(this);this.type="CubeCamera";var d=new Ea(90,1,a,b);d.up.set(0,-1,0);d.lookAt(new q(1,0,0));this.add(d);var e=new Ea(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new q(-1,0,0));this.add(e);var f=new Ea(90,1,a,b);f.up.set(0,0,1);f.lookAt(new q(0, +1,0));this.add(f);var g=new Ea(90,1,a,b);g.up.set(0,0,-1);g.lookAt(new q(0,-1,0));this.add(g);var h=new Ea(90,1,a,b);h.up.set(0,-1,0);h.lookAt(new q(0,0,1));this.add(h);var k=new Ea(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new q(0,0,-1));this.add(k);this.renderTarget=new Eb(c,c,{format:1022,magFilter:1006,minFilter:1006});this.updateCubeMap=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=this.renderTarget,p=c.texture.generateMipmaps;c.texture.generateMipmaps=!1;c.activeCubeFace=0;a.render(b, +d,c);c.activeCubeFace=1;a.render(b,e,c);c.activeCubeFace=2;a.render(b,f,c);c.activeCubeFace=3;a.render(b,g,c);c.activeCubeFace=4;a.render(b,h,c);c.texture.generateMipmaps=p;c.activeCubeFace=5;a.render(b,k,c);a.setRenderTarget(null)}}function Pd(){z.call(this);this.type="AudioListener";this.context=Md();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null}function dc(a){z.call(this);this.type="Audio";this.context=a.context;this.source=this.context.createBufferSource(); +this.source.onended=this.onEnded.bind(this);this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function Qd(a){dc.call(this,a);this.panner=this.context.createPanner();this.panner.connect(this.gain)}function Rd(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount); +a.getOutput().connect(this.analyser)}function wd(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function fa(a,b,c){this.path=b;this.parsedPath=c||fa.parseTrackName(b);this.node=fa.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Sd(a){this.uuid=T.generateUUID(); +this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var b={};this._indicesByUUID=b;for(var c=0,d=arguments.length;c!==d;++c)b[arguments[c].uuid]=c;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var e=this;this.stats={objects:{get total(){return e._objects.length},get inUse(){return this.total-e.nCachedObjects_}},get bindingsPerObject(){return e._bindings.length}}}function Td(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks; +b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled= +!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Ud(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function Ae(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Bb(){G.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function Vd(a,b,c,d){this.uuid=T.generateUUID();this.data=a;this.itemSize=b;this.offset=c;this.normalized=!0=== +d}function ec(a,b){this.uuid=T.generateUUID();this.array=a;this.stride=b;this.count=void 0!==a?a.length/b:0;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function fc(a,b,c){ec.call(this,a,b);this.meshPerAttribute=c||1}function gc(a,b,c){C.call(this,a,b);this.meshPerAttribute=c||1}function Wd(a,b,c,d){this.ray=new ab(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points."); +return this.Points}}})}function Be(a,b){return a.distance-b.distance}function Xd(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new ha(b,3));b=new oa({fog:!1});this.cone=new la(a,b);this.add(this.cone);this.update()}function ic(a){this.bones=this.getBoneList(a);for(var b=new Q, +c=0;cd;d++)c.faces[d].color=this.colors[4>d?0:1];d=new Ma({vertexColors:1,wireframe:!0});this.lightSphere=new ya(c,d);this.add(this.lightSphere);this.update()}function Sc(a,b,c,d){b=b||1;c=new O(void 0!==c?c:4473924);d=new O(void 0!== +d?d:8947848);for(var e=b/2,f=2*a/b,g=[],h=[],k=0,m=0,l=-a;k<=b;k++,l+=f){g.push(-a,0,l,a,0,l);g.push(l,0,-a,l,0,a);var n=k===e?c:d;n.toArray(h,m);m+=3;n.toArray(h,m);m+=3;n.toArray(h,m);m+=3;n.toArray(h,m);m+=3}a=new G;a.addAttribute("position",new ha(g,3));a.addAttribute("color",new ha(h,3));g=new oa({vertexColors:2});la.call(this,a,g)}function Tc(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=c.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead."); +c=new G;b=new ha(6*b,3);c.addAttribute("position",b);la.call(this,c,new oa({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function lc(a,b){z.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;void 0===b&&(b=1);var c=new G;c.addAttribute("position",new ha([-b,b,0,b,b,0,b,-b,0,-b,-b,0,-b,b,0],3));var d=new oa({fog:!1});this.add(new Ta(c,d));c=new G;c.addAttribute("position",new ha([0,0,0,0,0,1],3));this.add(new Ta(c,d));this.update()} +function Uc(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new q);d.colors.push(new O(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}var d=new Q,e=new oa({color:16777215,vertexColors:1}),f={};b("n1","n2",16755200);b("n2","n4",16755200);b("n4","n3",16755200);b("n3","n1",16755200);b("f1","f2",16755200);b("f2","f4",16755200);b("f4","f3",16755200);b("f3","f1",16755200);b("n1","f1",16755200);b("n2","f2",16755200);b("n3","f3",16755200);b("n4","f4",16755200);b("p","n1",16711680); +b("p","n2",16711680);b("p","n3",16711680);b("p","n4",16711680);b("u1","u2",43775);b("u2","u3",43775);b("u3","u1",43775);b("c","t",16777215);b("p","c",3355443);b("cn1","cn2",3355443);b("cn3","cn4",3355443);b("cf1","cf2",3355443);b("cf3","cf4",3355443);la.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()}function Vc(a,b){var c=void 0!==b?b:8947848;this.object=a;this.box= +new Ba;ya.call(this,new ob(1,1,1),new Ma({color:c,wireframe:!0}))}function Wc(a,b){void 0===b&&(b=16776960);var c=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),d=new Float32Array(24),e=new G;e.setIndex(new C(c,1));e.addAttribute("position",new C(d,3));la.call(this,e,new oa({color:b}));void 0!==a&&this.update(a)}function Cb(a,b,c,d,e,f){z.call(this);void 0===d&&(d=16776960);void 0===c&&(c=1);void 0===e&&(e=.2*c);void 0===f&&(f=.2*e);this.position.copy(b);this.line=new Ta(Ce,new oa({color:d})); +this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new ya(De,new Ma({color:d}));this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(a);this.setLength(c,e,f)}function xd(a){a=a||1;var b=new Float32Array([0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a]),c=new Float32Array([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1]);a=new G;a.addAttribute("position",new C(b,3));a.addAttribute("color",new C(c,3));b=new oa({vertexColors:2});la.call(this,a,b)}function Ee(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3."); +$d.call(this,a);this.type="catmullrom";this.closed=!0}function yd(a,b,c,d,e,f){Va.call(this,a,b,c,c,d,e,f)}void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a, +b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){console.warn("THREE.Math.random16() has been deprecated. Use Math.random() instead.");return Math.random()},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(a){return a* +T.DEG2RAD},radToDeg:function(a){return a*T.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}};B.prototype={constructor:B,isVector2:!0,get width(){return this.x},set width(a){this.x=a},get height(){return this.y},set height(a){this.y=a},set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x= +a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!== +b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a):this.y=this.x=0;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y, +a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new B,b=new B);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y= +Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x* +this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},distanceToManhattan:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.multiplyScalar(a/ +this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+ +1];return this},rotateAround:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=this.x-a.x,f=this.y-a.y;this.x=e*c-f*d+a.x;this.y=e*d+f*c+a.y;return this}};da.DEFAULT_IMAGE=void 0;da.DEFAULT_MAPPING=300;da.prototype={constructor:da,isTexture:!0,set needsUpdate(a){!0===a&&this.version++},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.image=a.image;this.mipmaps=a.mipmaps.slice(0);this.mapping=a.mapping;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=a.magFilter;this.minFilter= +a.minFilter;this.anisotropy=a.anisotropy;this.format=a.format;this.type=a.type;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.generateMipmaps=a.generateMipmaps;this.premultiplyAlpha=a.premultiplyAlpha;this.flipY=a.flipY;this.unpackAlignment=a.unpackAlignment;this.encoding=a.encoding;return this},toJSON:function(a){if(void 0!==a.textures[this.uuid])return a.textures[this.uuid];var b={metadata:{version:4.4,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,mapping:this.mapping, +repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],wrap:[this.wrapS,this.wrapT],minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY};if(void 0!==this.image){var c=this.image;void 0===c.uuid&&(c.uuid=T.generateUUID());if(void 0===a.images[c.uuid]){var d=a.images,e=c.uuid,f=c.uuid,g;void 0!==c.toDataURL?g=c:(g=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"),g.width=c.width,g.height=c.height,g.getContext("2d").drawImage(c, +0,0,c.width,c.height));g=2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0> +a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}};Object.assign(da.prototype,sa.prototype);var ee=0;ga.prototype={constructor:ga,isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a; +return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x, +this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this}, +addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){isFinite(a)? +(this.x*=a,this.y*=a,this.z*=a,this.w*=a):this.w=this.z=this.y=this.x=0;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y= +0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var m=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+m-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;m=(m+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>m?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b): +h>m?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=k/c):.01>m?(c=b=.707106781,d=0):(d=Math.sqrt(m),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x); +this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new ga,b=new ga);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y); +this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z); +this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)}, +normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w= +a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this}};Object.assign(Db.prototype,sa.prototype,{isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0, +0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Eb.prototype=Object.create(Db.prototype);Eb.prototype.constructor=Eb;Eb.prototype.isWebGLRenderTargetCube=!0;ba.prototype={constructor:ba,get x(){return this._x}, +set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get w(){return this._w},set w(a){this._w=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this.onChangeCallback(); +return this},setFromEuler:function(a,b){if(!1===(a&&a.isEuler))throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=Math.cos(a._x/2),d=Math.cos(a._y/2),e=Math.cos(a._z/2),f=Math.sin(a._x/2),g=Math.sin(a._y/2),h=Math.sin(a._z/2),k=a.order;"XYZ"===k?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"YXZ"===k?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"ZXY"===k?(this._x= +f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"ZYX"===k?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"YZX"===k?(this._x=f*d*e+c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e-f*g*h):"XZY"===k&&(this._x=f*d*e-c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e+f*g*h);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a,b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w= +Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+ +h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new q);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;return this.normalize()}}(),inverse:function(){return this.conjugate().normalize()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x* +a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."), +this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,m=b._w;this._x=c*m+f*g+d*k-e*h;this._y=d*m+f*h+e*g-c*k;this._z=e*m+f*k+c*h-d*g;this._w=f*m-c*g-d*h-e*k;this.onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z; +0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.sqrt(1-g*g);if(.001>Math.abs(h))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;var k=Math.atan2(h,g),g=Math.sin((1-b)*k)/h,h=Math.sin(b*k)/h;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x=== +this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};Object.assign(ba,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a, +b,c,d,e,f,g){var h=c[d+0],k=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var l=e[f+1],n=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==l||m!==n){f=1-g;var p=h*d+k*l+m*n+c*e,r=0<=p?1:-1,x=1-p*p;x>Number.EPSILON&&(x=Math.sqrt(x),p=Math.atan2(x,p*r),f=Math.sin(f*p)/x,g=Math.sin(g*p)/x);r*=g;h=h*f+d*r;k=k*f+l*r;m=m*f+n*r;c=c*f+e*r;f===1-g&&(g=1/Math.sqrt(h*h+k*k+m*m+c*c),h*=g,k*=g,m*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=m;a[b+3]=c}});q.prototype={constructor:q,isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this}, +setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x, +this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+= +a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."), +this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===(b&&b.isEuler)&&console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new ba);return this.applyQuaternion(a.setFromEuler(b))}}(), +applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new ba);return this.applyQuaternion(a.setFromAxisAngle(b,c))}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b= +this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-m*-f;this.y=k*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new J); +a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new J);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/= +a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(){var a,b;return function(c, +d){void 0===a&&(a=new q,b=new q);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this}, +roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+ +Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a, +b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new q);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0=== +a&&(a=new q);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(T.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},distanceToManhattan:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){var b=Math.sin(a.phi)*a.radius; +this.x=b*Math.sin(a.theta);this.y=Math.cos(a.phi)*a.radius;this.z=b*Math.cos(a.theta);return this},setFromMatrixPosition:function(a){return this.setFromMatrixColumn(a,3)},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){if("number"===typeof a){console.warn("THREE.Vector3: setFromMatrixColumn now expects ( matrix, index )."); +var c=a;a=b;b=c}return this.fromArray(a.elements,4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this}};J.prototype={constructor:J,isMatrix4:!0, +set:function(a,b,c,d,e,f,g,h,k,m,l,n,p,r,x,t){var q=this.elements;q[0]=a;q[4]=b;q[8]=c;q[12]=d;q[1]=e;q[5]=f;q[9]=g;q[13]=h;q[2]=k;q[6]=m;q[10]=l;q[14]=n;q[3]=p;q[7]=r;q[11]=x;q[15]=t;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new J).fromArray(this.elements)},copy:function(a){this.elements.set(a.elements);return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a, +b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a;return function(b){void 0===a&&(a=new q);var c=this.elements,d=b.elements,e=1/a.setFromMatrixColumn(b,0).length(),f=1/a.setFromMatrixColumn(b,1).length();b=1/a.setFromMatrixColumn(b,2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]* +f;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]*b;return this}}(),makeRotationFromEuler:function(a){!1===(a&&a.isEuler)&&console.error("THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c),c=Math.sin(c),g=Math.cos(d),d=Math.sin(d),h=Math.cos(e),e=Math.sin(e);if("XYZ"===a.order){a=f*h;var k=f*e,m=c*h,l=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+m*d;b[5]=a-l*d;b[9]=-c*g;b[2]=l-a*d;b[6]=m+k*d;b[10]=f*g}else"YXZ"=== +a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a+l*c,b[4]=m*c-k,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=k*c-m,b[6]=l+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a-l*c,b[4]=-f*e,b[8]=m+k*c,b[1]=k+m*c,b[5]=f*h,b[9]=l-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,k=f*e,m=c*h,l=c*e,b[0]=g*h,b[4]=m*d-k,b[8]=a*d+l,b[1]=g*e,b[5]=l*d+a,b[9]=k*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=l-a*e,b[8]=m*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k* +e+m,b[10]=a-l*e):"XZY"===a.order&&(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+l,b[5]=f*h,b[9]=k*e-m,b[2]=m*e-k,b[6]=c*h,b[10]=l*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(a){var b=this.elements,c=a.x,d=a.y,e=a.z,f=a.w,g=c+c,h=d+d,k=e+e;a=c*g;var m=c*h,c=c*k,l=d*h,d=d*k,e=e*k,g=f*g,h=f*h,f=f*k;b[0]=1-(l+e);b[4]=m-f;b[8]=c+h;b[1]=m+f;b[5]=1-(a+e);b[9]=d-g;b[2]=c-h;b[6]=d+g;b[10]=1-(a+l);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]= +0;b[14]=0;b[15]=1;return this},lookAt:function(){var a,b,c;return function(d,e,f){void 0===a&&(a=new q,b=new q,c=new q);var g=this.elements;c.subVectors(d,e).normalize();0===c.lengthSq()&&(c.z=1);a.crossVectors(f,c).normalize();0===a.lengthSq()&&(c.z+=1E-4,a.crossVectors(f,c).normalize());b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."), +this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements,e=this.elements,f=c[0],g=c[4],h=c[8],k=c[12],m=c[1],l=c[5],n=c[9],p=c[13],r=c[2],x=c[6],t=c[10],q=c[14],u=c[3],v=c[7],I=c[11],c=c[15],y=d[0],E=d[4],H=d[8],F=d[12],M=d[1],B=d[5],K=d[9],z=d[13],C=d[2],G=d[6],J=d[10],N=d[14],P=d[3],R=d[7],S=d[11],d=d[15];e[0]=f*y+g*M+h*C+k*P;e[4]=f*E+g*B+h*G+k*R;e[8]=f*H+g*K+h*J+k*S;e[12]= +f*F+g*z+h*N+k*d;e[1]=m*y+l*M+n*C+p*P;e[5]=m*E+l*B+n*G+p*R;e[9]=m*H+l*K+n*J+p*S;e[13]=m*F+l*z+n*N+p*d;e[2]=r*y+x*M+t*C+q*P;e[6]=r*E+x*B+t*G+q*R;e[10]=r*H+x*K+t*J+q*S;e[14]=r*F+x*z+t*N+q*d;e[3]=u*y+v*M+I*C+c*P;e[7]=u*E+v*B+I*G+c*R;e[11]=u*H+v*K+I*J+c*S;e[15]=u*F+v*z+I*N+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12]; +c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToVector3Array:function(){var a;return function(b,c,d){void 0===a&&(a=new q);void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;ethis.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,m=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c); +g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(T.DEG2RAD*a*.5);var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*k;g[9]=0;g[13]=-((c+d)*k);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b= +this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}};Xa.prototype=Object.create(da.prototype); +Xa.prototype.constructor=Xa;Xa.prototype.isCubeTexture=!0;Object.defineProperty(Xa.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});var ie=new da,je=new Xa,fe=[],he=[];ne.prototype.setValue=function(a,b){for(var c=this.seq,d=0,e=c.length;d!==e;++d){var f=c[d];f.setValue(a,b[f.id])}};var zd=/([\w\d_]+)(\])?(\[|\.)?/g;Ya.prototype.setValue=function(a,b,c){b=this.map[b];void 0!==b&&b.setValue(a,c,this.renderer)};Ya.prototype.set=function(a,b,c){var d=this.map[c]; +void 0!==d&&d.setValue(a,b[c],this.renderer)};Ya.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};Ya.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};Ya.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var La={merge:function(a){for(var b={},c=0;c< ALPHATEST ) discard;\n#endif\n", +aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif", +begin_vertex:"\nvec3 transformed = vec3( position );\n",beginnormal_vertex:"\nvec3 objectNormal = vec3( normal );\n",bsdfs:"bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\n\treturn any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t\t}\n\t\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n", +bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos );\n\t\tvec3 vSigmaY = dFdy( surf_pos );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n", +clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\n", +cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n", +defaultnormal_vertex:"#ifdef FLIP_SIDED\n\tobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;\n",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n", +emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n",encodings_fragment:" gl_FragColor = linearToOutputTexel( gl_FragColor );\n",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n return value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n float maxComponent = max( max( value.r, value.g ), value.b );\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n M = ceil( M * 255.0 ) / 255.0;\n return vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float D = max( maxRange / maxRGB, 1.0 );\n D = min( floor( D ) / 255.0, 1.0 );\n return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n vec4 vResult;\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n vResult.w = fract(Le);\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n return vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n float Le = value.z * 255.0 + value.w;\n vec3 Xp_Y_XYZp;\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n return vec4( max(vRGB, 0.0), 1.0 );\n}\n", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n", +envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntenstiy;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n",envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n", +fog_fragment:"#ifdef USE_FOG\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", +lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n", +lights_pars:"uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tif ( testLightInRange( lightDistance, pointLight.distance ) ) {\n\t\t\tdirectLight.color = pointLight.color;\n\t\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\t#include \n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\t#include \n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n", +lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n", +lights_template:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t \tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\t\t\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n", +logdepthbuf_fragment:"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n",logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n", +map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n",map_particle_fragment:"#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n", +metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.r;\n#endif\n",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n", +morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n", +normal_flip:"#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n",normal_fragment:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n", +packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n return normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n return 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n return ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n return linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n",project_vertex:"#ifdef USE_SKINNING\n\tvec4 mvPosition = modelViewMatrix * skinned;\n#else\n\tvec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;\n",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.r;\n#endif\n", +roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\treturn (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn 1.0;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n", +skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureWidth;\n\t\tuniform int boneTextureHeight;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureWidth ) );\n\t\t\tfloat y = floor( j / float( boneTextureWidth ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureWidth );\n\t\t\tfloat dy = 1.0 / float( boneTextureHeight );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n", +skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\tskinned = bindMatrixInverse * skinned;\n#endif\n",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n", +specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n",tonemapping_pars_fragment:"#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n return toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n color = max( vec3( 0.0 ), color - 0.004 );\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n", +uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n#endif\n", +uv_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif", +uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\t#ifdef USE_SKINNING\n\t\tvec4 worldPosition = modelMatrix * skinned;\n\t#else\n\t\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n\t#endif\n#endif\n",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n", +cube_vert:"varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n", +depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +distanceRGBA_frag:"uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include \n#include \n#include \nvoid main () {\n\t#include \n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n",distanceRGBA_vert:"varying vec4 vWorldPosition;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition;\n}\n", +equirect_frag:"uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n",equirect_vert:"varying vec3 vWorldPosition;\n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}\n", +linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n}\n",meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight;\n\treflectedLight.directDiffuse = vec3( 0.0 );\n\treflectedLight.directSpecular = vec3( 0.0 );\n\treflectedLight.indirectDiffuse = diffuseColor.rgb;\n\treflectedLight.indirectSpecular = vec3( 0.0 );\n\t#include \n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}\n", +meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nuniform float envMapIntensity;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n}\n", +normal_frag:"uniform float opacity;\nvarying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\n\t#include \n}\n",normal_vert:"varying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\tvNormal = normalize( normalMatrix * normal );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}\n", +shadow_frag:"uniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n",shadow_vert:"#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"};O.prototype={constructor:O, +isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1<1/6?a+6*(c-a)*d:.5>d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b, +c,d){b=T.euclideanModulo(b,1);c=T.clamp(c,0,1);d=T.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r= +Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){var d=parseFloat(c[1])/ +360,e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^\#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){a=a||{h:0,s:0,l:0};var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===e)f=g=0;else{var k=e-f,f=.5>=h?k/(e+f): +k/(2-e-f);switch(e){case b:g=(c-d)/k+(cthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&& +this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a,b){return(b||new B).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){return(b||new B).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new B;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min); +this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}};U.prototype={constructor:U,isMaterial:!0,get needsUpdate(){return this._needsUpdate},set needsUpdate(a){!0===a&&this.update();this._needsUpdate=a},setValues:function(a){if(void 0!==a)for(var b in a){var c=a[b];if(void 0===c)console.warn("THREE.Material: '"+ +b+"' parameter is undefined.");else{var d=this[b];void 0===d?console.warn("THREE."+this.type+": '"+b+"' is not a property of this material."):d&&d.isColor?d.set(c):d&&d.isVector3&&c&&c.isVector3?d.copy(c):this[b]="overdraw"===b?Number(c):c}}},toJSON:function(a){function b(a){var b=[],c;for(c in a){var d=a[c];delete d.metadata;b.push(d)}return b}var c=void 0===a;c&&(a={textures:{},images:{}});var d={metadata:{version:4.4,type:"Material",generator:"Material.toJSON"}};d.uuid=this.uuid;d.type=this.type; +""!==this.name&&(d.name=this.name);this.color&&this.color.isColor&&(d.color=this.color.getHex());void 0!==this.roughness&&(d.roughness=this.roughness);void 0!==this.metalness&&(d.metalness=this.metalness);this.emissive&&this.emissive.isColor&&(d.emissive=this.emissive.getHex());this.specular&&this.specular.isColor&&(d.specular=this.specular.getHex());void 0!==this.shininess&&(d.shininess=this.shininess);this.map&&this.map.isTexture&&(d.map=this.map.toJSON(a).uuid);this.alphaMap&&this.alphaMap.isTexture&& +(d.alphaMap=this.alphaMap.toJSON(a).uuid);this.lightMap&&this.lightMap.isTexture&&(d.lightMap=this.lightMap.toJSON(a).uuid);this.bumpMap&&this.bumpMap.isTexture&&(d.bumpMap=this.bumpMap.toJSON(a).uuid,d.bumpScale=this.bumpScale);this.normalMap&&this.normalMap.isTexture&&(d.normalMap=this.normalMap.toJSON(a).uuid,d.normalScale=this.normalScale.toArray());this.displacementMap&&this.displacementMap.isTexture&&(d.displacementMap=this.displacementMap.toJSON(a).uuid,d.displacementScale=this.displacementScale, +d.displacementBias=this.displacementBias);this.roughnessMap&&this.roughnessMap.isTexture&&(d.roughnessMap=this.roughnessMap.toJSON(a).uuid);this.metalnessMap&&this.metalnessMap.isTexture&&(d.metalnessMap=this.metalnessMap.toJSON(a).uuid);this.emissiveMap&&this.emissiveMap.isTexture&&(d.emissiveMap=this.emissiveMap.toJSON(a).uuid);this.specularMap&&this.specularMap.isTexture&&(d.specularMap=this.specularMap.toJSON(a).uuid);this.envMap&&this.envMap.isTexture&&(d.envMap=this.envMap.toJSON(a).uuid,d.reflectivity= +this.reflectivity);void 0!==this.size&&(d.size=this.size);void 0!==this.sizeAttenuation&&(d.sizeAttenuation=this.sizeAttenuation);1!==this.blending&&(d.blending=this.blending);2!==this.shading&&(d.shading=this.shading);0!==this.side&&(d.side=this.side);0!==this.vertexColors&&(d.vertexColors=this.vertexColors);1>this.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;0e&&(e=m);l>f&&(f=l);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g)},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y|| +a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a,b){return(b||new q).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(){var a;return function(b){void 0===a&&(a=new q);this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){var b,c;0<=a.constant&&c>=a.constant},clampPoint:function(a,b){return(b||new q).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new q;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new q;return function(b){b=b||new Ca;this.getCenter(b.center);b.radius=.5*this.getSize(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max); +this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new q,new q,new q,new q,new q,new q,new q,new q];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x, +this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}};Ca.prototype={constructor:Ca,set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a= +new Ba;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).getCenter(d);for(var e=0,f=0,g=b.length;f=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)- +this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(this.center.dot(a.normal)-a.constant)<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new q;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a= +a||new Ba;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}};Ia.prototype={constructor:Ia,isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1, +0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){a=a.elements;this.set(a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]);return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToVector3Array:function(){var a;return function(b,c,d){void 0===a&&(a=new q);void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;ec;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}};va.prototype={constructor:va,set:function(a,b){this.normal.copy(a); +this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new q,b=new q;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d,c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal); this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a,b){var c=this.distanceToPoint(a);return(b|| -new THREE.Vector3).copy(this.normal).multiplyScalar(c)},isIntersectionLine:function(a,b){var c=this.distanceToPoint(a),d=this.distanceToPoint(b);return 0>c&&0d&&0d||1c?c:a},clampBottom:function(a,b){return aa?-1:0this.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1: -f+2;k=this.points[c[0]];l=this.points[c[1]];m=this.points[c[2]];n=this.points[c[3]];i=g*g;h=g*i;d.x=b(k.x,l.x,m.x,n.x,g,i,h);d.y=b(k.y,l.y,m.y,n.y,g,i,h);d.z=b(k.z,l.z,m.z,n.z,g,i,h);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a<=a.x&&0<=a.y&&1>=a.x+a.y}; -THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){THREE.Triangle.__v0.subVectors(this.c,this.b);THREE.Triangle.__v1.subVectors(this.a,this.b);return 0.5*THREE.Triangle.__v0.cross(THREE.Triangle.__v1).length()},midpoint:function(a){return(a|| -new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}, -clone:function(){return(new THREE.Triangle).copy(this)}};THREE.Triangle.__v0=new THREE.Vector3;THREE.Triangle.__v1=new THREE.Vector3;THREE.Triangle.__v2=new THREE.Vector3;THREE.Triangle.__v3=new THREE.Vector3;THREE.Vertex=function(a){console.warn("THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.");return a};THREE.UV=function(a,b){console.warn("THREE.UV has been DEPRECATED. Use THREE.Vector2 instead.");return new THREE.Vector2(a,b)};THREE.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1};THREE.Clock.prototype.start=function(){this.oldTime=this.startTime=Date.now();this.running=!0};THREE.Clock.prototype.stop=function(){this.getElapsedTime();this.running=!1};THREE.Clock.prototype.getElapsedTime=function(){this.getDelta();return this.elapsedTime}; -THREE.Clock.prototype.getDelta=function(){var a=0;this.autoStart&&!this.running&&this.start();if(this.running){var b=Date.now(),a=0.001*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a};THREE.EventDispatcher=function(){var a={};this.addEventListener=function(b,c){void 0===a[b]&&(a[b]=[]);-1===a[b].indexOf(c)&&a[b].push(c)};this.removeEventListener=function(b,c){var d=a[b].indexOf(c);-1!==d&&a[b].splice(d,1)};this.dispatchEvent=function(b){var c=a[b.type];if(void 0!==c){b.target=this;for(var d=0,e=c.length;dg.scale.x)return h;h.push({distance:i,point:g.position,face:null,object:g})}else if(g instanceof a.Mesh){b.set(g.matrixWorld.getPosition(), -g.geometry.boundingSphere.radius*g.matrixWorld.getMaxScaleOnAxis());if(!i.ray.isIntersectionSphere(b))return h;var n=g.geometry,r=n.vertices,p=g.material instanceof a.MeshFaceMaterial,q=!0===p?g.material.materials:null,s=g.material.side,t,x,z,v=i.precision;g.matrixRotationWorld.extractRotation(g.matrixWorld);f.getInverse(g.matrixWorld);c.copy(i.ray).transform(f);for(var I=0,H=n.faces.length;Iy)){s=s.side;if(s!==a.DoubleSide&&(t=c.direction.dot(d.normal),!(s===a.FrontSide?0>t:0i.far)){e=c.at(y,e);if(D instanceof a.Face3){if(s=r[D.a],t=r[D.b],x=r[D.c],!a.Triangle.containsPoint(e,s,t,x))continue}else if(D instanceof a.Face4){if(s=r[D.a],t=r[D.b],x=r[D.c],z=r[D.d],!a.Triangle.containsPoint(e,s,t,z)&&!a.Triangle.containsPoint(e,t,x,z))continue}else throw Error("face type not supported");h.push({distance:y, -point:i.ray.at(y),face:D,faceIndex:I,object:g})}}}}}},h=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;de&&0>f||0>g&&0>i)return!1;0>e?c=Math.max(c,e/(e-f)):0>f&&(d=Math.min(d,e/(e-f)));0>g?c=Math.max(c,g/(g-i)):0>i&&(d=Math.min(d,g/(g-i)));if(d< -c)return!1;a.lerp(b,c);b.lerp(a,1-d);return!0}var e,f,g=[],i=0,h,k,l=[],m=0,n,r,p=[],q=0,s,t=[],x=0,z,v,I=[],H=0,D,y,F=[],E=0,G={objects:[],sprites:[],lights:[],elements:[]},W=new THREE.Vector3,A=new THREE.Vector4,X=new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1)),B=new THREE.Box3,K=Array(3),L=Array(4),U=new THREE.Matrix4,aa=new THREE.Matrix4,ba,xa=new THREE.Matrix4,J=new THREE.Matrix3,ha=new THREE.Matrix3,ua=new THREE.Vector3,Oa=new THREE.Frustum,M=new THREE.Vector4,fa=new THREE.Vector4; -this.projectVector=function(a,b){b.matrixWorldInverse.getInverse(b.matrixWorld);aa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);return a.applyProjection(aa)};this.unprojectVector=function(a,b){b.projectionMatrixInverse.getInverse(b.projectionMatrix);aa.multiplyMatrices(b.matrixWorld,b.projectionMatrixInverse);return a.applyProjection(aa)};this.pickingRay=function(a,b){a.z=-1;var c=new THREE.Vector3(a.x,a.y,1);this.unprojectVector(a,b);this.unprojectVector(c,b);c.sub(a).normalize();return new THREE.Raycaster(a, -c)};this.projectScene=function(g,i,m,Ja){var ma=!1,wa,Ta,Ra,ia,ra,ga,Z,pa,gb,hb,Ea,yb,Cb;y=v=s=r=0;G.elements.length=0;g.updateMatrixWorld();void 0===i.parent&&i.updateMatrixWorld();U.copy(i.matrixWorldInverse.getInverse(i.matrixWorld));aa.multiplyMatrices(i.projectionMatrix,U);ha.getInverse(U);ha.transpose();Oa.setFromMatrix(aa);f=0;G.objects.length=0;G.sprites.length=0;G.lights.length=0;var Lb=function(b){for(var c=0,d=b.children.length;ch.positionScreen.x||1h.positionScreen.y||1h.positionScreen.z||1(Z.positionScreen.x-ia.positionScreen.x)*(ra.positionScreen.y-ia.positionScreen.y)-(Z.positionScreen.y-ia.positionScreen.y)*(ra.positionScreen.x-ia.positionScreen.x),ga===THREE.DoubleSide||ma===(ga===THREE.FrontSide))r===q?(Ea=new THREE.RenderableFace3,p.push(Ea),q++,r++,n=Ea):n=p[r++],n.v1.copy(ia),n.v2.copy(ra),n.v3.copy(Z); -else continue;else continue;else if(Ta instanceof THREE.Face4)if(ia=l[Ta.a],ra=l[Ta.b],Z=l[Ta.c],Ea=l[Ta.d],L[0]=ia.positionScreen,L[1]=ra.positionScreen,L[2]=Z.positionScreen,L[3]=Ea.positionScreen,!0===ia.visible||!0===ra.visible||!0===Z.visible||!0===Ea.visible||X.isIntersectionBox(B.setFromPoints(L)))if(ma=0>(Ea.positionScreen.x-ia.positionScreen.x)*(ra.positionScreen.y-ia.positionScreen.y)-(Ea.positionScreen.y-ia.positionScreen.y)*(ra.positionScreen.x-ia.positionScreen.x)||0>(ra.positionScreen.x- -Z.positionScreen.x)*(Ea.positionScreen.y-Z.positionScreen.y)-(ra.positionScreen.y-Z.positionScreen.y)*(Ea.positionScreen.x-Z.positionScreen.x),ga===THREE.DoubleSide||ma===(ga===THREE.FrontSide)){if(s===x){var na=new THREE.RenderableFace4;t.push(na);x++;s++;n=na}else n=t[s++];n.v1.copy(ia);n.v2.copy(ra);n.v3.copy(Z);n.v4.copy(Ea)}else continue;else continue;n.normalModel.copy(Ta.normal);!1===ma&&(ga===THREE.BackSide||ga===THREE.DoubleSide)&&n.normalModel.negate();n.normalModel.applyMatrix3(J).normalize(); -n.normalModelView.copy(n.normalModel).applyMatrix3(ha);n.centroidModel.copy(Ta.centroid).applyMatrix4(ba);Z=Ta.vertexNormals;ia=0;for(ra=Z.length;iaA.z&&(y===E?(ma=new THREE.RenderableParticle,F.push(ma),E++,y++,D=ma):D=F[y++],D.object=pa,D.x=A.x/A.w,D.y= -A.y/A.w,D.z=A.z,D.rotation=pa.rotation.z,D.scale.x=pa.scale.x*Math.abs(D.x-(A.x+i.projectionMatrix.elements[0])/(A.w+i.projectionMatrix.elements[12])),D.scale.y=pa.scale.y*Math.abs(D.y-(A.y+i.projectionMatrix.elements[5])/(A.w+i.projectionMatrix.elements[13])),D.material=pa.material,G.elements.push(D)));!0===Ja&&G.elements.sort(c);return G}};THREE.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=void 0!==f?f:0;this.centroid=new THREE.Vector3}; -THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){var a=new THREE.Face3(this.a,this.b,this.c);a.normal.copy(this.normal);a.color.copy(this.color);a.centroid.copy(this.centroid);a.materialIndex=this.materialIndex;var b,c;b=0;for(c=this.vertexNormals.length;be?-1:1,f.vertexTangents[d]=new THREE.Vector4(A.x,A.y,A.z,e)}this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;ch;h++)if(i[h]==i[(h+1)%3]){e.push(f);break}}else if(a instanceof THREE.Face4){a.a=c[a.a];a.b=c[a.b];a.c=c[a.c];a.d=c[a.d];i=[a.a,a.b,a.c,a.d];d=-1;for(h=0;4>h;h++)i[h]==i[(h+1)%4]&&(0<=d&&e.push(f),d=h);if(0<=d){i.splice(d,1);var l=new THREE.Face3(i[0],i[1],i[2],a.normal,a.color,a.materialIndex);i=0;for(h=this.faceVertexUvs.length;i<=f;f--){this.faces.splice(f,1);i=0;for(h=this.faceVertexUvs.length;ib.max.x&&(b.max.x=c),db.max.y&&(b.max.y=d),eb.max.z&&(b.max.z=e)}if(void 0===a||0===a.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere= -new THREE.Sphere);var a=this.attributes.position.array;if(a){for(var b,c=0,d,e,f=0,g=a.length;fc&&(c=b);this.boundingSphere.radius=Math.sqrt(c)}},computeVertexNormals:function(){if(this.attributes.position){var a,b,c,d;a=this.attributes.position.array.length;if(void 0===this.attributes.normal)this.attributes.normal={itemSize:3,array:new Float32Array(a),numItems:a};else{a=0;for(b=this.attributes.normal.array.length;aua?-1:1;i[4*a]=U.x;i[4*a+1]=U.y;i[4*a+2]=U.z;i[4*a+3]=J}if(void 0===this.attributes.index||void 0===this.attributes.position|| -void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var b=this.attributes.index.array,c=this.attributes.position.array,d=this.attributes.normal.array,e=this.attributes.uv.array,f=c.length/3;if(void 0===this.attributes.tangent){var g=4*f;this.attributes.tangent={itemSize:4,array:new Float32Array(g),numItems:g}}for(var i=this.attributes.tangent.array,h=[],k=[],g=0;ga.length?".":a.join("/"))+"/"},initMaterials:function(a,b){for(var c=[],d=0;d<<16)+(255*a[1]<<8)+255*a[2]}var g=this,i="MeshLambertMaterial",h={color:15658734,opacity:1, -map:null,lightMap:null,normalMap:null,bumpMap:null,wireframe:!1};if(a.shading){var k=a.shading.toLowerCase();"phong"===k?i="MeshPhongMaterial":"basic"===k&&(i="MeshBasicMaterial")}void 0!==a.blending&&void 0!==THREE[a.blending]&&(h.blending=THREE[a.blending]);if(void 0!==a.transparent||1>a.opacity)h.transparent=a.transparent;void 0!==a.depthTest&&(h.depthTest=a.depthTest);void 0!==a.depthWrite&&(h.depthWrite=a.depthWrite);void 0!==a.visible&&(h.visible=a.visible);void 0!==a.flipSided&&(h.side=THREE.BackSide); -void 0!==a.doubleSided&&(h.side=THREE.DoubleSide);void 0!==a.wireframe&&(h.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"===a.vertexColors?h.vertexColors=THREE.FaceColors:a.vertexColors&&(h.vertexColors=THREE.VertexColors));a.colorDiffuse?h.color=f(a.colorDiffuse):a.DbgColor&&(h.color=a.DbgColor);a.colorSpecular&&(h.specular=f(a.colorSpecular));a.colorAmbient&&(h.ambient=f(a.colorAmbient));a.transparency&&(h.opacity=a.transparency);a.specularCoef&&(h.shininess=a.specularCoef);a.mapDiffuse&& -b&&e(h,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&e(h,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&e(h,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&e(h,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&e(h,"specularMap",a.mapSpecular,a.mapSpecularRepeat, -a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapBumpScale&&(h.bumpScale=a.mapBumpScale);a.mapNormal?(i=THREE.ShaderLib.normalmap,k=THREE.UniformsUtils.clone(i.uniforms),k.tNormal.value=h.normalMap,a.mapNormalFactor&&k.uNormalScale.value.set(a.mapNormalFactor,a.mapNormalFactor),h.map&&(k.tDiffuse.value=h.map,k.enableDiffuse.value=!0),h.specularMap&&(k.tSpecular.value=h.specularMap,k.enableSpecular.value=!0),h.lightMap&&(k.tAO.value=h.lightMap,k.enableAO.value=!0),k.uDiffuseColor.value.setHex(h.color), -k.uSpecularColor.value.setHex(h.specular),k.uAmbientColor.value.setHex(h.ambient),k.uShininess.value=h.shininess,void 0!==h.opacity&&(k.uOpacity.value=h.opacity),i=new THREE.ShaderMaterial({fragmentShader:i.fragmentShader,vertexShader:i.vertexShader,uniforms:k,lights:!0,fog:!0}),h.transparent&&(i.transparent=!0)):i=new THREE[i](h);void 0!==a.DbgName&&(i.name=a.DbgName);return i}};THREE.ImageLoader=function(){THREE.EventDispatcher.call(this);this.crossOrigin=null};THREE.ImageLoader.prototype={constructor:THREE.ImageLoader,load:function(a,b){var c=this;void 0===b&&(b=new Image);b.addEventListener("load",function(){c.dispatchEvent({type:"load",content:b})},!1);b.addEventListener("error",function(){c.dispatchEvent({type:"error",message:"Couldn't load URL ["+a+"]"})},!1);c.crossOrigin&&(b.crossOrigin=c.crossOrigin);b.src=a}};THREE.JSONLoader=function(a){THREE.Loader.call(this,a);this.withCredentials=!1};THREE.JSONLoader.prototype=Object.create(THREE.Loader.prototype);THREE.JSONLoader.prototype.load=function(a,b,c){c=c&&"string"===typeof c?c:this.extractUrlBase(a);this.onLoadStart();this.loadAjaxJSON(this,a,b,c)}; -THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,g=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var i=JSON.parse(f.responseText);a.createModel(i,c,d)}else console.warn("THREE.JSONLoader: ["+b+"] seems to be unreachable or file there is empty");a.onLoadComplete()}else console.error("THREE.JSONLoader: Couldn't load ["+b+"] ["+f.status+"]");else f.readyState===f.LOADING?e&&(0===g&&(g=f.getResponseHeader("Content-Length")), -e({total:g,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&(g=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials;f.send(null)}; -THREE.JSONLoader.prototype.createModel=function(a,b,c){var d=new THREE.Geometry,e=void 0!==a.scale?1/a.scale:1,f,g,i,h,k,l,m,n,r,p,q,s,t,x,z,v=a.faces;p=a.vertices;var I=a.normals,H=a.colors,D=0;for(f=0;fB.parameters.opacity&& -(B.parameters.transparent=!0);B.parameters.normalMap?(G=THREE.ShaderLib.normalmap,A=THREE.UniformsUtils.clone(G.uniforms),s=B.parameters.color,X=B.parameters.specular,q=B.parameters.ambient,W=B.parameters.shininess,A.tNormal.value=y.textures[B.parameters.normalMap],B.parameters.normalScale&&A.uNormalScale.value.set(B.parameters.normalScale[0],B.parameters.normalScale[1]),B.parameters.map&&(A.tDiffuse.value=B.parameters.map,A.enableDiffuse.value=!0),B.parameters.envMap&&(A.tCube.value=B.parameters.envMap, -A.enableReflection.value=!0,A.uReflectivity.value=B.parameters.reflectivity),B.parameters.lightMap&&(A.tAO.value=B.parameters.lightMap,A.enableAO.value=!0),B.parameters.specularMap&&(A.tSpecular.value=y.textures[B.parameters.specularMap],A.enableSpecular.value=!0),B.parameters.displacementMap&&(A.tDisplacement.value=y.textures[B.parameters.displacementMap],A.enableDisplacement.value=!0,A.uDisplacementBias.value=B.parameters.displacementBias,A.uDisplacementScale.value=B.parameters.displacementScale), -A.uDiffuseColor.value.setHex(s),A.uSpecularColor.value.setHex(X),A.uAmbientColor.value.setHex(q),A.uShininess.value=W,B.parameters.opacity&&(A.uOpacity.value=B.parameters.opacity),r=new THREE.ShaderMaterial({fragmentShader:G.fragmentShader,vertexShader:G.vertexShader,uniforms:A,lights:!0,fog:!0})):r=new THREE[B.type](B.parameters);y.materials[K]=r}for(K in E.materials)if(B=E.materials[K],B.parameters.materials){L=[];for(s=0;si.end&&(i.end=e);b||(b=g)}}a.firstAnimation=b}; -THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.animations||(this.geometry.animations={});this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=1E3*((c.end-c.start)/b),this.time=0):console.warn("animation["+a+"] undefined")}; -THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time)this.direction*=-1,this.time>this.duration&&(this.time=this.duration,this.directionBackwards=!0),0>this.time&&(this.time=0,this.directionBackwards=!1)}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a!==this.currentKeyframe&& -(this.morphTargetInfluences[this.lastKeyframe]=0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[a]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=a);b=this.time%b/b;this.directionBackwards&&(b=1-b);this.morphTargetInfluences[this.currentKeyframe]=b;this.morphTargetInfluences[this.lastKeyframe]=1-b}; -THREE.MorphAnimMesh.prototype.clone=function(a){void 0===a&&(a=new THREE.MorphAnimMesh(this.geometry,this.material));a.duration=this.duration;a.mirroredLoop=this.mirroredLoop;a.time=this.time;a.lastKeyframe=this.lastKeyframe;a.currentKeyframe=this.currentKeyframe;a.direction=this.direction;a.directionBackwards=this.directionBackwards;THREE.Mesh.prototype.clone.call(this,a);return a};THREE.Ribbon=function(a,b){THREE.Object3D.call(this);this.geometry=a;this.material=b};THREE.Ribbon.prototype=Object.create(THREE.Object3D.prototype);THREE.Ribbon.prototype.clone=function(a){void 0===a&&(a=new THREE.Ribbon(this.geometry,this.material));THREE.Object3D.prototype.clone.call(this,a);return a};THREE.LOD=function(){THREE.Object3D.call(this);this.LODs=[]};THREE.LOD.prototype=Object.create(THREE.Object3D.prototype);THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);for(var b=Math.abs(b),c=0;c=this.LODs[b].visibleAtDistance)this.LODs[b-1].object3D.visible=!1,this.LODs[b].object3D.visible=!0;else break;for(;bt&&q.clearRect(na.min.x|0,na.min.y|0,na.max.x-na.min.x|0,na.max.y-na.min.y|0),0=j||(j*=f.intensity,c.add(Ta.multiplyScalar(j)))}else f instanceof THREE.PointLight&&(g=f.matrixWorld.getPosition(),j=b.dot(ib.subVectors(g,a).normalize()), -0>=j||(j*=0==f.distance?1:1-Math.min(a.distanceTo(g)/f.distance,1),0!=j&&(j*=f.intensity,c.add(Ta.multiplyScalar(j)))))}}function m(a,d,e,g,j,i,h,Y){f.info.render.vertices+=3;f.info.render.faces++;b(Y.opacity);c(Y.blending);B=a.positionScreen.x;K=a.positionScreen.y;L=d.positionScreen.x;U=d.positionScreen.y;aa=e.positionScreen.x;ba=e.positionScreen.y;s(B,K,L,U,aa,ba);(Y instanceof THREE.MeshLambertMaterial||Y instanceof THREE.MeshPhongMaterial)&&null===Y.map&&null===Y.map?(ma.copy(Y.color),wa.copy(Y.emissive), -Y.vertexColors===THREE.FaceColors&&ma.multiply(h.color),!0===Db?!1===Y.wireframe&&Y.shading==THREE.SmoothShading&&3==h.vertexNormalsLength?(Da.copy(nb),Aa.copy(nb),Ia.copy(nb),n(h.v1.positionWorld,h.vertexNormalsModel[0],Da),n(h.v2.positionWorld,h.vertexNormalsModel[1],Aa),n(h.v3.positionWorld,h.vertexNormalsModel[2],Ia),Da.multiply(ma).add(wa),Aa.multiply(ma).add(wa),Ia.multiply(ma).add(wa),Ja.addColors(Aa,Ia).multiplyScalar(0.5),Z=jb(Da,Aa,Ia,Ja),I(B,K,L,U,aa,ba,0,0,1,0,0,1,Z)):(fa.copy(nb),n(h.centroidModel, -h.normalModel,fa),fa.multiply(ma).add(wa),!0===Y.wireframe?v(fa,Y.wireframeLinewidth,Y.wireframeLinecap,Y.wireframeLinejoin):x(fa)):!0===Y.wireframe?v(Y.color,Y.wireframeLinewidth,Y.wireframeLinecap,Y.wireframeLinejoin):x(Y.color)):Y instanceof THREE.MeshBasicMaterial||Y instanceof THREE.MeshLambertMaterial||Y instanceof THREE.MeshPhongMaterial?null!==Y.map?Y.map.mapping instanceof THREE.UVMapping&&(pa=h.uvs[0],z(B,K,L,U,aa,ba,pa[g].x,pa[g].y,pa[j].x,pa[j].y,pa[i].x,pa[i].y,Y.map)):null!==Y.envMap? -Y.envMap.mapping instanceof THREE.SphericalReflectionMapping&&(ib.copy(h.vertexNormalsModelView[g]),gb=0.5*ib.x+0.5,hb=0.5*ib.y+0.5,ib.copy(h.vertexNormalsModelView[j]),Ea=0.5*ib.x+0.5,yb=0.5*ib.y+0.5,ib.copy(h.vertexNormalsModelView[i]),Cb=0.5*ib.x+0.5,Lb=0.5*ib.y+0.5,z(B,K,L,U,aa,ba,gb,hb,Ea,yb,Cb,Lb,Y.envMap)):(fa.copy(Y.color),Y.vertexColors===THREE.FaceColors&&fa.multiply(h.color),!0===Y.wireframe?v(fa,Y.wireframeLinewidth,Y.wireframeLinecap,Y.wireframeLinejoin):x(fa)):Y instanceof THREE.MeshDepthMaterial? -(ra=l.near,ga=l.far,j=1-cb(a.positionScreen.z*a.positionScreen.w,ra,ga),Da.setRGB(j,j,j),j=1-cb(d.positionScreen.z*d.positionScreen.w,ra,ga),Aa.setRGB(j,j,j),j=1-cb(e.positionScreen.z*e.positionScreen.w,ra,ga),Ia.setRGB(j,j,j),Ja.addColors(Aa,Ia).multiplyScalar(0.5),Z=jb(Da,Aa,Ia,Ja),I(B,K,L,U,aa,ba,0,0,1,0,0,1,Z)):Y instanceof THREE.MeshNormalMaterial&&(Y.shading==THREE.FlatShading?(d=h.normalModelView,fa.setRGB(d.x,d.y,d.z).multiplyScalar(0.5).addScalar(0.5),!0===Y.wireframe?v(fa,Y.wireframeLinewidth, -Y.wireframeLinecap,Y.wireframeLinejoin):x(fa)):Y.shading==THREE.SmoothShading&&(d=h.vertexNormalsModelView[g],Da.setRGB(d.x,d.y,d.z).multiplyScalar(0.5).addScalar(0.5),d=h.vertexNormalsModelView[j],Aa.setRGB(d.x,d.y,d.z).multiplyScalar(0.5).addScalar(0.5),d=h.vertexNormalsModelView[i],Ia.setRGB(d.x,d.y,d.z).multiplyScalar(0.5).addScalar(0.5),Ja.addColors(Aa,Ia).multiplyScalar(0.5),Z=jb(Da,Aa,Ia,Ja),I(B,K,L,U,aa,ba,0,0,1,0,0,1,Z)))}function s(a,b,c,d,e,f){q.beginPath();q.moveTo(a,b);q.lineTo(c,d); -q.lineTo(e,f);q.closePath()}function t(a,b,c,d,e,f,g,j){q.beginPath();q.moveTo(a,b);q.lineTo(c,d);q.lineTo(e,f);q.lineTo(g,j);q.closePath()}function v(a,b,c,e){H!==b&&(H=q.lineWidth=b);D!==c&&(D=q.lineCap=c);y!==e&&(y=q.lineJoin=e);d(a.getStyle());q.stroke();Ya.expandByScalar(2*b)}function x(a){e(a.getStyle());q.fill()}function z(a,b,c,d,f,g,j,i,h,Y,k,l,n){if(!(n instanceof THREE.DataTexture||void 0===n.image||0==n.image.width)){if(!0===n.needsUpdate){var m=n.wrapS==THREE.RepeatWrapping,p=n.wrapT== -THREE.RepeatWrapping;Ra[n.id]=q.createPattern(n.image,!0===m&&!0===p?"repeat":!0===m&&!1===p?"repeat-x":!1===m&&!0===p?"repeat-y":"no-repeat");n.needsUpdate=!1}void 0===Ra[n.id]?e("rgba(0,0,0,1)"):e(Ra[n.id]);var m=n.offset.x/n.repeat.x,p=n.offset.y/n.repeat.y,s=n.image.width*n.repeat.x,r=n.image.height*n.repeat.y,j=(j+m)*s,i=(1-i+p)*r,c=c-a,d=d-b,f=f-a,g=g-b,h=(h+m)*s-j,Y=(1-Y+p)*r-i,k=(k+m)*s-j,l=(1-l+p)*r-i,m=h*l-k*Y;0===m?(void 0===ia[n.id]&&(b=document.createElement("canvas"),b.width=n.image.width, -b.height=n.image.height,b=b.getContext("2d"),b.drawImage(n.image,0,0),ia[n.id]=b.getImageData(0,0,n.image.width,n.image.height).data),b=ia[n.id],j=4*(Math.floor(j)+Math.floor(i)*n.image.width),fa.setRGB(b[j]/255,b[j+1]/255,b[j+2]/255),x(fa)):(m=1/m,n=(l*c-Y*f)*m,Y=(l*d-Y*g)*m,c=(h*f-k*c)*m,d=(h*g-k*d)*m,a=a-n*j-c*i,j=b-Y*j-d*i,q.save(),q.transform(n,Y,c,d,a,j),q.fill(),q.restore())}}function I(a,b,c,d,e,f,g,j,i,h,Y,k,n){var l,m;l=n.width-1;m=n.height-1;g*=l;j*=m;c-=a;d-=b;e-=a;f-=b;i=i*l-g;h=h*m- -j;Y=Y*l-g;k=k*m-j;m=1/(i*k-Y*h);l=(k*c-h*e)*m;h=(k*d-h*f)*m;c=(i*e-Y*c)*m;d=(i*f-Y*d)*m;a=a-l*g-c*j;b=b-h*g-d*j;q.save();q.transform(l,h,c,d,a,b);q.clip();q.drawImage(n,0,0);q.restore()}function jb(a,b,c,d){ob[0]=255*a.r|0;ob[1]=255*a.g|0;ob[2]=255*a.b|0;ob[4]=255*b.r|0;ob[5]=255*b.g|0;ob[6]=255*b.b|0;ob[8]=255*c.r|0;ob[9]=255*c.g|0;ob[10]=255*c.b|0;ob[12]=255*d.r|0;ob[13]=255*d.g|0;ob[14]=255*d.b|0;Ob.putImageData(rc,0,0);sb.drawImage(zb,0,0);return Fa}function cb(a,b,c){a=(a-b)/(c-b);return a*a* -(3-2*a)}function kb(a,b){var c=b.x-a.x,d=b.y-a.y,e=c*c+d*d;0!==e&&(e=1/Math.sqrt(e),c*=e,d*=e,b.x+=c,b.y+=d,a.x-=c,a.y-=d)}if(!1===l instanceof THREE.Camera)console.error("THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.");else{!0===this.autoClear&&this.clear();q.setTransform(1,0,0,-1,r,p);f.info.render.vertices=0;f.info.render.faces=0;g=k.projectScene(a,l,this.sortObjects,this.sortElements);i=g.elements;h=g.lights;Db=0>1,dd=ja.height>>1,Wa=Za.scale.x*r,Pa=Za.scale.y*p,Va=Wa*Y,$a=Pa*dd,Ya.min.set(T.x-Va,T.y-$a),Ya.max.set(T.x+Va,T.y+$a),!1!==Ua.isIntersectionBox(Ya)&&(q.save(),q.translate(T.x, -T.y),q.rotate(-Za.rotation),q.scale(Wa,-Pa),q.translate(-Y,-dd),q.drawImage(ja,0,0),q.restore())):S instanceof THREE.ParticleCanvasMaterial&&(Va=Za.scale.x*r,$a=Za.scale.y*p,Ya.min.set(T.x-Va,T.y-$a),Ya.max.set(T.x+Va,T.y+$a),!1!==Ua.isIntersectionBox(Ya)&&(d(S.color.getStyle()),e(S.color.getStyle()),q.save(),q.translate(T.x,T.y),q.rotate(-Za.rotation),q.scale(Va,$a),S.program(q),q.restore()))}else if(ja instanceof THREE.RenderableLine)F=ja.v1,E=ja.v2,F.positionScreen.x*=r,F.positionScreen.y*=p,E.positionScreen.x*= -r,E.positionScreen.y*=p,Ya.setFromPoints([F.positionScreen,E.positionScreen]),!0===Ua.isIntersectionBox(Ya)&&(T=F,Za=E,b(S.opacity),c(S.blending),q.beginPath(),q.moveTo(T.positionScreen.x,T.positionScreen.y),q.lineTo(Za.positionScreen.x,Za.positionScreen.y),S instanceof THREE.LineBasicMaterial&&(T=S.linewidth,H!==T&&(H=q.lineWidth=T),T=S.linecap,D!==T&&(D=q.lineCap=T),T=S.linejoin,y!==T&&(y=q.lineJoin=T),d(S.color.getStyle()),q.stroke(),Ya.expandByScalar(2*S.linewidth)));else if(ja instanceof THREE.RenderableFace3){F= -ja.v1;E=ja.v2;G=ja.v3;if(-1>F.positionScreen.z||1E.positionScreen.z||1G.positionScreen.z||1F.positionScreen.z||1E.positionScreen.z||1G.positionScreen.z||1W.positionScreen.z||1 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif", -lights_lambert_vertex:"vLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\nvLightBack = vec3( 0.0 );\n#endif\ntransformedNormal = normalize( transformedNormal );\n#if MAX_DIR_LIGHTS > 0\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, dirVector );\nvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\ndirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\ndirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n#ifdef DOUBLE_SIDED\nvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n#endif\n}\n#endif\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\npointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\npointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;\n#ifdef DOUBLE_SIDED\nvLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\nspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\nspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;\n#ifdef DOUBLE_SIDED\nvLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\nvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n#ifdef DOUBLE_SIDED\nvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n#endif\n}\n#endif\nvLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;\n#ifdef DOUBLE_SIDED\nvLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;\n#endif", -lights_phong_pars_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif", -lights_phong_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nvPointLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nvSpotLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvWorldPosition = worldPosition.xyz;\n#endif", -lights_phong_pars_fragment:"uniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#else\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#else\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;", -lights_phong_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#ifdef DOUBLE_SIDED\nnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n#endif\n#ifdef USE_NORMALMAP\nnormal = perturbNormal2Arb( -viewPosition, normal );\n#elif defined( USE_BUMPMAP )\nnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vPointLight[ i ].xyz );\nfloat lDistance = vPointLight[ i ].w;\n#endif\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n#endif\npointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\nvec3 pointHalfVector = normalize( lVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n#else\npointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vSpotLight[ i ].xyz );\nfloat lDistance = vSpotLight[ i ].w;\n#endif\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n#endif\nspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\nvec3 spotHalfVector = normalize( lVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, dirVector );\n#ifdef WRAP_AROUND\nfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n#endif\ndirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += diffuse * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;\n#endif", -color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n#ifdef BONE_TEXTURE\nuniform sampler2D boneTexture;\nmat4 getBoneMatrix( const in float i ) {\nfloat j = i * 4.0;\nfloat x = mod( j, N_BONE_PIXEL_X );\nfloat y = floor( j / N_BONE_PIXEL_X );\nconst float dx = 1.0 / N_BONE_PIXEL_X;\nconst float dy = 1.0 / N_BONE_PIXEL_Y;\ny = dy * ( y + 0.5 );\nvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\nvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\nvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\nvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\nmat4 bone = mat4( v1, v2, v3, v4 );\nreturn bone;\n}\n#else\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\nmat4 getBoneMatrix( const in float i ) {\nmat4 bone = boneGlobalMatrices[ int(i) ];\nreturn bone;\n}\n#endif\n#endif", -skinbase_vertex:"#ifdef USE_SKINNING\nmat4 boneMatX = getBoneMatrix( skinIndex.x );\nmat4 boneMatY = getBoneMatrix( skinIndex.y );\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n#ifdef USE_MORPHTARGETS\nvec4 skinVertex = vec4( morphed, 1.0 );\n#else\nvec4 skinVertex = vec4( position, 1.0 );\n#endif\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n#ifndef USE_MORPHNORMALS\nuniform float morphTargetInfluences[ 8 ];\n#else\nuniform float morphTargetInfluences[ 4 ];\n#endif\n#endif", -morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n#ifndef USE_MORPHNORMALS\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n#endif\nmorphed += position;\n#endif", -default_vertex:"vec4 mvPosition;\n#ifdef USE_SKINNING\nmvPosition = modelViewMatrix * skinned;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( position, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\nvec3 morphedNormal = vec3( 0.0 );\nmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\nmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\nmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\nmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\nmorphedNormal += normal;\n#endif", -skinnormal_vertex:"#ifdef USE_SKINNING\nmat4 skinMatrix = skinWeight.x * boneMatX;\nskinMatrix \t+= skinWeight.y * boneMatY;\n#ifdef USE_MORPHNORMALS\nvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n#else\nvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n#endif\n#endif",defaultnormal_vertex:"vec3 objectNormal;\n#ifdef USE_SKINNING\nobjectNormal = skinnedNormal.xyz;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )\nobjectNormal = morphedNormal;\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )\nobjectNormal = normal;\n#endif\n#ifdef FLIP_SIDED\nobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;", -shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform vec2 shadowMapSize[ MAX_SHADOWS ];\nuniform float shadowDarkness[ MAX_SHADOWS ];\nuniform float shadowBias[ MAX_SHADOWS ];\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif",shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_DEBUG\nvec3 frustumColors[3];\nfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\nfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\nfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n#endif\n#ifdef SHADOWMAP_CASCADE\nint inFrustumCount = 0;\n#endif\nfloat fDepth;\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\nbool inFrustum = all( inFrustumVec );\n#ifdef SHADOWMAP_CASCADE\ninFrustumCount += int( inFrustum );\nbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n#else\nbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n#endif\nbool frustumTest = all( frustumTestVec );\nif ( frustumTest ) {\nshadowCoord.z += shadowBias[ i ];\n#if defined( SHADOWMAP_TYPE_PCF )\nfloat shadow = 0.0;\nconst float shadowDelta = 1.0 / 9.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.25 * xPixelOffset;\nfloat dy0 = -1.25 * yPixelOffset;\nfloat dx1 = 1.25 * xPixelOffset;\nfloat dy1 = 1.25 * yPixelOffset;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\nfloat shadow = 0.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.0 * xPixelOffset;\nfloat dy0 = -1.0 * yPixelOffset;\nfloat dx1 = 1.0 * xPixelOffset;\nfloat dy1 = 1.0 * yPixelOffset;\nmat3 shadowKernel;\nmat3 depthKernel;\ndepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( depthKernel[0][0] < shadowCoord.z ) shadowKernel[0][0] = 0.25;\nelse shadowKernel[0][0] = 0.0;\ndepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( depthKernel[0][1] < shadowCoord.z ) shadowKernel[0][1] = 0.25;\nelse shadowKernel[0][1] = 0.0;\ndepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( depthKernel[0][2] < shadowCoord.z ) shadowKernel[0][2] = 0.25;\nelse shadowKernel[0][2] = 0.0;\ndepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( depthKernel[1][0] < shadowCoord.z ) shadowKernel[1][0] = 0.25;\nelse shadowKernel[1][0] = 0.0;\ndepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( depthKernel[1][1] < shadowCoord.z ) shadowKernel[1][1] = 0.25;\nelse shadowKernel[1][1] = 0.0;\ndepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( depthKernel[1][2] < shadowCoord.z ) shadowKernel[1][2] = 0.25;\nelse shadowKernel[1][2] = 0.0;\ndepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( depthKernel[2][0] < shadowCoord.z ) shadowKernel[2][0] = 0.25;\nelse shadowKernel[2][0] = 0.0;\ndepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( depthKernel[2][1] < shadowCoord.z ) shadowKernel[2][1] = 0.25;\nelse shadowKernel[2][1] = 0.0;\ndepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( depthKernel[2][2] < shadowCoord.z ) shadowKernel[2][2] = 0.25;\nelse shadowKernel[2][2] = 0.0;\nvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\nshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\nshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\nvec4 shadowValues;\nshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\nshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\nshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\nshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\nshadow = dot( shadowValues, vec4( 1.0 ) );\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n#endif\n}\n#ifdef SHADOWMAP_DEBUG\n#ifdef SHADOWMAP_CASCADE\nif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n#else\nif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n#endif\n#endif\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", -shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; -THREE.UniformsUtils={merge:function(a){var b,c,d,e={};for(b=0;b dashSize ) {\ndiscard;\n}\ngl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f", -value:1}},vertexShader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform float mNear;\nuniform float mFar;\nuniform float opacity;\nvoid main() {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat color = 1.0 - smoothstep( mNear, mFar, depth );\ngl_FragColor = vec4( vec3( color ), opacity );\n}"},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:"varying vec3 vNormal;\nvoid main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvNormal = normalize( normalMatrix * normal );\ngl_Position = projectionMatrix * mvPosition;\n}", -fragmentShader:"uniform float opacity;\nvarying vec3 vNormal;\nvoid main() {\ngl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );\n}"},normalmap:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{enableAO:{type:"i",value:0},enableDiffuse:{type:"i",value:0},enableSpecular:{type:"i",value:0},enableReflection:{type:"i",value:0},enableDisplacement:{type:"i",value:0},tDisplacement:{type:"t",value:null},tDiffuse:{type:"t",value:null}, -tCube:{type:"t",value:null},tNormal:{type:"t",value:null},tSpecular:{type:"t",value:null},tAO:{type:"t",value:null},uNormalScale:{type:"v2",value:new THREE.Vector2(1,1)},uDisplacementBias:{type:"f",value:0},uDisplacementScale:{type:"f",value:1},uDiffuseColor:{type:"c",value:new THREE.Color(16777215)},uSpecularColor:{type:"c",value:new THREE.Color(1118481)},uAmbientColor:{type:"c",value:new THREE.Color(16777215)},uShininess:{type:"f",value:30},uOpacity:{type:"f",value:1},useRefract:{type:"i",value:0}, -uRefractionRatio:{type:"f",value:0.98},uReflectivity:{type:"f",value:0.5},uOffset:{type:"v2",value:new THREE.Vector2(0,0)},uRepeat:{type:"v2",value:new THREE.Vector2(1,1)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),fragmentShader:["uniform vec3 uAmbientColor;\nuniform vec3 uDiffuseColor;\nuniform vec3 uSpecularColor;\nuniform float uShininess;\nuniform float uOpacity;\nuniform bool enableDiffuse;\nuniform bool enableSpecular;\nuniform bool enableAO;\nuniform bool enableReflection;\nuniform sampler2D tDiffuse;\nuniform sampler2D tNormal;\nuniform sampler2D tSpecular;\nuniform sampler2D tAO;\nuniform samplerCube tCube;\nuniform vec2 uNormalScale;\nuniform bool useRefract;\nuniform float uRefractionRatio;\nuniform float uReflectivity;\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nuniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", -THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3( 1.0 ), uOpacity );\nvec3 specularTex = vec3( 1.0 );\nvec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;\nnormalTex.xy *= uNormalScale;\nnormalTex = normalize( normalTex );\nif( enableDiffuse ) {\n#ifdef GAMMA_INPUT\nvec4 texelColor = texture2D( tDiffuse, vUv );\ntexelColor.xyz *= texelColor.xyz;\ngl_FragColor = gl_FragColor * texelColor;\n#else\ngl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );\n#endif\n}\nif( enableAO ) {\n#ifdef GAMMA_INPUT\nvec4 aoColor = texture2D( tAO, vUv );\naoColor.xyz *= aoColor.xyz;\ngl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;\n#endif\n}\nif( enableSpecular )\nspecularTex = texture2D( tSpecular, vUv ).xyz;\nmat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );\nvec3 finalNormal = tsb * normalTex;\n#ifdef FLIP_SIDED\nfinalNormal = -finalNormal;\n#endif\nvec3 normal = normalize( finalNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 pointVector = lPosition.xyz + vViewPosition.xyz;\nfloat pointDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\npointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );\npointVector = normalize( pointVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );\n#endif\npointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;\nvec3 pointHalfVector = normalize( pointVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;\n#else\npointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 spotVector = lPosition.xyz + vViewPosition.xyz;\nfloat spotDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nspotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );\nspotVector = normalize( spotVector );\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );\n#endif\nspotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;\nvec3 spotHalfVector = normalize( spotVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\n#ifdef WRAP_AROUND\nfloat directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );\nfloat directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\n#endif\ndirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += uDiffuseColor * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += uSpecularColor * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor ) + totalSpecular;\n#endif\nif ( enableReflection ) {\nvec3 vReflect;\nvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\nif ( useRefract ) {\nvReflect = refract( cameraToVertex, normal, uRefractionRatio );\n} else {\nvReflect = reflect( cameraToVertex, normal );\n}\nvec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );\n#ifdef GAMMA_INPUT\ncubeColor.xyz *= cubeColor.xyz;\n#endif\ngl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );\n}", -THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n"),vertexShader:["attribute vec4 tangent;\nuniform vec2 uOffset;\nuniform vec2 uRepeat;\nuniform bool enableDisplacement;\n#ifdef VERTEX_TEXTURES\nuniform sampler2D tDisplacement;\nuniform float uDisplacementScale;\nuniform float uDisplacementBias;\n#endif\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", -THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,"#ifdef USE_SKINNING\nvNormal = normalize( normalMatrix * skinnedNormal.xyz );\nvec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );\nvTangent = normalize( normalMatrix * skinnedTangent.xyz );\n#else\nvNormal = normalize( normalMatrix * normal );\nvTangent = normalize( normalMatrix * tangent.xyz );\n#endif\nvBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );\nvUv = uv * uRepeat + uOffset;\nvec3 displacedPosition;\n#ifdef VERTEX_TEXTURES\nif ( enableDisplacement ) {\nvec3 dv = texture2D( tDisplacement, uv ).xyz;\nfloat df = uDisplacementScale * dv.x + uDisplacementBias;\ndisplacedPosition = position + normalize( normal ) * df;\n} else {\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n}\n#else\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n#endif\nvec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );\nvec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\nvWorldPosition = worldPosition.xyz;\nvViewPosition = -mvPosition.xyz;\n#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif\n}"].join("\n")}, -cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:"varying vec3 vWorldPosition;\nvoid main() {\nvec4 worldPosition = modelMatrix * vec4( position, 1.0 );\nvWorldPosition = worldPosition.xyz;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\nvoid main() {\ngl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n}"}, -depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,"}"].join("\n"),fragmentShader:"vec4 pack_depth( const in float depth ) {\nconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\nconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\nvec4 res = fract( depth * bit_shift );\nres -= res.xxyz * bit_mask;\nreturn res;\n}\nvoid main() {\ngl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n}"}};THREE.WebGLRenderer=function(a){function b(a){if(a.__webglCustomAttributesList)for(var b in a.__webglCustomAttributesList)j.deleteBuffer(a.__webglCustomAttributesList[b].buffer)}function c(a,b){var c=a.vertices.length,d=b.material;if(d.attributes){void 0===a.__webglCustomAttributesList&&(a.__webglCustomAttributesList=[]);for(var e in d.attributes){var f=d.attributes[e];if(!f.__webglInitialized||f.createUniqueBuffers){f.__webglInitialized=!0;var g=1;"v2"===f.type?g=2:"v3"===f.type?g=3:"v4"===f.type? -g=4:"c"===f.type&&(g=3);f.size=g;f.array=new Float32Array(c*g);f.buffer=j.createBuffer();f.buffer.belongsToAttribute=e;f.needsUpdate=!0}a.__webglCustomAttributesList.push(f)}}}function d(a,b){var c=b.geometry,d=a.faces3,i=a.faces4,h=3*d.length+4*i.length,k=1*d.length+2*i.length,i=3*d.length+4*i.length,d=e(b,a),n=g(d),l=f(d),m=d.vertexColors?d.vertexColors:!1;a.__vertexArray=new Float32Array(3*h);l&&(a.__normalArray=new Float32Array(3*h));c.hasTangents&&(a.__tangentArray=new Float32Array(4*h));m&& -(a.__colorArray=new Float32Array(3*h));if(n){if(0l;l++)M.autoScaleCubemaps&&!f?(m=k,r=l,t=c.image[l],x=ad,t.width<=x&&t.height<=x||(z=Math.max(t.width,t.height),v=Math.floor(t.width*x/z),x=Math.floor(t.height*x/z),z=document.createElement("canvas"),z.width=v,z.height=x,z.getContext("2d").drawImage(t,0,0,t.width,t.height,0,0,v,x),t=z),m[r]=t):k[l]=c.image[l];l=k[0];m=0===(l.width&l.width-1)&&0===(l.height&l.height-1);r=K(c.format);t=K(c.type);A(j.TEXTURE_CUBE_MAP,c,m);for(l=0;6>l;l++)if(f){x= -k[l].mipmaps;z=0;for(D=x.length;z=Bc&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Bc); -Ra+=1;return a}function D(a,b){a._modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld);a._normalMatrix.getInverse(a._modelViewMatrix);a._normalMatrix.transpose()}function y(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function F(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function E(a,b,c){yb!==a&&(a?j.enable(j.POLYGON_OFFSET_FILL):j.disable(j.POLYGON_OFFSET_FILL),yb=a);if(a&&(Cb!==b||Lb!==c))j.polygonOffset(b,c),Cb=b,Lb=c}function G(a){for(var a=a.split("\n"),b=0,c= -a.length;bb;b++)j.deleteFramebuffer(a.__webglFramebuffer[b]),j.deleteRenderbuffer(a.__webglRenderbuffer[b]);else j.deleteFramebuffer(a.__webglFramebuffer),j.deleteRenderbuffer(a.__webglRenderbuffer);M.info.memory.textures--},Wa=function(a){a=a.target;a.removeEventListener("dispose",Wa);Pa(a)},Pa=function(a){var b= -a.program;if(void 0!==b){a.program=void 0;var c,d,e=!1,a=0;for(c=fa.length;a<=b.position)a&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglVertexBuffer),k(b.position),j.vertexAttribPointer(b.position,3,j.FLOAT,!1,0,0));else if(f.morphTargetBase){c=d.program.attributes;-1!==f.morphTargetBase&&0<=c.position?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[f.morphTargetBase]),k(c.position),j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0)):0<=c.position&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglVertexBuffer),k(c.position),j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0));if(f.morphTargetForcedOrder.length){var i= -0;h=f.morphTargetForcedOrder;for(g=f.morphTargetInfluences;i<=c["morphTarget"+i]&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[h[i]]),k(c["morphTarget"+i]),j.vertexAttribPointer(c["morphTarget"+i],3,j.FLOAT,!1,0,0)),0<=c["morphNormal"+i]&&d.morphNormals&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphNormalsBuffers[h[i]]),k(c["morphNormal"+i]),j.vertexAttribPointer(c["morphNormal"+i],3,j.FLOAT,!1,0,0)),f.__webglMorphTargetInfluences[i]=g[h[i]],i++}else{h= -[];g=f.morphTargetInfluences;var m,p=g.length;for(m=0;md.numSupportedMorphTargets?(h.sort(n),h.length=d.numSupportedMorphTargets):h.length>d.numSupportedMorphNormals?h.sort(n):0===h.length&&h.push([0,0]);for(i=0;i<=c["morphTarget"+i]&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[m]),k(c["morphTarget"+i]),j.vertexAttribPointer(c["morphTarget"+i],3,j.FLOAT,!1,0,0)),0<=c["morphNormal"+i]&&d.morphNormals&& -(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphNormalsBuffers[m]),k(c["morphNormal"+i]),j.vertexAttribPointer(c["morphNormal"+i],3,j.FLOAT,!1,0,0)),f.__webglMorphTargetInfluences[i]=g[m]):f.__webglMorphTargetInfluences[i]=0,i++}null!==d.program.uniforms.morphTargetInfluences&&j.uniform1fv(d.program.uniforms.morphTargetInfluences,f.__webglMorphTargetInfluences)}if(a){if(e.__webglCustomAttributesList){g=0;for(h=e.__webglCustomAttributesList.length;g<=b[c.buffer.belongsToAttribute]&& -(j.bindBuffer(j.ARRAY_BUFFER,c.buffer),k(b[c.buffer.belongsToAttribute]),j.vertexAttribPointer(b[c.buffer.belongsToAttribute],c.size,j.FLOAT,!1,0,0))}0<=b.color&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglColorBuffer),k(b.color),j.vertexAttribPointer(b.color,3,j.FLOAT,!1,0,0));0<=b.normal&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglNormalBuffer),k(b.normal),j.vertexAttribPointer(b.normal,3,j.FLOAT,!1,0,0));0<=b.tangent&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglTangentBuffer),k(b.tangent),j.vertexAttribPointer(b.tangent, -4,j.FLOAT,!1,0,0));0<=b.uv&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUVBuffer),k(b.uv),j.vertexAttribPointer(b.uv,2,j.FLOAT,!1,0,0));0<=b.uv2&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUV2Buffer),k(b.uv2),j.vertexAttribPointer(b.uv2,2,j.FLOAT,!1,0,0));d.skinning&&(0<=b.skinIndex&&0<=b.skinWeight)&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinIndicesBuffer),k(b.skinIndex),j.vertexAttribPointer(b.skinIndex,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinWeightsBuffer),k(b.skinWeight),j.vertexAttribPointer(b.skinWeight, -4,j.FLOAT,!1,0,0));0<=b.lineDistance&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglLineDistanceBuffer),k(b.lineDistance),j.vertexAttribPointer(b.lineDistance,1,j.FLOAT,!1,0,0))}f instanceof THREE.Mesh?(d.wireframe?(d=d.wireframeLinewidth,d!==Ua&&(j.lineWidth(d),Ua=d),a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglLineBuffer),j.drawElements(j.LINES,e.__webglLineCount,j.UNSIGNED_SHORT,0)):(a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglFaceBuffer),j.drawElements(j.TRIANGLES,e.__webglFaceCount,j.UNSIGNED_SHORT, -0)),M.info.render.calls++,M.info.render.vertices+=e.__webglFaceCount,M.info.render.faces+=e.__webglFaceCount/3):f instanceof THREE.Line?(f=f.type===THREE.LineStrip?j.LINE_STRIP:j.LINES,d=d.linewidth,d!==Ua&&(j.lineWidth(d),Ua=d),j.drawArrays(f,0,e.__webglLineCount),M.info.render.calls++):f instanceof THREE.ParticleSystem?(j.drawArrays(j.POINTS,0,e.__webglParticleCount),M.info.render.calls++,M.info.render.points+=e.__webglParticleCount):f instanceof THREE.Ribbon&&(j.drawArrays(j.TRIANGLE_STRIP,0,e.__webglVertexCount), -M.info.render.calls++)}};this.render=function(a,b,c,d){if(!1===b instanceof THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var e,f,g,h,i=a.__lights,k=a.fog;Ja=-1;sb=!0;this.autoUpdateScene&&a.updateMatrixWorld();void 0===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);Ob.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);zb.setFromMatrix(Ob);this.autoUpdateObjects&&this.initWebGLObjects(a);r(this.renderPluginsPre, -a,b);M.info.render.calls=0;M.info.render.vertices=0;M.info.render.faces=0;M.info.render.points=0;this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);h=a.__webglObjects;d=0;for(e=h.length;dva;va++)mc=$a[va],Gb[qb]=mc.x,Gb[qb+1]=mc.y,Gb[qb+2]=mc.z,qb+=3;else for(va=0;3>va;va++)Gb[qb]=Wa.x,Gb[qb+1]=Wa.y,Gb[qb+2]=Wa.z,qb+=3;C=0;for(V=ta.length;Cva;va++)mc=$a[va],Gb[qb]=mc.x,Gb[qb+1]=mc.y,Gb[qb+2]=mc.z,qb+=3;else for(va=0;4>va;va++)Gb[qb]=Wa.x,Gb[qb+1]=Wa.y,Gb[qb+ -2]=Wa.z,qb+=3;j.bindBuffer(j.ARRAY_BUFFER,qa.__webglNormalBuffer);j.bufferData(j.ARRAY_BUFFER,Gb,na)}if(Bc&&fd&&pb){C=0;for(V=sa.length;Cva;va++)Eb=hb[va],Mb[gc]=Eb.x,Mb[gc+1]=Eb.y,gc+=2;C=0;for(V=ta.length;Cva;va++)Eb=hb[va],Mb[gc]=Eb.x,Mb[gc+1]=Eb.y,gc+=2;0va;va++)xc=sb[va],Nb[hc]=xc.x,Nb[hc+1]=xc.y,hc+=2;C=0;for(V=ta.length;Cva;va++)xc=sb[va],Nb[hc]=xc.x,Nb[hc+1]=xc.y,hc+=2;0<=y[x]&&a.numSupportedMorphNormals++}a.uniformsList=[];for(i in a.uniforms)a.uniformsList.push([a.uniforms[i],i])};this.setFaceCulling=function(a,b){a===THREE.CullFaceNone?j.disable(j.CULL_FACE):(b===THREE.FrontFaceDirectionCW?j.frontFace(j.CW):j.frontFace(j.CCW),a===THREE.CullFaceBack?j.cullFace(j.BACK):a===THREE.CullFaceFront?j.cullFace(j.FRONT):j.cullFace(j.FRONT_AND_BACK),j.enable(j.CULL_FACE))};this.setMaterialFaces=function(a){var b=a.side===THREE.DoubleSide,a=a.side===THREE.BackSide;ia!== -b&&(b?j.disable(j.CULL_FACE):j.enable(j.CULL_FACE),ia=b);ra!==a&&(a?j.frontFace(j.CW):j.frontFace(j.CCW),ra=a)};this.setDepthTest=function(a){hb!==a&&(a?j.enable(j.DEPTH_TEST):j.disable(j.DEPTH_TEST),hb=a)};this.setDepthWrite=function(a){Ea!==a&&(j.depthMask(a),Ea=a)};this.setBlending=function(a,b,c,d){a!==ga&&(a===THREE.NoBlending?j.disable(j.BLEND):a===THREE.AdditiveBlending?(j.enable(j.BLEND),j.blendEquation(j.FUNC_ADD),j.blendFunc(j.SRC_ALPHA,j.ONE)):a===THREE.SubtractiveBlending?(j.enable(j.BLEND), -j.blendEquation(j.FUNC_ADD),j.blendFunc(j.ZERO,j.ONE_MINUS_SRC_COLOR)):a===THREE.MultiplyBlending?(j.enable(j.BLEND),j.blendEquation(j.FUNC_ADD),j.blendFunc(j.ZERO,j.SRC_COLOR)):a===THREE.CustomBlending?j.enable(j.BLEND):(j.enable(j.BLEND),j.blendEquationSeparate(j.FUNC_ADD,j.FUNC_ADD),j.blendFuncSeparate(j.SRC_ALPHA,j.ONE_MINUS_SRC_ALPHA,j.ONE,j.ONE_MINUS_SRC_ALPHA)),ga=a);if(a===THREE.CustomBlending){if(b!==Z&&(j.blendEquation(K(b)),Z=b),c!==pa||d!==gb)j.blendFunc(K(c),K(d)),pa=c,gb=d}else gb=pa= -Z=null};this.setTexture=function(a,b){if(a.needsUpdate){a.__webglInit||(a.__webglInit=!0,a.addEventListener("dispose",Va),a.__webglTexture=j.createTexture(),M.info.memory.textures++);j.activeTexture(j.TEXTURE0+b);j.bindTexture(j.TEXTURE_2D,a.__webglTexture);j.pixelStorei(j.UNPACK_FLIP_Y_WEBGL,a.flipY);j.pixelStorei(j.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a.premultiplyAlpha);j.pixelStorei(j.UNPACK_ALIGNMENT,a.unpackAlignment);var c=a.image,d=0===(c.width&c.width-1)&&0===(c.height&c.height-1),e=K(a.format), -f=K(a.type);A(j.TEXTURE_2D,a,d);var g=a.mipmaps;if(a instanceof THREE.DataTexture)if(0f;f++){a.__webglFramebuffer[f]=j.createFramebuffer();a.__webglRenderbuffer[f]=j.createRenderbuffer();j.texImage2D(j.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var g=a,h=j.TEXTURE_CUBE_MAP_POSITIVE_X+f;j.bindFramebuffer(j.FRAMEBUFFER, -a.__webglFramebuffer[f]);j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,h,g.__webglTexture,0);X(a.__webglRenderbuffer[f],a)}c&&j.generateMipmap(j.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=j.createFramebuffer(),a.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:j.createRenderbuffer(),j.bindTexture(j.TEXTURE_2D,a.__webglTexture),A(j.TEXTURE_2D,a,c),j.texImage2D(j.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=j.TEXTURE_2D,j.bindFramebuffer(j.FRAMEBUFFER,a.__webglFramebuffer), -j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_ATTACHMENT,j.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_STENCIL_ATTACHMENT,j.RENDERBUFFER,a.__webglRenderbuffer):X(a.__webglRenderbuffer,a),c&&j.generateMipmap(j.TEXTURE_2D);b?j.bindTexture(j.TEXTURE_CUBE_MAP,null):j.bindTexture(j.TEXTURE_2D,null);j.bindRenderbuffer(j.RENDERBUFFER, -null);j.bindFramebuffer(j.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Db,a=nb,d=na,e=Ya);b!==Ia&&(j.bindFramebuffer(j.FRAMEBUFFER,b),j.viewport(d,e,c,a),Ia=b);kc=c;Mb=a};this.shadowMapPlugin=new THREE.ShadowMapPlugin;this.addPrePlugin(this.shadowMapPlugin);this.addPostPlugin(new THREE.SpritePlugin);this.addPostPlugin(new THREE.LensFlarePlugin)};THREE.WebGLRenderTarget=function(a,b,c){THREE.EventDispatcher.call(this);this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1); -this.format=void 0!==c.format?c.format:THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=null}; -THREE.WebGLRenderTarget.prototype.clone=function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps;a.shareDepthFrom=this.shareDepthFrom;return a}; -THREE.WebGLRenderTarget.prototype.dispose=function(){this.dispatchEvent({type:"dispose"})};THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.RenderableVertex=function(){this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.visible=!0};THREE.RenderableVertex.prototype.copy=function(a){this.positionWorld.copy(a.positionWorld);this.positionScreen.copy(a.positionScreen)};THREE.RenderableFace3=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.centroidModel=new THREE.Vector3;this.normalModel=new THREE.Vector3;this.normalModelView=new THREE.Vector3;this.vertexNormalsLength=0;this.vertexNormalsModel=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsModelView=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.material=this.color=null;this.uvs=[[]];this.z=null};THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.v4=new THREE.RenderableVertex;this.centroidModel=new THREE.Vector3;this.normalModel=new THREE.Vector3;this.normalModelView=new THREE.Vector3;this.vertexNormalsLength=0;this.vertexNormalsModel=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsModelView=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3]; -this.material=this.color=null;this.uvs=[[]];this.z=null};THREE.RenderableObject=function(){this.z=this.object=null};THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=this.object=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.material=null};THREE.ColorUtils={adjustHSV:function(a,b,c,d){var e=THREE.ColorUtils.__hsv;a.getHSV(e);e.h=THREE.Math.clamp(e.h+b,0,1);e.s=THREE.Math.clamp(e.s+c,0,1);e.v=THREE.Math.clamp(e.v+d,0,1);a.setHSV(e.h,e.s,e.v)}};THREE.ColorUtils.__hsv={h:0,s:0,v:0};THREE.GeometryUtils={merge:function(a,b){var c,d,e=a.vertices.length,f=b instanceof THREE.Mesh?b.geometry:b,g=a.vertices,i=f.vertices,h=a.faces,k=f.faces,l=a.faceVertexUvs[0],f=f.faceVertexUvs[0];b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),c=b.matrix,d=new THREE.Matrix3,d.getInverse(c),d.transpose());for(var m=0,n=i.length;ma?b(c,e-1):k[e]<=d;c++)a[c].materialIndex=b}};THREE.GeometryUtils.random=THREE.Math.random16;THREE.GeometryUtils.__v1=new THREE.Vector3;THREE.GeometryUtils.__v2=new THREE.Vector3;THREE.ImageUtils={crossOrigin:"anonymous",loadTexture:function(a,b,c,d){var e=new Image,f=new THREE.Texture(e,b),b=new THREE.ImageLoader;b.addEventListener("load",function(a){f.image=a.content;f.needsUpdate=!0;c&&c(f)});b.addEventListener("error",function(a){d&&d(a.message)});b.crossOrigin=this.crossOrigin;b.load(a,e);f.sourceFile=a;return f},loadCompressedTexture:function(a,b,c,d){var e=new THREE.CompressedTexture;e.mapping=b;var f=new XMLHttpRequest;f.onload=function(){var a=THREE.ImageUtils.parseDDS(f.response, -!0);e.format=a.format;e.mipmaps=a.mipmaps;e.image.width=a.width;e.image.height=a.height;e.generateMipmaps=!1;e.needsUpdate=!0;c&&c(e)};f.onerror=d;f.open("GET",a,!0);f.responseType="arraybuffer";f.send(null);return e},loadTextureCube:function(a,b,c,d){var e=[];e.loadCount=0;var f=new THREE.Texture;f.image=e;void 0!==b&&(f.mapping=b);f.flipY=!1;for(var b=0,g=a.length;b<<8)+(a.charCodeAt(2)<<16)+(a.charCodeAt(3)<<24)}var d={mipmaps:[],width:0,height:0,format:null,mipmapCount:1},e=c("DXT1"),f=c("DXT3"),g=c("DXT5"),i=new Int32Array(a,0,31);if(542327876!==i[0])return console.error("ImageUtils.parseDDS(): Invalid magic number in DDS header"),d;if(!i[20]&4)return console.error("ImageUtils.parseDDS(): Unsupported format, must contain a FourCC code"), -d;var h=i[21];switch(h){case e:e=8;d.format=THREE.RGB_S3TC_DXT1_Format;break;case f:e=16;d.format=THREE.RGBA_S3TC_DXT3_Format;break;case g:e=16;d.format=THREE.RGBA_S3TC_DXT5_Format;break;default:return console.error("ImageUtils.parseDDS(): Unsupported FourCC code: ",String.fromCharCode(h&255,h>>8&255,h>>16&255,h>>24&255)),d}d.mipmapCount=1;i[2]&131072&&!1!==b&&(d.mipmapCount=Math.max(1,i[7]));d.isCubemap=i[28]&512?!0:!1;d.width=i[4];d.height=i[3];for(var i=i[1]+4,f=d.width,g=d.height,h=d.isCubemap? -6:1,k=0;km-1?0:m-1,r=m+1>e-1?e-1:m+1,p=0>l-1?0:l-1,q=l+1>d-1?d-1:l+1,s=[],t=[0,0,i[4*(m*d+l)]/255*b];s.push([-1,0,i[4*(m*d+p)]/255*b]);s.push([-1,-1,i[4*(n*d+p)]/255*b]);s.push([0,-1,i[4*(n*d+l)]/255*b]);s.push([1,-1,i[4*(n*d+q)]/255*b]);s.push([1,0,i[4*(m*d+q)]/255*b]);s.push([1,1,i[4*(r*d+q)]/255*b]);s.push([0,1,i[4*(r*d+l)]/255*b]);s.push([-1,1,i[4*(r*d+p)]/255*b]);n=[];p=s.length;for(r=0;re)return null;var f=[],g=[],i=[],h,k,l;if(0=m--){console.log("Warning, unable to triangulate polygon!");break}h=k;e<=h&&(h=0);k=h+1;e<=k&&(k=0);l=k+1;e<=l&&(l=0);var n;a:{var r=n=void 0,p=void 0,q=void 0,s=void 0,t=void 0,x=void 0,z=void 0,v= -void 0,r=a[g[h]].x,p=a[g[h]].y,q=a[g[k]].x,s=a[g[k]].y,t=a[g[l]].x,x=a[g[l]].y;if(1E-10>(q-r)*(x-p)-(s-p)*(t-r))n=!1;else{var I=void 0,H=void 0,D=void 0,y=void 0,F=void 0,E=void 0,G=void 0,W=void 0,A=void 0,X=void 0,A=W=G=v=z=void 0,I=t-q,H=x-s,D=r-t,y=p-x,F=q-r,E=s-p;for(n=0;n<=A&&0<=W&&0<=G){n=!1;break a}n=!0}}if(n){f.push([a[g[h]],a[g[k]],a[g[l]]]);i.push([g[h],g[k],g[l]]); -h=k;for(l=k+1;lh)g=d+1;else if(0b&&(b=0);1d.length-2?d.length-1:a+1;c[3]=a>d.length-3?d.length-1:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,e);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,e);return b}; -THREE.EllipseCurve=function(a,b,c,d,e,f,g){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;this.aClockwise||(a=1-a);b=this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);b=this.aY+this.yRadius*Math.sin(b);return new THREE.Vector2(a,b)}; -THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype); -THREE.Curve.Utils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){var a=0.5*(c-a),d=0.5*(d-b),f=e*e;return(2*b-2*c+a+d)*e*f+(-3*b+3*c-2*a-d)*f+a*e+b}}; -THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.getPoint=b;return a};THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b}); -THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b,c;b=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);c=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);a=THREE.Shape.Utils.b2(a,this.v0.z,this.v1.z,this.v2.z);return new THREE.Vector3(b,c,a)}); -THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b,c;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);c=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);a=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return new THREE.Vector3(b,c,a)}); -THREE.SplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,e,a=(d.length-1)*a;e=Math.floor(a);a-=e;c[0]=0==e?e:e-1;c[1]=e;c[2]=e>d.length-2?d.length-1:e+1;c[3]=e>d.length-3?d.length-1:e+2;e=d[c[0]];var f=d[c[1]],g=d[c[2]],c=d[c[3]];b.x=THREE.Curve.Utils.interpolate(e.x,f.x,g.x,c.x,a);b.y=THREE.Curve.Utils.interpolate(e.y,f.y,g.y,c.y,a);b.z=THREE.Curve.Utils.interpolate(e.z,f.z,g.z,c.z,a);return b}); -THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,e;e=(d.length-0)*a;a=Math.floor(e);e-=a;a+=0=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; -THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb?b=i.x:i.xc?c=i.y:i.yd?d=i.z:i.zMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; -THREE.Path.prototype.toShapes=function(){var a,b,c,d,e=[],f=new THREE.Path;a=0;for(b=this.actions.length;a -i&&(i+=c.length);i%=c.length;0>g&&(g+=k.length);g%=k.length;e=0<=i-1?i-1:c.length-1;f=0<=g-1?g-1:k.length-1;q=[k[g],c[i],c[e]];q=THREE.FontUtils.Triangulate.area(q);s=[k[g],k[f],c[i]];s=THREE.FontUtils.Triangulate.area(s);m+n>q+s&&(i=r,g=l,0>i&&(i+=c.length),i%=c.length,0>g&&(g+=k.length),g%=k.length,e=0<=i-1?i-1:c.length-1,f=0<=g-1?g-1:k.length-1);m=c.slice(0,i);n=c.slice(i);r=k.slice(g);l=k.slice(0,g);f=[k[g],k[f],c[i]];p.push([k[g],c[i],c[e]]);p.push(f);c=m.concat(r).concat(l).concat(n)}return{shape:c, -isolatedPts:p,allpoints:d}},triangulateShape:function(a,b){var c=THREE.Shape.Utils.removeHoles(a,b),d=c.allpoints,e=c.isolatedPts,c=THREE.FontUtils.Triangulate(c.shape,!1),f,g,i,h,k={};f=0;for(g=d.length;fd;d++)h=i[d].x+":"+i[d].y,h=k[h],void 0!==h&&(i[d]=h)}f=0;for(g=e.length;fd;d++)h=i[d].x+":"+i[d].y,h=k[h],void 0!==h&&(i[d]=h)}return c.concat(e)}, -isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+ -this.b3p3(a,e)}};THREE.AnimationHandler=function(){var a=[],b={},c={update:function(b){for(var c=0;ca.hierarchy[c].keys[d].time&& -(a.hierarchy[c].keys[d].time=0),void 0!==a.hierarchy[c].keys[d].rot&&!(a.hierarchy[c].keys[d].rot instanceof THREE.Quaternion)){var i=a.hierarchy[c].keys[d].rot;a.hierarchy[c].keys[d].rot=new THREE.Quaternion(i[0],i[1],i[2],i[3])}if(a.hierarchy[c].keys.length&&void 0!==a.hierarchy[c].keys[0].morphTargets){i={};for(d=0;dr;r++){c=b[r];g=h.prevKey[c];i=h.nextKey[c];if(i.time<=l){if(k< -k;)g=i,i=this.getNextKeyWith(c,m,i.index+1)}else{this.stop();return}else{do g=i,i=this.getNextKeyWith(c,m,i.index+1);while(i.timed||1d?0:1;if("pos"===c)if(c=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+ -(f[2]-e[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)this.points[0]=this.getPrevKeyWith("pos",m,g.index-1).pos,this.points[1]=e,this.points[2]=f,this.points[3]=this.getNextKeyWith("pos",m,i.index+1).pos,d=0.33*d+0.33,e=this.interpolateCatmullRom(this.points,d),c.x=e[0],c.y=e[1],c.z=e[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(d=this.interpolateCatmullRom(this.points,1.01*d), -this.target.set(d[0],d[1],d[2]),this.target.sub(c),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0))}else"rot"===c?THREE.Quaternion.slerp(e,f,a.quaternion,d):"scl"===c&&(c=a.scale,c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+(f[2]-e[2])*d)}}}}; -THREE.Animation.prototype.interpolateCatmullRom=function(a,b){var c=[],d=[],e,f,g,i,h,k;e=(a.length-1)*b;f=Math.floor(e);e-=f;c[0]=0===f?f:f-1;c[1]=f;c[2]=f>a.length-2?f:f+1;c[3]=f>a.length-3?f:f+2;f=a[c[0]];i=a[c[1]];h=a[c[2]];k=a[c[3]];c=e*e;g=e*c;d[0]=this.interpolate(f[0],i[0],h[0],k[0],e,c,g);d[1]=this.interpolate(f[1],i[1],h[1],k[1],e,c,g);d[2]=this.interpolate(f[2],i[2],h[2],k[2],e,c,g);return d}; -THREE.Animation.prototype.interpolate=function(a,b,c,d,e,f,g){a=0.5*(c-a);d=0.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b};THREE.Animation.prototype.getNextKeyWith=function(a,b,c){for(var d=this.data.hierarchy[b].keys,c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c=g?b.interpolate(c,g):b.interpolate(c,c.time)}this.data.hierarchy[a].node.updateMatrix();d.matrixWorldNeedsUpdate=!0}}if(this.JITCompile&&void 0===f[0][e]){this.hierarchy[0].updateMatrixWorld(!0);for(a=0;a< -a){this.vertices.push(new THREE.Vector3(0,g,0));for(i=0;ig?(b=Math.atan2(b.y-a.y,b.x-a.x),a=Math.atan2(c.y-a.y,c.x-a.x),b>a&&(a+=2*Math.PI),c=(b+a)/2,a=-Math.cos(c),c=-Math.sin(c),new THREE.Vector2(a,c)):d.multiplyScalar(g).add(h).sub(a).clone()}function e(c,d){var e,f;for(J=c.length;0<=--J;){e=J;f=J-1;0>f&&(f=c.length-1);for(var g=0,h=r+2*l, -g=0;gMath.abs(c-h)?[new THREE.Vector2(b,1-e),new THREE.Vector2(d,1-f),new THREE.Vector2(k,1-g),new THREE.Vector2(m,1-a)]:[new THREE.Vector2(c,1-e),new THREE.Vector2(h,1-f),new THREE.Vector2(l,1-g),new THREE.Vector2(n,1-a)]}};THREE.ExtrudeGeometry.__v1=new THREE.Vector2;THREE.ExtrudeGeometry.__v2=new THREE.Vector2;THREE.ExtrudeGeometry.__v3=new THREE.Vector2;THREE.ExtrudeGeometry.__v4=new THREE.Vector2; -THREE.ExtrudeGeometry.__v5=new THREE.Vector2;THREE.ExtrudeGeometry.__v6=new THREE.Vector2;THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);!1===a instanceof Array&&(a=[a]);this.shapebb=a[a.length-1].getBoundingBox();this.addShapeList(a,b);this.computeCentroids();this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cd?(d=new THREE.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()]),d.centroid.add(a).add(b).add(c).divideScalar(3),d.normal=d.centroid.clone().normalize(),h.faces.push(d),d=Math.atan2(d.centroid.z,-d.centroid.x),h.faceVertexUvs[0].push([i(a.uv, -a,d),i(b.uv,b,d),i(c.uv,c,d)])):(d-=1,f(a,g(a,b),g(a,c),d),f(g(a,b),b,g(b,c),d),f(g(a,c),g(b,c),c,d),f(g(a,b),g(b,c),g(a,c),d))}function g(a,b){m[a.index]||(m[a.index]=[]);m[b.index]||(m[b.index]=[]);var c=m[a.index][b.index];void 0===c&&(m[a.index][b.index]=m[b.index][a.index]=c=e((new THREE.Vector3).addVectors(a,b).divideScalar(2)));return c}function i(a,b,c){0>c&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+0.5,a.y));return a}THREE.Geometry.call(this); -for(var c=c||1,d=d||0,h=this,k=0,l=a.length;k=l){for(k=0;3>k;k++){l=[h[k],h[(k+1)%3]];m=!0;for(n=0;ni;i++)void 0===f[g[i]]&&(f[g[i]]=e++,this.vertices.push(a[g[i]])),g[i]=f[g[i]]}for(d=0;db.y?this.rotation.set(Math.PI,0,0):(a=THREE.ArrowHelper.__v2.set(b.z,0,-b.x).normalize(),b=Math.acos(b.y),a=THREE.ArrowHelper.__q1.setFromAxisAngle(a,b),this.rotation.setEulerFromQuaternion(a,this.eulerOrder))}; -THREE.ArrowHelper.prototype.setLength=function(a){this.scale.set(a,a,a)};THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.setHex(a);this.cone.material.color.setHex(a)};THREE.ArrowHelper.__v1=new THREE.Vector3;THREE.ArrowHelper.__v2=new THREE.Vector3;THREE.ArrowHelper.__q1=new THREE.Quaternion;THREE.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.geometry.vertices.push(new THREE.Vector3);d.geometry.colors.push(new THREE.Color(b));void 0===d.pointMap[a]&&(d.pointMap[a]=[]);d.pointMap[a].push(d.geometry.vertices.length-1)}THREE.Line.call(this);var d=this;this.geometry=new THREE.Geometry;this.material=new THREE.LineBasicMaterial({color:16777215,vertexColors:THREE.FaceColors});this.type=THREE.LinePieces;this.matrixWorld=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap= -{};b("n1","n2",16755200);b("n2","n4",16755200);b("n4","n3",16755200);b("n3","n1",16755200);b("f1","f2",16755200);b("f2","f4",16755200);b("f4","f3",16755200);b("f3","f1",16755200);b("n1","f1",16755200);b("n2","f2",16755200);b("n3","f3",16755200);b("n4","f4",16755200);b("p","n1",16711680);b("p","n2",16711680);b("p","n3",16711680);b("p","n4",16711680);b("u1","u2",43775);b("u2","u3",43775);b("u3","u1",43775);b("c","t",16777215);b("p","c",3355443);b("cn1","cn2",3355443);b("cn3","cn4",3355443);b("cf1", -"cf2",3355443);b("cf3","cf4",3355443);this.camera=a;this.update(a)};THREE.CameraHelper.prototype=Object.create(THREE.Line.prototype); -THREE.CameraHelper.prototype.update=function(){function a(a,d,e,f){THREE.CameraHelper.__v.set(d,e,f);THREE.CameraHelper.__projector.unprojectVector(THREE.CameraHelper.__v,THREE.CameraHelper.__c);a=b.pointMap[a];if(void 0!==a){d=0;for(e=a.length;di.end&&(i.end=f);c||(c=h)}}for(h in d)i=d[h],this.createAnimation(h,i.start,i.end,a);this.firstAnimation=c}; -THREE.MorphBlendMesh.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};THREE.MorphBlendMesh.prototype.setAnimationFPS=function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)}; -THREE.MorphBlendMesh.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};THREE.MorphBlendMesh.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};THREE.MorphBlendMesh.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};THREE.MorphBlendMesh.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b}; -THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("animation["+a+"] undefined")};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1}; -THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.startFrame+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight; -f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);this.morphTargetInfluences[d.currentFrame]=e*g;this.morphTargetInfluences[d.lastFrame]=(1-e)*g}}};THREE.LensFlarePlugin=function(){function a(a,c){var d=b.createProgram(),e=b.createShader(b.FRAGMENT_SHADER),f=b.createShader(b.VERTEX_SHADER),g="precision "+c+" float;\n";b.shaderSource(e,g+a.fragmentShader);b.shaderSource(f,g+a.vertexShader);b.compileShader(e);b.compileShader(f);b.attachShader(d,e);b.attachShader(d,f);b.linkProgram(d);return d}var b,c,d,e,f,g,i,h,k,l,m,n,r;this.init=function(p){b=p.context;c=p;d=p.getPrecision();e=new Float32Array(16);f=new Uint16Array(6);p=0;e[p++]=-1;e[p++]=-1; -e[p++]=0;e[p++]=0;e[p++]=1;e[p++]=-1;e[p++]=1;e[p++]=0;e[p++]=1;e[p++]=1;e[p++]=1;e[p++]=1;e[p++]=-1;e[p++]=1;e[p++]=0;e[p++]=1;p=0;f[p++]=0;f[p++]=1;f[p++]=2;f[p++]=0;f[p++]=2;f[p++]=3;g=b.createBuffer();i=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,g);b.bufferData(b.ARRAY_BUFFER,e,b.STATIC_DRAW);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,i);b.bufferData(b.ELEMENT_ARRAY_BUFFER,f,b.STATIC_DRAW);h=b.createTexture();k=b.createTexture();b.bindTexture(b.TEXTURE_2D,h);b.texImage2D(b.TEXTURE_2D,0,b.RGB,16,16, -0,b.RGB,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);b.bindTexture(b.TEXTURE_2D,k);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,16,16,0,b.RGBA,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE); -b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);0>=b.getParameter(b.MAX_VERTEX_TEXTURE_IMAGE_UNITS)?(l=!1,m=a(THREE.ShaderFlares.lensFlare,d)):(l=!0,m=a(THREE.ShaderFlares.lensFlareVertexTexture,d));n={};r={};n.vertex=b.getAttribLocation(m,"position");n.uv=b.getAttribLocation(m,"uv");r.renderType=b.getUniformLocation(m,"renderType");r.map=b.getUniformLocation(m,"map");r.occlusionMap=b.getUniformLocation(m,"occlusionMap");r.opacity= -b.getUniformLocation(m,"opacity");r.color=b.getUniformLocation(m,"color");r.scale=b.getUniformLocation(m,"scale");r.rotation=b.getUniformLocation(m,"rotation");r.screenPosition=b.getUniformLocation(m,"screenPosition")};this.render=function(a,d,e,f){var a=a.__webglFlares,x=a.length;if(x){var z=new THREE.Vector3,v=f/e,I=0.5*e,H=0.5*f,D=16/f,y=new THREE.Vector2(D*v,D),F=new THREE.Vector3(1,1,0),E=new THREE.Vector2(1,1),G=r,D=n;b.useProgram(m);b.enableVertexAttribArray(n.vertex);b.enableVertexAttribArray(n.uv); -b.uniform1i(G.occlusionMap,0);b.uniform1i(G.map,1);b.bindBuffer(b.ARRAY_BUFFER,g);b.vertexAttribPointer(D.vertex,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(D.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,i);b.disable(b.CULL_FACE);b.depthMask(!1);var W,A,X,B,K;for(W=0;WD;D++)z[D]=new THREE.Vector3,t[D]=new THREE.Vector3;z=v.shadowCascadeNearZ[x];v=v.shadowCascadeFarZ[x];t[0].set(-1,-1,z);t[1].set(1,-1,z);t[2].set(-1, -1,z);t[3].set(1,1,z);t[4].set(-1,-1,v);t[5].set(1,-1,v);t[6].set(-1,1,v);t[7].set(1,1,v);H.originalCamera=m;t=new THREE.Gyroscope;t.position=p.shadowCascadeOffset;t.add(H);t.add(H.target);m.add(t);p.shadowCascadeArray[s]=H;console.log("Created virtualLight",H)}x=p;z=s;v=x.shadowCascadeArray[z];v.position.copy(x.position);v.target.position.copy(x.target.position);v.lookAt(v.target);v.shadowCameraVisible=x.shadowCameraVisible;v.shadowDarkness=x.shadowDarkness;v.shadowBias=x.shadowCascadeBias[z];t=x.shadowCascadeNearZ[z]; -x=x.shadowCascadeFarZ[z];v=v.pointsFrustum;v[0].z=t;v[1].z=t;v[2].z=t;v[3].z=t;v[4].z=x;v[5].z=x;v[6].z=x;v[7].z=x;I[q]=H;q++}else I[q]=p,q++;n=0;for(r=I.length;nx;x++)z=v[x],z.copy(t[x]),THREE.ShadowMapPlugin.__projector.unprojectVector(z,s),z.applyMatrix4(q.matrixWorldInverse),z.xk.x&&(k.x=z.x),z.yk.y&&(k.y=z.y),z.zk.z&& -(k.z=z.z);q.left=h.x;q.right=k.x;q.top=k.y;q.bottom=h.y;q.updateProjectionMatrix()}q=p.shadowMap;t=p.shadowMatrix;s=p.shadowCamera;s.position.copy(p.matrixWorld.getPosition());s.lookAt(p.target.matrixWorld.getPosition());s.updateMatrixWorld();s.matrixWorldInverse.getInverse(s.matrixWorld);p.cameraHelper&&(p.cameraHelper.visible=p.shadowCameraVisible);p.shadowCameraVisible&&p.cameraHelper.update();t.set(0.5,0,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0,1);t.multiply(s.projectionMatrix);t.multiply(s.matrixWorldInverse); -i.multiplyMatrices(s.projectionMatrix,s.matrixWorldInverse);g.setFromMatrix(i);b.setRenderTarget(q);b.clear();v=l.__webglObjects;p=0;for(q=v.length;p< alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}}; +new q).copy(this.normal).multiplyScalar(c)},intersectLine:function(){var a=new q;return function(b,c){var d=c||new q,e=b.delta(a),f=this.normal.dot(e);if(0===f){if(0===this.distanceToPoint(b.start))return d.copy(b.start)}else return f=-(b.start.dot(this.normal)+this.constant)/f,0>f||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],m=c[7],l=c[8],n=c[9],p=c[10],r=c[11],q=c[12],t=c[13],D=c[14],c=c[15]; +b[0].setComponents(f-a,m-g,r-l,c-q).normalize();b[1].setComponents(f+a,m+g,r+l,c+q).normalize();b[2].setComponents(f+d,m+h,r+n,c+t).normalize();b[3].setComponents(f-d,m-h,r-n,c-t).normalize();b[4].setComponents(f-e,m-k,r-p,c-D).normalize();b[5].setComponents(f+e,m+k,r+p,c+D).normalize();return this},intersectsObject:function(){var a=new Ca;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(), +intersectsSprite:function(){var a=new Ca;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}};ab.prototype={constructor:ab,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin); +this.direction.copy(a.direction);return this},at:function(a,b){return(b||new q).copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(){var a=new q;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){var c=b||new q;c.subVectors(a,this.origin);var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)}, +distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new q;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a=new q,b=new q,c=new q;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a); +var h=.5*d.distanceTo(e),k=-this.direction.dot(b),m=c.dot(this.direction),l=-c.dot(b),n=c.lengthSq(),p=Math.abs(1-k*k),r;0<=d?e>=-r?e<=r?(h=1/p,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*l)+n):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+n):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+n):e<=-r?(d=Math.max(0,-(-k*h+m)),e=0<=r?(d=0,e=Math.min(Math.max(-h,-l),h),k=e*(e+2*l)+n):(d=Math.max(0,-(k*h+m)),e=0f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceToPoint(a.center)<= +a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z; +var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(f<=g?(e=(a.min.z-h.z)*g,g*=a.max.z-h.z):(e=(a.max.z-h.z)*g,g*=a.min.z-h.z);if(c>g||e>d)return null;if(e>c||c!==c)c=e;if(gd?null:this.at(0<=c?c:d,b)},intersectsBox:function(){var a=new q;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a= +new q,b=new q,c=new q,d=new q;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.direction.add(this.origin).applyMatrix4(a);this.origin.applyMatrix4(a); +this.direction.sub(this.origin);this.direction.normalize();return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}};bb.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");bb.DefaultOrder="XYZ";bb.prototype={constructor:bb,isEuler:!0,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order}, +set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=T.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],m=e[9],l=e[2],n=e[6],e=e[10];b=b|| +this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-l,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.99999>Math.abs(n)?(this._y=Math.atan2(-l,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(l,-1,1)),.99999> +Math.abs(l)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-l,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(n,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback(); +return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new J);a.makeRotationFromQuaternion(b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new ba;return function(b){a.setFromEuler(this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1]; +this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new q(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};Yc.prototype={constructor:Yc,set:function(a){this.mask=1<<<<<=b.x&&0<=b.y&&1>=b.x+b.y}}();wa.prototype={constructor:wa,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c); +return this},area:function(){var a=new q,b=new q;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a||new q).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return wa.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new va).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return wa.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return wa.containsPoint(a, +this.a,this.b,this.c)},closestPointToPoint:function(){var a,b,c,d;return function(e,f){void 0===a&&(a=new va,b=[new gb,new gb,new gb],c=new q,d=new q);var g=f||new q,h=Infinity;a.setFromCoplanarPoints(this.a,this.b,this.c);a.projectPoint(e,c);if(!0===this.containsPoint(c))g.copy(c);else{b[0].set(this.a,this.b);b[1].set(this.b,this.c);b[2].set(this.c,this.a);for(var k=0;kd;d++)if(e[d]===e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;c<<b.far?null:{distance:c,point:u.clone(),object:a}}function c(c,d,e,f,m,l,n,w){g.fromArray(f,3*l);h.fromArray(f,3*n);k.fromArray(f, +3*w);if(c=b(c,d,e,g,h,k,D))m&&(p.fromArray(m,2*l),r.fromArray(m,2*n),x.fromArray(m,2*w),c.uv=a(D,g,h,k,p,r,x)),c.face=new ea(l,n,w,wa.normal(g,h,k)),c.faceIndex=l;return c}var d=new J,e=new ab,f=new Ca,g=new q,h=new q,k=new q,m=new q,l=new q,n=new q,p=new B,r=new B,x=new B,t=new q,D=new q,u=new q;return function(q,t){var u=this.geometry,E=this.material,H=this.matrixWorld;if(void 0!==E&&(null===u.boundingSphere&&u.computeBoundingSphere(),f.copy(u.boundingSphere),f.applyMatrix4(H),!1!==q.ray.intersectsSphere(f)&& +(d.getInverse(H),e.copy(q.ray).applyMatrix4(d),null===u.boundingBox||!1!==e.intersectsBox(u.boundingBox)))){var F,M;if(u&&u.isBufferGeometry){var B,K,E=u.index,H=u.attributes,u=H.position.array;void 0!==H.uv&&(F=H.uv.array);if(null!==E)for(var H=E.array,z=0,C=H.length;zthis.scale.x*this.scale.y/4||c.push({distance:Math.sqrt(d),point:this.position, +face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)}});rc.prototype=Object.assign(Object.create(z.prototype),{constructor:rc,copy:function(a){z.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=d[e].distance)d[e- +1].object.visible=!1,d[e].object.visible=!0;else break;for(;ef||(l.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(l),td.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else for(g=0,x=r.length/3-1;gf||(l.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(l),td.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld), +index:g,face:null,faceIndex:null,object:this}))}else if(g&&g.isGeometry)for(k=g.vertices,m=k.length,g=0;gf||(l.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(l),td.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});la.prototype=Object.assign(Object.create(Ta.prototype), +{constructor:la,isLineSegments:!0});xa.prototype=Object.create(U.prototype);xa.prototype.constructor=xa;xa.prototype.isPointsMaterial=!0;xa.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.size=a.size;this.sizeAttenuation=a.sizeAttenuation;return this};Kb.prototype=Object.assign(Object.create(z.prototype),{constructor:Kb,isPoints:!0,raycast:function(){var a=new J,b=new ab,c=new Ca;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a); +if(fd.far||e.push({distance:m,distanceToRay:Math.sqrt(f),point:h.clone(),index:c,face:null,object:g})}}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);var m=m/((this.scale.x+this.scale.y+this.scale.z)/3), +l=m*m,m=new q;if(h&&h.isBufferGeometry){var n=h.index,h=h.attributes.position.array;if(null!==n)for(var p=n.array,n=0,r=p.length;nc)return null;var d=[],e=[],f=[],g,h,k;if(0=m--){console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()");break}g=h;c<=g&&(g=0);h=g+1;c<=h&&(h=0);k=h+1;c<=k&&(k=0);var l;a:{var n, +p,r,q,t,D,u,v;n=a[e[g]].x;p=a[e[g]].y;r=a[e[h]].x;q=a[e[h]].y;t=a[e[k]].x;D=a[e[k]].y;if(0>=(r-n)*(D-p)-(q-p)*(t-n))l=!1;else{var I,y,E,H,F,M,B,z,C,G;I=t-r;y=D-q;E=n-t;H=p-D;F=r-n;M=q-p;for(l=0;l=-Number.EPSILON&&z>=-Number.EPSILON&&B>=-Number.EPSILON)){l=!1;break a}l=!0}}if(l){d.push([a[e[g]],a[e[h]],a[e[k]]]);f.push([e[g],e[h],e[k]]);g=h;for(k=h+1;kNumber.EPSILON){if(0q||q>p)return[];k=m*l-k*n;if(0>k||k>p)return[]}else{if(0< +k||k<=p?a<=c?[b,h]:[b,m]:k>c?[]:k===c?f?[]:[g]:a<=c?[g,h]:[g,m]}function f(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0<=e&&0<=b:0<=e||0<=b):0e&&(e=d);var g=a+1;g>d&&(g=0);d=f(h[a],h[e],h[g],k[b]);if(!d)return!1;d=k.length-1;e=b-1;0>e&&(e=d);g=b+1;g>d&&(g=0);return(d=f(k[b],k[e],k[g],h[a]))?!0:!1}function d(a,b){var c,f;for(c=0;cN){console.log("Infinite Loop! Holes left:"+m.length+", Probably Hole outside Shape!");break}for(n=z;n<=l)break;B[w]=!0}if(0<=l)break}}return h}(a,b);var p=ra.triangulate(g,!1);g=0;for(h=p.length;gk;k++)l=m[k].x+":"+m[k].y,l=n[l],void 0!==l&&(m[k]=l);return p.concat()},isClockWise:function(a){return 0>ra.area(a)},b2:function(){return function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}}(),b3:function(){return function(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}}()};za.prototype=Object.create(Q.prototype);za.prototype.constructor= +za;za.prototype.addShapeList=function(a,b){for(var c=a.length,d=0;dNumber.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(d*d+g*g),h=b.x-f/k;b=b.y+e/k;g=((c.x-g/m-h)*g-(c.y+d/m-b)*d)/(e*g-f*d);d=h+e*g-a.x;e=b+f*g-a.y;f= +d*d+e*e;if(2>=f)return new B(d,e);f=Math.sqrt(f/2)}else a=!1,e>Number.EPSILON?d>Number.EPSILON&&(a=!0):e<-Number.EPSILON?d<-Number.EPSILON&&(a=!0):Math.sign(f)===Math.sign(g)&&(a=!0),a?(d=-f,f=Math.sqrt(h)):(d=e,e=f,f=Math.sqrt(h/2));return new B(d/f,e/f)}function e(a,b){var c,d;for(L=a.length;0<=--L;){c=L;d=L-1;0>d&&(d=a.length-1);var e,f=r+2*l;for(e=0;eMath.abs(b.y-c.y)?[new B(b.x,1-b.z),new B(c.x,1-c.z),new B(d.x,1-d.z),new B(e.x,1-e.z)]:[new B(b.y,1-b.z),new B(c.y,1-c.z),new B(d.y,1-d.z),new B(e.y, +1-e.z)]}};Dc.prototype=Object.create(za.prototype);Dc.prototype.constructor=Dc;mb.prototype=Object.create(G.prototype);mb.prototype.constructor=mb;Vb.prototype=Object.create(Q.prototype);Vb.prototype.constructor=Vb;Wb.prototype=Object.create(G.prototype);Wb.prototype.constructor=Wb;Ec.prototype=Object.create(Q.prototype);Ec.prototype.constructor=Ec;Fc.prototype=Object.create(Q.prototype);Fc.prototype.constructor=Fc;Xb.prototype=Object.create(G.prototype);Xb.prototype.constructor=Xb;Gc.prototype=Object.create(Q.prototype); +Gc.prototype.constructor=Gc;cb.prototype=Object.create(Q.prototype);cb.prototype.constructor=cb;cb.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),d=this.getValueSize(),this.times=ma.arraySlice(c,e,f),this.values=ma.arraySlice(this.values,e*d,f*d);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("invalid value size in track",this),a=!1);var c=this.times,b=this.values,d=c.length;0===d&&(console.error("track is empty", +this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("time is not a valid number",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("out of order keys",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ma.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("value is not a valid number",this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1, +f=a.length-1,g=1;gk.opacity&&(k.transparent=!0);c.setTextures(h);return c.parse(k)}}()};wb.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=this.handlers,c=0,d=b.length;cg;g++)p=v[k++],u=D[2*p],p=D[2*p+1],u=new B(u,p),2!==g&&c.faceVertexUvs[d][h].push(u),0!==g&&c.faceVertexUvs[d][h+1].push(u);n&&(n=3*v[k++],r.normal.set(z[n++],z[n++],z[n]),t.normal.copy(r.normal));if(x)for(d=0;4>d;d++)n=3*v[k++],x=new q(z[n++],z[n++],z[n]),2!==d&&r.vertexNormals.push(x),0!==d&&t.vertexNormals.push(x);w&&(w=v[k++],w=y[w],r.color.setHex(w),t.color.setHex(w));if(b)for(d= +0;4>d;d++)w=v[k++],w=y[w],2!==d&&r.vertexColors.push(new O(w)),0!==d&&t.vertexColors.push(new O(w));c.faces.push(r);c.faces.push(t)}else{r=new ea;r.a=v[k++];r.b=v[k++];r.c=v[k++];h&&(h=v[k++],r.materialIndex=h);h=c.faces.length;if(d)for(d=0;dg;g++)p=v[k++],u=D[2*p],p=D[2*p+1],u=new B(u,p),c.faceVertexUvs[d][h].push(u);n&&(n=3*v[k++],r.normal.set(z[n++],z[n++],z[n]));if(x)for(d=0;3>d;d++)n=3*v[k++],x=new q(z[n++],z[n++],z[n]),r.vertexNormals.push(x); +w&&(w=v[k++],r.color.setHex(y[w]));if(b)for(d=0;3>d;d++)w=v[k++],r.vertexColors.push(new O(y[w]));c.faces.push(r)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;d< +b?a.skinIndices[d+2]:0,3k)g=d+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(T.clamp(d[k-1].dot(d[k]),-1,1)),e[k].applyMatrix4(h.makeRotationAxis(g,c))),f[k].crossVectors(d[k],e[k]);if(!0===b)for(c=Math.acos(T.clamp(e[0].dot(e[a]),-1,1)),c/=a,0<=a;k++)e[k].applyMatrix4(h.makeRotationAxis(d[k],c*k)), +f[k].crossVectors(d[k],e[k]);return{tangents:d,normals:e,binormals:f}}};ia.create=function(a,b){a.prototype=Object.create(ia.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Sa.prototype=Object.create(ia.prototype);Sa.prototype.constructor=Sa;Sa.prototype.isLineCurve=!0;Sa.prototype.getPoint=function(a){if(1===a)return this.v2.clone();var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};Sa.prototype.getPointAt=function(a){return this.getPoint(a)};Sa.prototype.getTangent= +function(a){return this.v2.clone().sub(this.v1).normalize()};Oc.prototype=Object.assign(Object.create(ia.prototype),{constructor:Oc,add:function(a){this.curves.push(a)},closePath:function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new Sa(b,a))},getPoint:function(a){var b=a*this.getLength(),c=this.getCurveLengths();for(a=0;a=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null}, +getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;cc;)c+=b;for(;c>b;)c-=b;cb.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=Xc.interpolate;return new B(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a))};yb.prototype=Object.create(ia.prototype); +yb.prototype.constructor=yb;yb.prototype.getPoint=function(a){var b=ra.b3;return new B(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))};yb.prototype.getTangent=function(a){var b=Xc.tangentCubicBezier;return(new B(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))).normalize()};zb.prototype=Object.create(ia.prototype);zb.prototype.constructor=zb;zb.prototype.getPoint=function(a){var b=ra.b2;return new B(b(a,this.v0.x, +this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))};zb.prototype.getTangent=function(a){var b=Xc.tangentQuadraticBezier;return(new B(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))).normalize()};var de=Object.assign(Object.create(Oc.prototype),{fromPoints:function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;bNumber.EPSILON){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y=== +g.y){if(a.x===g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=ra.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);var g,h,k,l=[];if(1===f.length)return h=f[0],k=new Ab,k.curves=h.curves,l.push(k),l;var q=!e(f[0].getPoints()),q=a?!q:q;k=[];var n=[],p=[],r=0,x;n[r]=void 0;p[r]=[];for(var t=0,D=f.length;td&&this._mixBufferRegion(c,a,3*b,1-d,b);for(var d=b,f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d= +b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d,e){ba.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}};fa.prototype={constructor:fa,getValue:function(a,b){this.bind();this.getValue(a,b)},setValue:function(a,b){this.bind();this.setValue(a,b)},bind:function(){var a= +this.node,b=this.parsedPath,c=b.objectName,d=b.propertyName,e=b.propertyIndex;a||(this.node=a=fa.findNode(this.rootNode,b.nodeName)||this.rootNode);this.getValue=this._getValue_unavailable;this.setValue=this._setValue_unavailable;if(a){if(c){var f=b.objectIndex;switch(c){case "materials":if(!a.material){console.error(" can not bind to material as node does not have a material",this);return}if(!a.material.materials){console.error(" can not bind to material.materials as node.material does not have a materials array", +this);return}a=a.material.materials;break;case "bones":if(!a.skeleton){console.error(" can not bind to bones as node does not have a skeleton",this);return}a=a.skeleton.bones;for(c=0;c=c){var n=c++,p=b[n];d[p.uuid]=q;b[q]=p;d[l]=n;b[n]=k;k=0;for(l=f;k!==l;++k){var p=e[k],r=p[q];p[q]=p[n];p[n]=r}}}this.nCachedObjects_=c},uncache:function(a){for(var b=this._objects,c=b.length,d=this.nCachedObjects_,e=this._indicesByUUID,f=this._bindings,g=f.length,h=0,k=arguments.length;h!==k;++h){var l=arguments[h].uuid,q=e[l];if(void 0!== +q)if(delete e[l],qb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&& +(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){var b=this.timeScale,c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0],b=b*d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a;if(0===a)return b;var c=this._clip.duration,d=this.loop,e=this._loopCount;if(2200===d)a:{if(-1===e&&(this.loopCount= +0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else break a;this.clampWhenFinished?this.paused=!0:this.enabled=!1;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{d=2202===d;-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,d)):this._setEndings(0===this.repetitions,!0,d));if(b>=c||0>b){var f=Math.floor(b/c),b=b-c*f,e=e+Math.abs(f),g=this.repetitions-e;0>g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,b=0a,this._setEndings(a,!a,d)):this._setEndings(!1,!1,d),this._loopCount=e,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:f}))}if(d&&1===(e&1))return this.time=b,c-b}return this.time=b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time, +f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}};Object.assign(Ud.prototype,sa.prototype,{clipAction:function(a,b){var c=b||this._root,d=c.uuid,e="string"===typeof a?Ha.findByName(c,a):a,c=null!==e?e.uuid:a,f=this._actionsByClip[c],g=null;if(void 0!==f){g=f.actionByRoot[d];if(void 0!==g)return g;g=f.knownActions[0];null===e&&(e=g._clip)}if(null===e)return null;e=new Td(this, +e,b);this._bindAction(e,g);this._addInactiveAction(e,c,d);return e},existingAction:function(a,b){var c=b||this._root,d=c.uuid,c="string"===typeof a?Ha.findByName(c,a):a,c=this._actionsByClip[c?c.uuid:a];return void 0!==c?c.actionByRoot[d]||null:null},stopAllAction:function(){for(var a=this._actions,b=this._nActiveActions,c=this._bindings,d=this._nActiveBindings,e=this._nActiveBindings=this._nActiveActions=0;e!==b;++e)a[e].reset();for(e=0;e!==d;++e)c[e].useCount=0;return this},update:function(a){a*= +this.timeScale;for(var b=this._actions,c=this._nActiveActions,d=this.time+=a,e=Math.sign(a),f=this._accuIndex^=1,g=0;g!==c;++g){var h=b[g];h.enabled&&h._update(d,a,e,f)}a=this._bindings;b=this._nActiveBindings;for(g=0;g!==b;++g)a[g].apply(f);return this},getRoot:function(){return this._root},uncacheClip:function(a){var b=this._actions;a=a.uuid;var c=this._actionsByClip,d=c[a];if(void 0!==d){for(var d=d.knownActions,e=0,f=d.length;e!==f;++e){var g=d[e];this._deactivateAction(g);var h=g._cacheIndex, +k=b[b.length-1];g._cacheIndex=null;g._byClipCacheIndex=null;k._cacheIndex=h;b[h]=k;b.pop();this._removeInactiveBindingsForAction(g)}delete c[a]}},uncacheRoot:function(a){a=a.uuid;var b=this._actionsByClip,c;for(c in b){var d=b[c].actionByRoot[a];void 0!==d&&(this._deactivateAction(d),this._removeInactiveAction(d))}c=this._bindingsByRootAndName[a];if(void 0!==c)for(var e in c)a=c[e],a.restoreOriginalState(),this._removeInactiveBinding(a)},uncacheAction:function(a,b){var c=this.existingAction(a,b); +null!==c&&(this._deactivateAction(c),this._removeInactiveAction(c))}});Object.assign(Ud.prototype,{_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings,g=a._interpolants,h=c.uuid,k=this._bindingsByRootAndName,l=k[h];void 0===l&&(l={},k[h]=l);for(k=0;k!==e;++k){var q=d[k],n=q.name,p=l[n];if(void 0===p){p=f[k];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,h,n));continue}p=new wd(fa.create(c,n,b&&b._propertyBindings[k].binding.parsedPath), +q.ValueTypeName,q.getValueSize());++p.referenceCount;this._addInactiveBinding(p,h,n)}f[k]=p;g[k].resultBuffer=p.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, +_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length}, +get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&ah.end&&(h.end=f);c||(c=k)}}for(k in d)h=d[k],this.createAnimation(k,h.start,h.end,a);this.firstAnimation=c};na.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};na.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};na.prototype.setAnimationFPS=function(a,b){var c= +this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)};na.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};na.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};na.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};na.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b};na.prototype.getAnimationDuration= +function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};na.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("THREE.MorphBlendMesh: animation["+a+"] undefined in .playAnimation()")};na.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1};na.prototype.update=function(a){for(var b=0,c=this.animationsList.length;b +d.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.start+T.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight;f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);d.currentFrame!== +d.lastFrame?(this.morphTargetInfluences[d.currentFrame]=e*g,this.morphTargetInfluences[d.lastFrame]=(1-e)*g):this.morphTargetInfluences[d.currentFrame]=g}}};Qc.prototype=Object.create(z.prototype);Qc.prototype.constructor=Qc;Qc.prototype.isImmediateRenderObject=!0;Rc.prototype=Object.create(la.prototype);Rc.prototype.constructor=Rc;Rc.prototype.update=function(){var a=new q,b=new q,c=new Ia;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld); +var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,q=k.length;lc.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();Cb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix(); +this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};Cb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};xd.prototype=Object.create(la.prototype);xd.prototype.constructor=xd;var $d=function(){function a(){}var b=new q,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,l,n){this.init(b,c,((b-a)/e-(c-a)/ +(e+l)+(c-b)/l)*l,((c-b)/l-(d-b)/(l+n)+(d-c)/n)*l)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3*b*a};return ia.create(function(a){this.points=a||[];this.closed=!1},function(a){var g=this.points,h,k;k=g.length;2>k&&console.log("duh, you need at least 2 points");a*=k-(this.closed?0:1);h=Math.floor(a);a-=h;this.closed?h+=0h&&(h=1);1E-4>k&&(k=h);1E-4>p&&(p=h);c.initNonuniformCatmullRom(l.x,w.x,n.x,g.x,k, +h,p);d.initNonuniformCatmullRom(l.y,w.y,n.y,g.y,k,h,p);e.initNonuniformCatmullRom(l.z,w.z,n.z,g.z,k,h,p)}else"catmullrom"===this.type&&(k=void 0!==this.tension?this.tension:.5,c.initCatmullRom(l.x,w.x,n.x,g.x,k),d.initCatmullRom(l.y,w.y,n.y,g.y,k),e.initCatmullRom(l.z,w.z,n.z,g.z,k));return new q(c.calc(a),d.calc(a),e.calc(a))})}();Ee.prototype=Object.create($d.prototype);var Ef=ia.create(function(a){console.warn("THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3");this.points= +void 0===a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=Xc.interpolate;return new q(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a),c(d.z,e.z,f.z,b.z,a))}),Ff=ia.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=ra.b3;return new q(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y),b(a,this.v0.z,this.v1.z,this.v2.z, +this.v3.z))}),Gf=ia.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=ra.b2;return new q(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y),b(a,this.v0.z,this.v1.z,this.v2.z))}),Hf=ia.create(function(a,b){this.v1=a;this.v2=b},function(a){if(1===a)return this.v2.clone();var b=new q;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b});yd.prototype=Object.create(Va.prototype);yd.prototype.constructor=yd;Object.assign(mc.prototype,{center:function(a){console.warn("THREE.Box2: .center() has been renamed to .getCenter()."); +return this.getCenter(a)},empty:function(){console.warn("THREE.Box2: .empty() has been renamed to .isEmpty().");return this.isEmpty()},isIntersectionBox:function(a){console.warn("THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},size:function(a){console.warn("THREE.Box2: .size() has been renamed to .getSize().");return this.getSize(a)}});Object.assign(Ba.prototype,{center:function(a){console.warn("THREE.Box3: .center() has been renamed to .getCenter()."); +return this.getCenter(a)},empty:function(){console.warn("THREE.Box3: .empty() has been renamed to .isEmpty().");return this.isEmpty()},isIntersectionBox:function(a){console.warn("THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},isIntersectionSphere:function(a){console.warn("THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().");return this.intersectsSphere(a)},size:function(a){console.warn("THREE.Box3: .size() has been renamed to .getSize()."); +return this.getSize(a)}});Object.assign(gb.prototype,{center:function(a){console.warn("THREE.Line3: .center() has been renamed to .getCenter().");return this.getCenter(a)}});Object.assign(Ia.prototype,{multiplyVector3:function(a){console.warn("THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)},multiplyVector3Array:function(a){console.warn("THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."); +return this.applyToVector3Array(a)}});Object.assign(J.prototype,{extractPosition:function(a){console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().");return this.copyPosition(a)},setRotationFromQuaternion:function(a){console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().");return this.makeRotationFromQuaternion(a)},multiplyVector3:function(a){console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead."); +return a.applyProjection(this)},multiplyVector4:function(a){console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},multiplyVector3Array:function(a){console.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.");return this.applyToVector3Array(a)},rotateAxis:function(a){console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead."); +a.transformDirection(this)},crossVector:function(a){console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},translate:function(a){console.error("THREE.Matrix4: .translate() has been removed.")},rotateX:function(a){console.error("THREE.Matrix4: .rotateX() has been removed.")},rotateY:function(a){console.error("THREE.Matrix4: .rotateY() has been removed.")},rotateZ:function(a){console.error("THREE.Matrix4: .rotateZ() has been removed.")}, +rotateByAxis:function(a,b){console.error("THREE.Matrix4: .rotateByAxis() has been removed.")}});Object.assign(va.prototype,{isIntersectionLine:function(a){console.warn("THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().");return this.intersectsLine(a)}});Object.assign(ba.prototype,{multiplyVector3:function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)}});Object.assign(ab.prototype, +{isIntersectionBox:function(a){console.warn("THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},isIntersectionPlane:function(a){console.warn("THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().");return this.intersectsPlane(a)},isIntersectionSphere:function(a){console.warn("THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().");return this.intersectsSphere(a)}});Object.assign(Ab.prototype,{extrude:function(a){console.warn("THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead."); +return new za(this,a)},makeGeometry:function(a){console.warn("THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.");return new cb(this,a)}});Object.assign(q.prototype,{setEulerFromRotationMatrix:function(){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")}, +getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(b, +a)}});Object.assign(z.prototype,{getChildByName:function(a){console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().");return this.getObjectByName(a)},renderDepth:function(a){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},translate:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)}});Object.defineProperties(z.prototype, +{eulerOrder:{get:function(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set:function(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");this.rotation.order=a}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(a){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}}); +Object.defineProperties(rc.prototype,{objects:{get:function(){console.warn("THREE.LOD: .objects has been renamed to .levels.");return this.levels}}});Ea.prototype.setLens=function(a,b){console.warn("THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup.");void 0!==b&&(this.filmGauge=b);this.setFocalLength(a)};Object.defineProperties(pa.prototype,{onlyShadow:{set:function(a){console.warn("THREE.Light: .onlyShadow has been removed.")}},shadowCameraFov:{set:function(a){console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov."); +this.shadow.camera.fov=a}},shadowCameraLeft:{set:function(a){console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left.");this.shadow.camera.left=a}},shadowCameraRight:{set:function(a){console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right.");this.shadow.camera.right=a}},shadowCameraTop:{set:function(a){console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top.");this.shadow.camera.top=a}},shadowCameraBottom:{set:function(a){console.warn("THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom."); +this.shadow.camera.bottom=a}},shadowCameraNear:{set:function(a){console.warn("THREE.Light: .shadowCameraNear is now .shadow.camera.near.");this.shadow.camera.near=a}},shadowCameraFar:{set:function(a){console.warn("THREE.Light: .shadowCameraFar is now .shadow.camera.far.");this.shadow.camera.far=a}},shadowCameraVisible:{set:function(a){console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.")}},shadowBias:{set:function(a){console.warn("THREE.Light: .shadowBias is now .shadow.bias."); +this.shadow.bias=a}},shadowDarkness:{set:function(a){console.warn("THREE.Light: .shadowDarkness has been removed.")}},shadowMapWidth:{set:function(a){console.warn("THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.");this.shadow.mapSize.width=a}},shadowMapHeight:{set:function(a){console.warn("THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.");this.shadow.mapSize.height=a}}});Object.defineProperties(C.prototype,{length:{get:function(){console.warn("THREE.BufferAttribute: .length has been deprecated. Please use .count."); +return this.array.length}}});Object.assign(G.prototype,{addIndex:function(a){console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().");this.setIndex(a)},addDrawCall:function(a,b,c){void 0!==c&&console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.");console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup().");this.addGroup(a,b)},clearDrawCalls:function(){console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups()."); +this.clearGroups()},computeTangents:function(){console.warn("THREE.BufferGeometry: .computeTangents() has been removed.")},computeOffsets:function(){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")}});Object.defineProperties(G.prototype,{drawcalls:{get:function(){console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups.");return this.groups}},offsets:{get:function(){console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups.");return this.groups}}}); +Object.defineProperties(U.prototype,{wrapAround:{get:function(){console.warn("THREE."+this.type+": .wrapAround has been removed.")},set:function(a){console.warn("THREE."+this.type+": .wrapAround has been removed.")}},wrapRGB:{get:function(){console.warn("THREE."+this.type+": .wrapRGB has been removed.");return new O}}});Object.defineProperties(db.prototype,{metal:{get:function(){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.");return!1},set:function(a){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead")}}}); +Object.defineProperties(Fa.prototype,{derivatives:{get:function(){console.warn("THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");return this.extensions.derivatives},set:function(a){console.warn("THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");this.extensions.derivatives=a}}});sa.prototype=Object.assign(Object.create({constructor:sa,apply:function(a){console.warn("THREE.EventDispatcher: .apply is deprecated, just inherit or Object.assign the prototype to mix-in."); +Object.assign(a,this)}}),sa.prototype);Object.defineProperties(Ae.prototype,{dynamic:{set:function(a){console.warn("THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.")}},onUpdate:{value:function(){console.warn("THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.");return this}}});Object.assign(Dd.prototype,{supportsFloatTextures:function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' )."); +return this.extensions.get("OES_texture_float")},supportsHalfFloatTextures:function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return this.extensions.get("OES_texture_half_float")},supportsStandardDerivatives:function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return this.extensions.get("OES_standard_derivatives")},supportsCompressedTextureS3TC:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' )."); +return this.extensions.get("WEBGL_compressed_texture_s3tc")},supportsCompressedTexturePVRTC:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return this.extensions.get("WEBGL_compressed_texture_pvrtc")},supportsBlendMinMax:function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return this.extensions.get("EXT_blend_minmax")},supportsVertexTextures:function(){return this.capabilities.vertexTextures}, +supportsInstancedArrays:function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return this.extensions.get("ANGLE_instanced_arrays")},enableScissorTest:function(a){console.warn("THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().");this.setScissorTest(a)},initMaterial:function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")},addPrePlugin:function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}, +addPostPlugin:function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")},updateShadowMap:function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}});Object.defineProperties(Dd.prototype,{shadowMapEnabled:{get:function(){return this.shadowMap.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");this.shadowMap.enabled=a}},shadowMapType:{get:function(){return this.shadowMap.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type."); +this.shadowMap.type=a}},shadowMapCullFace:{get:function(){return this.shadowMap.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");this.shadowMap.cullFace=a}}});Object.defineProperties(pe.prototype,{cullFace:{get:function(){return this.renderReverseSided?2:1},set:function(a){a=1!==a;console.warn("WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to "+a+".");this.renderReverseSided=a}}});Object.defineProperties(Db.prototype, +{wrapS:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");return this.texture.wrapS},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");this.texture.wrapS=a}},wrapT:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");return this.texture.wrapT},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");this.texture.wrapT=a}},magFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter."); +return this.texture.magFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");this.texture.magFilter=a}},minFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");return this.texture.minFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");this.texture.minFilter=a}},anisotropy:{get:function(){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy."); +return this.texture.anisotropy},set:function(a){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");this.texture.anisotropy=a}},offset:{get:function(){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");return this.texture.offset},set:function(a){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");this.texture.offset=a}},repeat:{get:function(){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");return this.texture.repeat}, +set:function(a){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");this.texture.repeat=a}},format:{get:function(){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");return this.texture.format},set:function(a){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");this.texture.format=a}},type:{get:function(){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type.");return this.texture.type},set:function(a){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type."); +this.texture.type=a}},generateMipmaps:{get:function(){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");return this.texture.generateMipmaps},set:function(a){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");this.texture.generateMipmaps=a}}});Object.assign(dc.prototype,{load:function(a){console.warn("THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.");var b=this;(new Od).load(a,function(a){b.setBuffer(a)}); +return this}});Object.assign(Rd.prototype,{getData:function(a){console.warn("THREE.AudioAnalyser: .getData() is now .getFrequencyData().");return this.getFrequencyData()}});l.WebGLRenderTargetCube=Eb;l.WebGLRenderTarget=Db;l.WebGLRenderer=Dd;l.ShaderLib=Gb;l.UniformsLib=W;l.UniformsUtils=La;l.ShaderChunk=X;l.FogExp2=Ib;l.Fog=Jb;l.Scene=jb;l.LensFlare=Ed;l.Sprite=qc;l.LOD=rc;l.SkinnedMesh=dd;l.Skeleton=bd;l.Bone=cd;l.Mesh=ya;l.LineSegments=la;l.Line=Ta;l.Points=Kb;l.Group=sc;l.VideoTexture=ed;l.DataTexture= +lb;l.CompressedTexture=Lb;l.CubeTexture=Xa;l.CanvasTexture=fd;l.DepthTexture=tc;l.TextureIdCount=function(){return ee++};l.Texture=da;l.MaterialIdCount=function(){return oe++};l.CompressedTextureLoader=we;l.BinaryTextureLoader=Gd;l.DataTextureLoader=Gd;l.CubeTextureLoader=Hd;l.TextureLoader=gd;l.ObjectLoader=xe;l.MaterialLoader=ud;l.BufferGeometryLoader=Id;l.DefaultLoadingManager=Ga;l.LoadingManager=Fd;l.JSONLoader=Jd;l.ImageLoader=Lc;l.FontLoader=ye;l.XHRLoader=Ja;l.Loader=wb;l.Cache=ce;l.AudioLoader= +Od;l.SpotLightShadow=id;l.SpotLight=jd;l.PointLight=kd;l.HemisphereLight=hd;l.DirectionalLightShadow=ld;l.DirectionalLight=md;l.AmbientLight=nd;l.LightShadow=tb;l.Light=pa;l.StereoCamera=ze;l.PerspectiveCamera=Ea;l.OrthographicCamera=Hb;l.CubeCamera=vd;l.Camera=Z;l.AudioListener=Pd;l.PositionalAudio=Qd;l.getAudioContext=Md;l.AudioAnalyser=Rd;l.Audio=dc;l.VectorKeyframeTrack=bc;l.StringKeyframeTrack=rd;l.QuaternionKeyframeTrack=Nc;l.NumberKeyframeTrack=cc;l.ColorKeyframeTrack=td;l.BooleanKeyframeTrack= +sd;l.PropertyMixer=wd;l.PropertyBinding=fa;l.KeyframeTrack=vb;l.AnimationUtils=ma;l.AnimationObjectGroup=Sd;l.AnimationMixer=Ud;l.AnimationClip=Ha;l.Uniform=Ae;l.InstancedBufferGeometry=Bb;l.BufferGeometry=G;l.GeometryIdCount=function(){return ad++};l.Geometry=Q;l.InterleavedBufferAttribute=Vd;l.InstancedInterleavedBuffer=fc;l.InterleavedBuffer=ec;l.InstancedBufferAttribute=gc;l.DynamicBufferAttribute=function(a,b){console.warn("THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead."); +return(new C(a,b)).setDynamic(!0)};l.Float64Attribute=function(a,b){return new C(new Float64Array(a),b)};l.Float32Attribute=ha;l.Uint32Attribute=$c;l.Int32Attribute=function(a,b){return new C(new Int32Array(a),b)};l.Uint16Attribute=Zc;l.Int16Attribute=function(a,b){return new C(new Int16Array(a),b)};l.Uint8ClampedAttribute=function(a,b){return new C(new Uint8ClampedArray(a),b)};l.Uint8Attribute=function(a,b){return new C(new Uint8Array(a),b)};l.Int8Attribute=function(a,b){return new C(new Int8Array(a), +b)};l.BufferAttribute=C;l.Face3=ea;l.Object3DIdCount=function(){return qe++};l.Object3D=z;l.Raycaster=Wd;l.Layers=Yc;l.EventDispatcher=sa;l.Clock=Yd;l.QuaternionLinearInterpolant=qd;l.LinearInterpolant=Mc;l.DiscreteInterpolant=pd;l.CubicInterpolant=od;l.Interpolant=qa;l.Triangle=wa;l.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,l,w,n,p;this.initFromArray=function(a){this.points=[]; +for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+2;l=this.points[c[0]];w=this.points[c[1]];n=this.points[c[2]];p=this.points[c[3]];h=g*g;k=g*h;d.x=b(l.x,w.x,n.x,p.x,g,h,k);d.y=b(l.y,w.y,n.y,p.y,g,h,k);d.z=b(l.z,w.z,n.z,p.z,g,h,k);return d};this.getControlPointsArray=function(){var a, +b,c=this.points.length,d=[];for(a=0;a< 0.0)', + ' distordNormal = distordNormal * -1.0;', + + // Compute diffuse and specular light (use normal and eye direction) + ' vec3 diffuseLight = vec3(0.0);', + ' vec3 specularLight = vec3(0.0);', + ' sunLight(distordNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight);', + + // Compute final 3d distortion, and project it to get the mirror sampling + ' float distance = length(worldToEye);', + ' vec2 distortion = distordCoord.xy * distortionScale * sqrt(distance) * 0.07;', + ' vec3 mirrorDistord = mirrorCoord.xyz + vec3(distortion.x, distortion.y, 1.0);', + ' vec3 reflectionSample = texture2DProj(mirrorSampler, mirrorDistord).xyz;', + + // Compute other parameters as the reflectance and the water appareance + ' float theta = max(dot(eyeDirection, distordNormal), 0.0);', + ' float reflectance = 0.3 + (1.0 - 0.3) * pow((1.0 - theta), 3.0);', + ' vec3 scatter = max(0.0, dot(distordNormal, eyeDirection)) * waterColor;', + + // Compute final pixel color + ' vec3 albedo = mix(sunColor * diffuseLight * 0.3 + scatter, (vec3(0.1) + reflectionSample * 0.9 + reflectionSample * specularLight), reflectance);', + + ' vec3 outgoingLight = albedo;', + THREE.ShaderChunk[ "fog_fragment" ], + + ' gl_FragColor = vec4( outgoingLight, alpha );', + '}' + ].join('\n') + +}; + +THREE.Water = function (renderer, camera, scene, options) { + + THREE.Object3D.call(this); + this.name = 'water_' + this.id; + + function optionalParameter (value, defaultValue) { + return value !== undefined ? value : defaultValue; + }; + + options = options || {}; + + this.matrixNeedsUpdate = true; + + var width = optionalParameter(options.textureWidth, 512); + var height = optionalParameter(options.textureHeight, 512); + this.clipBias = optionalParameter(options.clipBias, -0.0001); + this.alpha = optionalParameter(options.alpha, 1.0); + this.time = optionalParameter(options.time, 0.0); + this.normalSampler = optionalParameter(options.waterNormals, null); + this.sunDirection = optionalParameter(options.sunDirection, new THREE.Vector3(0.70707, 0.70707, 0.0)); + this.sunColor = new THREE.Color(optionalParameter(options.sunColor, 0xffffff)); + this.waterColor = new THREE.Color(optionalParameter(options.waterColor, 0x7F7F7F)); + this.eye = optionalParameter(options.eye, new THREE.Vector3(0, 0, 0)); + this.distortionScale = optionalParameter(options.distortionScale, 20.0); + this.noiseScale = optionalParameter(options.noiseScale, 1.0); + this.side = optionalParameter(options.side, THREE.FrontSide); + this.fog = optionalParameter(options.fog, false); + + this.renderer = renderer; + this.scene = scene; + this.mirrorPlane = new THREE.Plane(); + this.normal = new THREE.Vector3(0, 0, 1); + this.cameraWorldPosition = new THREE.Vector3(); + this.rotationMatrix = new THREE.Matrix4(); + this.lookAtPosition = new THREE.Vector3(0, 0, -1); + this.clipPlane = new THREE.Vector4(); + + if ( camera instanceof THREE.PerspectiveCamera ) { + this.camera = camera; + } + else { + this.camera = new THREE.PerspectiveCamera(); + console.log(this.name + ': camera is not a Perspective Camera!') + } + + this.textureMatrix = new THREE.Matrix4(); + + this.mirrorCamera = this.camera.clone(); + + this.texture = new THREE.WebGLRenderTarget(width, height); + this.tempTexture = new THREE.WebGLRenderTarget(width, height); + + var mirrorShader = THREE.ShaderLib["water"]; + var mirrorUniforms = THREE.UniformsUtils.clone(mirrorShader.uniforms); + + this.material = new THREE.ShaderMaterial({ + fragmentShader: mirrorShader.fragmentShader, + vertexShader: mirrorShader.vertexShader, + uniforms: mirrorUniforms, + transparent: true, + side: this.side, + fog: this.fog + }); + + this.mesh = new THREE.Object3D(); + + this.material.uniforms.mirrorSampler.value = this.texture; + this.material.uniforms.textureMatrix.value = this.textureMatrix; + this.material.uniforms.alpha.value = this.alpha; + this.material.uniforms.time.value = this.time; + this.material.uniforms.normalSampler.value = this.normalSampler; + this.material.uniforms.sunColor.value = this.sunColor; + this.material.uniforms.waterColor.value = this.waterColor; + this.material.uniforms.sunDirection.value = this.sunDirection; + this.material.uniforms.distortionScale.value = this.distortionScale; + this.material.uniforms.noiseScale.value = this.noiseScale; + + this.material.uniforms.eye.value = this.eye; + + if ( !THREE.Math.isPowerOfTwo(width) || !THREE.Math.isPowerOfTwo(height) ) { + this.texture.generateMipmaps = false; + this.tempTexture.generateMipmaps = false; + } +}; + +THREE.Water.prototype = Object.create(THREE.Object3D.prototype); + +THREE.Water.prototype.renderWithMirror = function (otherMirror) { + + // update the mirror matrix to mirror the current view + this.updateTextureMatrix(); + this.matrixNeedsUpdate = false; + + // set the camera of the other mirror so the mirrored view is the reference view + var tempCamera = otherMirror.camera; + otherMirror.camera = this.mirrorCamera; + + // render the other mirror in temp texture + otherMirror.render(true); + + // render the current mirror + this.render(); + this.matrixNeedsUpdate = true; + + // restore material and camera of other mirror + otherMirror.camera = tempCamera; + + // restore texture matrix of other mirror + otherMirror.updateTextureMatrix(); +}; + +THREE.Water.prototype.updateTextureMatrix = function () { + if ( this.parent !== undefined ) { + this.mesh = this.parent; + } + function sign(x) { return x ? x < 0 ? -1 : 1 : 0; } + + this.updateMatrixWorld(); + this.camera.updateMatrixWorld(); + + this.cameraWorldPosition.setFromMatrixPosition(this.camera.matrixWorld); + + this.rotationMatrix.extractRotation(this.matrixWorld); + + this.normal = (new THREE.Vector3(0, 0, 1)).applyEuler(this.mesh.rotation); + var cameraPosition = this.camera.position.clone().sub( this.mesh.position ); + if ( this.normal.dot(cameraPosition) < 0 ) { + var meshNormal = (new THREE.Vector3(0, 0, 1)).applyEuler(this.mesh.rotation); + this.normal.reflect(meshNormal); + } + + var view = this.mesh.position.clone().sub(this.cameraWorldPosition); + view.reflect(this.normal).negate(); + view.add(this.mesh.position); + + this.rotationMatrix.extractRotation(this.camera.matrixWorld); + + this.lookAtPosition.set(0, 0, -1); + this.lookAtPosition.applyMatrix4(this.rotationMatrix); + this.lookAtPosition.add(this.cameraWorldPosition); + + var target = this.mesh.position.clone().sub(this.lookAtPosition); + target.reflect(this.normal).negate(); + target.add(this.mesh.position); + + this.up.set(0, -1, 0); + this.up.applyMatrix4(this.rotationMatrix); + this.up.reflect(this.normal).negate(); + + this.mirrorCamera.position.copy(view); + this.mirrorCamera.up = this.up; + this.mirrorCamera.lookAt(target); + this.mirrorCamera.aspect = this.camera.aspect; + + this.mirrorCamera.updateProjectionMatrix(); + this.mirrorCamera.updateMatrixWorld(); + this.mirrorCamera.matrixWorldInverse.getInverse(this.mirrorCamera.matrixWorld); + + // Update the texture matrix + this.textureMatrix.set(0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0); + this.textureMatrix.multiply(this.mirrorCamera.projectionMatrix); + this.textureMatrix.multiply(this.mirrorCamera.matrixWorldInverse); + + // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html + // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf + this.mirrorPlane.setFromNormalAndCoplanarPoint(this.normal, this.mesh.position); + this.mirrorPlane.applyMatrix4(this.mirrorCamera.matrixWorldInverse); + + this.clipPlane.set(this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant); + + var q = new THREE.Vector4(); + var projectionMatrix = this.mirrorCamera.projectionMatrix; + + q.x = (sign(this.clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0]; + q.y = (sign(this.clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5]; + q.z = -1.0; + q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14]; + + // Calculate the scaled plane vector + var c = new THREE.Vector4(); + c = this.clipPlane.multiplyScalar(2.0 / this.clipPlane.dot(q)); + + // Replacing the third row of the projection matrix + projectionMatrix.elements[2] = c.x; + projectionMatrix.elements[6] = c.y; + projectionMatrix.elements[10] = c.z + 1.0 - this.clipBias; + projectionMatrix.elements[14] = c.w; + + var worldCoordinates = new THREE.Vector3(); + worldCoordinates.setFromMatrixPosition(this.camera.matrixWorld); + this.eye = worldCoordinates; + this.material.uniforms.eye.value = this.eye; +}; + +THREE.Water.prototype.render = function (isTempTexture) { + + if ( this.matrixNeedsUpdate ) { + this.updateTextureMatrix(); + } + + this.matrixNeedsUpdate = true; + + // Render the mirrored view of the current scene into the target texture + if ( this.scene !== undefined && this.scene instanceof THREE.Scene ) { + // Remove the mirror texture from the scene the moment it is used as render texture + // https://github.com/jbouny/ocean/issues/7 + this.material.visible = false; + + var renderTexture = (isTempTexture !== undefined && isTempTexture)? this.tempTexture : this.texture; + this.renderer.render(this.scene, this.mirrorCamera, renderTexture, true); + + this.material.visible = true; + this.material.uniforms.mirrorSampler.value = renderTexture; + } + +}; \ No newline at end of file diff --git a/examples/binary.html b/examples/binary.html new file mode 100644 index 0000000..bd98c01 --- /dev/null +++ b/examples/binary.html @@ -0,0 +1,90 @@ + + + + jQuery Three :: OBJ Mesh + + + + + + + + + + +
+

jQuery Three

+

A 3D model loader example, loading the Dreamway Palm in binary format | next >

+
+ +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/examples/earth.html b/examples/earth.html index 5f9e9b4..22d66da 100644 --- a/examples/earth.html +++ b/examples/earth.html @@ -3,58 +3,88 @@ jQuery Three :: Earth - + + + - + +
+

jQuery Three

+

Texture of a mercator projection applied on a sphere and infinite rotation initiated with CSS | next >

+
+
- - - - -
- - - + + + + +
+ + + + + + - + + + - + \ No newline at end of file diff --git a/examples/fly.html b/examples/fly.html index 6749eb1..2f409aa 100644 --- a/examples/fly.html +++ b/examples/fly.html @@ -3,28 +3,24 @@ jQuery Three :: Fly Controls - + + + - + +
+

jQuery Three

+

A first person camera controlled with keyboard arrows and mouse for movement
The a minimal environment is dynamically generated using a Handlebars template | next >

+
+
- - - - -
- - - - + + + + + + + + + + + + - + + + + + - + + + - + \ No newline at end of file diff --git a/examples/handlebars.html b/examples/handlebars.html index 4b56c89..e88264a 100644 --- a/examples/handlebars.html +++ b/examples/handlebars.html @@ -3,28 +3,30 @@ jQuery Three :: Handlebars Template - + + + @@ -35,33 +32,41 @@
- - + +
+ - + + + + + + + + - - - - - - + + + + + + diff --git a/examples/materials.html b/examples/materials.html index 2e30d8d..05981b8 100644 --- a/examples/materials.html +++ b/examples/materials.html @@ -1,19 +1,15 @@ - -jQuery Three :: Materials + + jQuery Three :: Materials + + + - @@ -32,20 +28,28 @@
No WebGL detected
- - + +
- + + + + + + + + + diff --git a/examples/obj.html b/examples/obj.html deleted file mode 100644 index 315b7a1..0000000 --- a/examples/obj.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - jQuery Three :: OBJ Mesh - - - - - - - - -
- - - - -
- - - - - - - - - \ No newline at end of file diff --git a/examples/primitives.html b/examples/primitives.html index b08e74b..a3e2a97 100644 --- a/examples/primitives.html +++ b/examples/primitives.html @@ -1,20 +1,17 @@ - -jQuery Three :: Primitives - - - + +
+

jQuery Three

+

A skybox rendered with 6 different images, defined in the same background-image style | next >

+
+
- - - -
- - - + + + + + + + + + + - + + + - + \ No newline at end of file diff --git a/examples/skysphere.html b/examples/skysphere.html new file mode 100644 index 0000000..b456982 --- /dev/null +++ b/examples/skysphere.html @@ -0,0 +1,59 @@ + + + + jQuery Three :: Skysphere + + + + + + + + + + +
+

jQuery Three

+

A similar effect to the skybox, only now we use a sphere for geometry and a single texture | next >

+
+ +
+ + + +
+ + + + + + + + + + + + + + + + diff --git a/examples/sprite.html b/examples/sprite.html new file mode 100644 index 0000000..a23ac09 --- /dev/null +++ b/examples/sprite.html @@ -0,0 +1,142 @@ + + + + jQuery Three :: Sprite character + + + + + + + + + +
+

jQuery Three

+

Here we have a character, animated from a sprite sheet; use the controls to change the animations | next >

+
+ +
+ + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + diff --git a/examples/terrain.html b/examples/terrain.html index 6f59f99..066e6da 100644 --- a/examples/terrain.html +++ b/examples/terrain.html @@ -3,59 +3,67 @@ jQuery Three :: Heightmap Terrain - + + + - +
- - + + - -
- - - + + + + + + + + - + + + - + - \ No newline at end of file + diff --git a/examples/vr.html b/examples/vr.html new file mode 100644 index 0000000..61d7760 --- /dev/null +++ b/examples/vr.html @@ -0,0 +1,125 @@ + + + + jQuery Three :: VR shader (using FPS example) + + + + + + + + + + +
+

jQuery Three

+

The First person example, rendered with the THREE.OculusRiftEffect shader | next >

+
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + diff --git a/examples/water.html b/examples/water.html new file mode 100644 index 0000000..65ad603 --- /dev/null +++ b/examples/water.html @@ -0,0 +1,56 @@ + + + + jQuery Three :: Water Shader + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + diff --git a/lib/_end.js b/lib/_end.js deleted file mode 100644 index d764536..0000000 --- a/lib/_end.js +++ /dev/null @@ -1,12 +0,0 @@ - -// Prototype -Three.prototype.css = css; -Three.prototype.fn = fn; -//Three.prototype.fn.webgl = fn.webgl; - -//Three.prototype.utils = utils; -//Three.prototype.cssSet = cssSet; -//Three.prototype.cssSkybox = cssSkybox; - - -})); \ No newline at end of file diff --git a/lib/_start.js b/lib/_start.js deleted file mode 100644 index 74bba3b..0000000 --- a/lib/_start.js +++ /dev/null @@ -1,44 +0,0 @@ -/** -* jQuery Three() - jQuery extension with 3D methods (using Three.js) -* Created by: Makis Tracend (@tracend) -* -* Copyright © 2013 Makesites.org -* Licensed under the MIT license -* -**/ - -// RequestAnimationFrame shim - Source: http://paulirish.com/2011/requestanimationframe-for-smart-animating/ -window.requestAnimFrame = ( function( callback ) { - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function ( callback ) { - window.setTimeout( callback, 1000 / 60 ); - }; -})(); - -(function (factory) { - - "use strict"; - - var define = define || false; - var jQuery = jQuery || false; - - if (define && typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals - factory( jQuery ); - } -}(function ( jQuery ) { - -// Local variables -var css, _css; - -// Create a fn container for internal methods -var fn = { - self : function(){ return this; } - }; diff --git a/lib/animations.js b/lib/animations.js new file mode 100644 index 0000000..cea0520 --- /dev/null +++ b/lib/animations.js @@ -0,0 +1,239 @@ + +Three.prototype.animate = function( options, el ){ + //this.mesh.rotation.z = Date.now() / 1000; + + // fallbacks + options = options || {}; + el = el || this.last || false; // last processed object + // FIX: we are checking the type of the element to attach to Object3D? + if( el instanceof THREE.Mesh && el.parent instanceof THREE.Object3D ){ + el = el.parent; + } + // prerequisites + if( !el || !options.name ) return; + // create the necessary object containers + // should we be checking the type of the element to attach to Object3D? + el._animations = el._animations || {}; + el._update = el._update || updateAnimations.bind( el ); + + // pickup animation keyframes + options.keyframes = this.fn.animate.getKeyframes.call( this, options.name ); + // exit now... + if( !options.keyframes ) return; + // set the new animation + el._animations[ options.name ] = options; + // add to animate queue (once...) + var inQueue = ( typeof this.fn.animate.queue[el.uuid] !== "undefined" ); + if( !inQueue){ + this.fn.animate.queue[el.uuid] = el._update; // using uuid to be able to remove from queue later + } +}; + +// Internal + +fn.animate = { + // container for all methods to be updated + queue: {}, + + getKeyframes: function( name ){ + var keyframes = {}; + // first find the rules + var animation = findKeyframesRule( name ); + + if(!animation) return; + // parse each one of them + for(var i in animation.cssRules){ + var rule = animation.cssRules[i]; + var frame = {}; + // FIX: only rules parsed + if( !rule.keyText ) continue; + // convert percent to 1-100 number + var key = parseInt( rule.keyText, 10 ), val; + // find rotation values + frame.rotation = this.fn.css.rotate( rule.cssText ); + // find translate values + frame.translation = this.fn.css.translate( rule.cssText ); + // find scale values + frame.scale = this.fn.css.scale( rule.cssText ); + // other attributes + if( rule.cssText.search("background-position-x") > -1 ){ + frame["background-position"] = frame["background-position"] || {}; + val = rule.cssText.match(/:[\d|\s|\w]+\;/); // capture everything between : ; + if( val ) frame["background-position"].x = parseFloat(val[0].substr(1), 10); + } + if( rule.cssText.search("background-position-y") > -1 ){ + frame["background-position"] = frame["background-position"] || {}; + val = rule.cssText.match(/:[\d|\s|\w]+\;/); // capture everything between : ; + if( val ) frame["background-position"].y = parseFloat(val[0].substr(1), 10); + } + // add to the keyframes + keyframes[ key ] = frame; + } + return keyframes; + }, + + // loop through the object's animations and update the object's properties + update: function( el ){ + //console.log( this.queue ); + // loop through the queue + for( var i in this.queue ){ + // execute + this.queue[i](); + } + } + +}; + +// Helpers + +function updateAnimations(){ + // context is the individual object + //console.log( this ); + // loop through animations + for( var i in this._animations){ + var animation = this._animations[i]; + var keyframes = animation.keyframes; + // get current params + animation.start = animation.start || utils.now(); + animation.end = animation.end || ( animation.start + animation.duration ); + animation.offset = animation.offset || registerState( this ); + animation.count = animation.count || 0; + // find the right stage in the animation + var now = utils.now(); + var percent = ( ( now - animation.start) / animation.duration ) * 100; + var start = false, + end = false; + for( var key in keyframes ){ + if( key <= percent ){ + start = keyframes[ key ]; + } + if( key > percent && !end ){ + end = keyframes[ key ]; + } + } + // fallbacks + if( !start ) start = keyframes[ 0 ]; + if( !end ) end = keyframes[ 100 ]; + // apply updates + // NOTE: only linear supported for now... + // - rotate + var rot = { + x: ( typeof start.rotation.x != "undefined" && typeof end.rotation.x != "undefined" ) ? (end.rotation.x - start.rotation.x )*(percent/100) : 0, + y: ( typeof start.rotation.y != "undefined" && typeof end.rotation.y != "undefined" ) ? (end.rotation.y - start.rotation.y )*(percent/100) : 0, + z: ( typeof start.rotation.z != "undefined" && typeof end.rotation.z != "undefined" ) ? (end.rotation.z - start.rotation.z )*(percent/100) : 0 + }; + this.rotation.set( animation.offset.rotation.x+rot.x, animation.offset.rotation.y+rot.y, animation.offset.rotation.z+ rot.z); + // TBA... + // - translate + + // - scale + + // - sprites + if( this instanceof THREE.Sprite ){ + // get current sprite index + var offset = { + x: this.material.map.offset.x, + y: this.material.map.offset.y + }; + // increment + var steps = animation.easing; + var step = 100/steps; + var nextStep = ( (parseInt( percent, 10) % step) === 0 ) ? parseInt( percent, 10) / 100 : 0; // every time we return to zero we have a new step + if( nextStep ){ + // FIX: start index of steps from zero + nextStep -= 1/steps; + // find the right axis + if( typeof animation.keyframes[0]["background-position"].x !== "undefined" ){ + // - numbers go in reverse order (steps-1 to 0) + offset.x = ((steps-1)/steps)-nextStep; + } + if( typeof animation.keyframes[0]["background-position"].y !== "undefined" ){ + // - numbers go in reverse order (steps-1 to 0) + offset.y = ((steps-1)/steps)-nextStep; + } + // update sprite + this.material.map.offset.set( offset.x, offset.y ); + } + + } + // reset if reached completion + if( percent >= 100 ){ + delete animation.start; + delete animation.end; + delete animation.offset; + animation.count++; + } + // + if( animation.count == animation.repeat ){ + delete this._animations[i]; + } else { + // save animation updates + this._animations[i] = animation; + } + } +} + +// register element state +function registerState( el ){ + return { + position: { + x: el.position.x, + y: el.position.y, + z: el.position.z + }, + rotation: { + x: el.rotation.x, + y: el.rotation.y, + z: el.rotation.z + }, + scale: { + x: el.scale.x, + y: el.scale.y, + z: el.scale.z + } + }; +} + +/* + * Access and modify CSS animations @keyFrames with Javascript + * Based on : http://jsfiddle.net/russelluresti/RHhBz/2/ + * Issue : http://stackoverflow.com/questions/10342494/set-webkit-keyframes-values-using-javascript-variable + */ + + // search the CSSOM for a specific -webkit-keyframe rule +function findKeyframesRule(rule){ + // gather all stylesheets into an array + var ss = document.styleSheets; + + // loop through the stylesheets + for (var i = 0; i < ss.length; ++i) { + + // loop through all the rules + for (var j = 0; j < ss[i].cssRules.length; ++j) { + + // find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule + if (ss[i].cssRules[j].type == window.CSSRule.WEBKIT_KEYFRAMES_RULE && ss[i].cssRules[j].name == rule) + return ss[i].cssRules[j]; + } + } + + // rule not found + return null; +} + +// remove old keyframes and add new ones +function changeAnimationKeyframes(anim){ + // find our -webkit-keyframe rule + var keyframes = findKeyframesRule(anim); + + // remove the existing 0% and 100% rules + keyframes.deleteRule("0%"); + keyframes.deleteRule("100%"); + + // create new 0% and 100% rules with random numbers + keyframes.insertRule("0% { -webkit-transform: rotate("+randomFromTo(-360,360)+"deg); }"); + keyframes.insertRule("100% { -webkit-transform: rotate("+randomFromTo(-360,360)+"deg); }"); + + // assign the animation to our element (which will cause the animation to run) + document.getElementById('box').style.webkitAnimationName = anim; +} \ No newline at end of file diff --git a/lib/attributes.js b/lib/attributes.js index c442fb7..7ea1379 100644 --- a/lib/attributes.js +++ b/lib/attributes.js @@ -1,19 +1,23 @@ // get attributes from tags Three.prototype.getAttributes = function( html ){ - // + // var data={}; // filter only the ones with the data- prefix $(html).each(function(){ - + var attr = this.attributes; - + for( var i in attr ){ if( attr[i].name && attr[i].name.search("data-") === 0 ){ var key = attr[i].name.replace("data-", ""); + // #47 convert dashed to camelCase + key = utils.camelCase( key ); var val = attr[i].value; // check if it's a number... - data[key] = ( parseInt(val, 10) ) ? parseInt(val, 10) : val; + data[key] = ( parseInt(val, 10) || val === "0" ) ? parseInt(val, 10) : val; + // convert boolean + if( data[key] === "false" || data[key] === "true" ) data[key] = JSON.parse( data[key] ); } else if( attr[i].name && attr[i].name.search("class") === 0 ){ // add classes var classes = attr[i].value.split(" "); @@ -26,21 +30,21 @@ Three.prototype.getAttributes = function( html ){ data.style = attr[i].value; } } - + }); - + return data; }; - + // add a class Three.prototype.addClass = function( name ){ var object = this.last; - // add the class to the markup - var $el = $(this.container).find("[data-id='"+ object.id +"']"); + // add the class to the markup + var $el = $(this.el).find("[data-id='"+ object.id +"']"); $el.addClass(name); - - var options = this.css( $el ); - this.fn.css.set.call( object, options ); - + // update 3d object + var options = this.fn.css.styles.call(this, $el ); + this.fn.css.set.call(this, object, options ); + return this; }; diff --git a/lib/config.js b/lib/config.js index 3903d78..43a87cf 100644 --- a/lib/config.js +++ b/lib/config.js @@ -67,7 +67,6 @@ "underscore", "backbone", "handlebars", - "showdown", "backbone.app", "jquery.three" ] diff --git a/lib/core.js b/lib/core.js index fded0c6..352bf42 100644 --- a/lib/core.js +++ b/lib/core.js @@ -1,154 +1,190 @@ var defaults = { - watch : false, + alpha: true, + clock: true, + watch: false, //deps : { "THREE" : "http://cdnjs.cloudflare.com/ajax/libs/three.js/r54/three.min.js" } - deps : { + deps: { "THREE" : "https://raw.github.com/mrdoob/three.js/master/build/three.min.js" //"FresnelShader" : "" - } - + }, + paused: false }; - - Three = function( obj, options, callback ){ - + + Three = function( element, options, callback ){ + var self = this; - this.container = obj; - this.options = $.extend(true, defaults, options); + this.el = this.setEl( element ); + this.options = $.extend(true, {}, defaults, options); // main buckets this.objects = {}; this.scenes = {}; this.cameras = {}; + this.terrains = {}; this.materials = {}; + // defining types (extandable) + this.groups = { + "camera" : "cameras", "scene" : "scenes", "terrain" : "terrains", "mesh" : "objects", "plane" : "objects", "cube" : "objects", "sphere" : "objects", "cylinder" : "objects", "material" : "materials" + }; + + // init clock + if( this.options.clock ) this.clock = new THREE.Clock(); + // #43 - calculating 'actual' framerate (use clock?) + this.frame = { + current: 0, + rate: 0, + date: new Date() + }; // pointers for objects this.last = false; this.parent = false; - + // Dependencies (replace with AMD module?) this.dependencies( function () { self.init(); // execute callback if( callback instanceof Function ) callback( self ); - + }); }; Three.prototype = { init : function() { - + var self = this; // create active object this.active = { scene: false, - camera: false, + camera: false, skybox: false }; // set properties this.properties = this.setProperties(); - + // init renderer - this.renderer = new THREE.WebGLRenderer(); + this.renderer = new THREE.WebGLRenderer({ alpha: this.options.alpha }); this.renderer.setSize( this.properties.width, this.properties.height); // condition this! this.renderer.autoClear = false; - + // #23 - remove fallback message - $(this.container).find(".fallback").remove(); + $(this.el).find(".fallback").remove(); // check if the container has (existing) markup - var html = $(this.container).html(); + var html = $(this.el).html(); // clear it off... - $(this.container).html(""); - this.parent = $(this.container).find("shadow-root"); + $(this.el).html(""); + this.parent = $(this.el).find("shadow-root"); + this.target = this.parent; this.html( html ); - + //document.body.appendChild( this.renderer.domElement ); - $( this.renderer.domElement ).appendTo( this.container ); - + $( this.renderer.domElement ).appendTo( this.el ); + // set first as active (refactor later) //this.active.scene = this.scenes[0]; //this.active.camera = this.cameras[0]; // don't set as active if it's 'hidden' //if( css.display == "none" ) return; - + // resize event listener window.addEventListener( 'resize', function(){ self.resize(); }, false ); - + // #31 - live watching DOM updates - if( this.options.watch ) this.watch(this.container); - + if( this.options.watch ) this.watch(this.parent); + this.tick(); - + }, destroy : function( ) { - + return this.each(function(){ - + var $this = $(this), three = $this.data('three'); $this.removeData('three'); - + }); - + }, - // check if the obj has a Three() class attached to it + // check if the element has a Three() class attached to it self: function(options, callback){ - + var list = []; - + this.each(function(){ - - var $this = $(this), + + var $this = $(this), three = $this.data('three'); - + // check if three has initialized for the ocntainer if ( ! three ) { three = new Three( this, options, callback); $(this).data('three', three); } - + // push the lib down the display list list.push( three ); - + }); - - // return as a jQuery object + + // return as a jQuery object // collapse the array if only one item return (list.length == 1) ? list[0] : $(list); - - }, + + }, // one cycle in an infinite loop tick : function() { - + var self = this; // update vars for objects - // - this.render(); + // + // skip render if paused + if( !this.options.paused ) this.render(); + // #43 - calculate framerate + var now = new Date(); + if( this.frame.date.getSeconds() === now.getSeconds() ){ + this.frame.current++; + } else { + // new frame, new count + this.frame.rate = this.frame.current; + this.frame.current = 1; //start from 1 to include running frame ;) + this.frame.date = now; + } // loop on the next click requestAnimFrame(function(){ self.tick(); }); - - }, + + }, render : function() { - // apply transformations - $(this.container).trigger({ - type: "update", - target: this - }); - // - + // init render if( this.active.scene && this.active.camera ){ - // render the skybox as a first pass + // resize skybox to the limits of the active camera (far attribute) if( this.active.skybox ){ - this.active.skybox.camera.rotation.copy( this.active.camera.rotation ); - this.renderer.render( this.active.skybox.scene, this.active.skybox.camera ); - + //if( this.active.skybox.camera ) this.active.skybox.camera.rotation.copy( this.active.camera.rotation ); + //this.renderer.render( this.active.skybox.scene, this.active.skybox.camera ); + var horizon = this.active.camera.far; + var scale = this.active.skybox.scale; + if( scale.x !== horizon ) + scale.x = scale.y = scale.z = horizon; + // always center around camera... + var position = this.active.camera.position; + this.active.skybox.position.set( position.x, position.y, position.z ); } + this.renderer.render( this.active.scene, this.active.camera ); } - - }, - + + // update internal animation queue + this.fn.animate.update(); + // trigger update event regardlesss + $(this.el).trigger({ + type: "update", + target: this + }); + }, + show : function( ) { }, hide : function( ) { }, update : function( content ) { }, @@ -157,58 +193,56 @@ Three.prototype = { * Inspired by Three's Detect.js * https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js */ - detect: function(){ - + detect: function(){ + return { canvas: !! window.CanvasRenderingContext2D, webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), workers: !! window.Worker, fileapi: window.File && window.FileReader && window.FileList && window.Blob, - + all: function () { return ( this.webgl && this.canvas && this.workers && this.fileapi ); } }; - }, + }, // trigger when the window is resized resize: function(){ - + // update properties this.properties = this.setProperties(); - // loop through cameras for( var i in this.cameras ){ - this.cameras[i].aspect = this.properties.aspect; this.cameras[i].updateProjectionMatrix(); - // better way of targeting skybox??? - this.active.skybox.aspect = this.properties.aspect; - this.active.skybox.updateProjectionMatrix(); - } - + // better way of targeting skybox??? + //if( this.active.skybox ){ + // this.active.skybox.camera.aspect = this.properties.aspect; + // this.active.skybox.camera.updateProjectionMatrix(); + //} this.renderer.setSize( this.properties.width, this.properties.height ); - }, - + }, + dependencies : function( callback ){ - + var scripts = $.map( this.options.deps , function (item, index) { // checking if the namespace is available if( window[index] || ( window.THREE && window.THREE[index] ) ) return; - return item; - }); - - // replace this with a proper dependency loader... + return item; + }); + + // replace this with a proper dependency loader... if( scripts.length ){ this.loadScripts(scripts, callback); } else { callback(); } - }, + }, loadScripts : function(scripts, callback){ var self = this; - + $.when( $.getScript( scripts.shift() ) ).done(function(){ if( scripts.length > 0 ){ self.loadScripts(scripts, callback); @@ -217,8 +251,18 @@ Three.prototype = { callback(); } }); + }, + + setEl: function( el ){ + // add an id if not available + var id = $(this).attr('id'); + // For some browsers, `attr` is undefined; for others `attr` is false. Check for both. + if (typeof id === "undefined" || id === false) { + $(el).addClass("3d-" + utils.unid() ); + } + return el; } - + }; @@ -227,8 +271,8 @@ $.fn.three = function( options, callback ) { // fallbacks var a = options || ( options = false ); var b = callback || ( callback = function(i){ return i; } ); - - return Three.prototype.self.apply( this, arguments, options, callback ); + + return Three.prototype.self.apply( this, arguments, options, callback ); /* if( !options) { @@ -238,7 +282,7 @@ return this.each(function(){ new Three( options ); } -} +} if ( Three[method] ) { return Three[method].apply( this, Array.prototype.slice.call( arguments, 1 )); @@ -246,6 +290,6 @@ return Three[method].apply( this, Array.prototype.slice.call( arguments, 1 )); return Three.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.Three' ); -} +} */ }; diff --git a/lib/css.js b/lib/css.js old mode 100644 new mode 100755 index 5499338..fde82e1 --- a/lib/css.js +++ b/lib/css.js @@ -2,32 +2,61 @@ // CSS // Public Methods -css = function (a){ +css = function ( styles ){ + // support more than one formats? + // for now expecting a straighforward object... + this.fn.css.set.call(this, this.last , styles); + // preserve chainability + return this; + }; + +// Internal functions +fn.css = { + styles: function (a){ var sheets = document.styleSheets, o = {}; - for(var i in sheets) { - var rules = sheets[i].rules || sheets[i].cssRules; + + // loop through stylesheets + for( var i in sheets ){ + var sheet = sheets[i]; + var isOutsideOfDomain = sheet.href && sheet.href.indexOf("/") !== 0 && sheet.href.indexOf(origin) !== 0; + // ignore sheets out-of-domain or without CSS rules + if(isOutsideOfDomain || sheet.cssRules === null) continue; + // + var rules = sheet.cssRules || sheet.rules; for(var r in rules) { // #21 - excluding :hover styles from parsing if( rules[r].selectorText && rules[r].selectorText.search(":hover") > -1) continue; - if(a.is(rules[r].selectorText)) { - o = $.extend(o, css2json(rules[r].style), css2json(a.attr('style'))); + // excluding other pseudo elements + if( rules[r].selectorText && rules[r].selectorText.search("::before") > -1) continue; + if( rules[r].selectorText && rules[r].selectorText.search("::after") > -1) continue; + try{ + if(a.is(rules[r].selectorText)) { + o = $.extend(o, css2json(rules[r].style)); + } + } catch( e ) { + console.log( e ); } } } + // add inline styles + o = $.extend(o, css2json(a.attr('style'))); + // return o; - }; - - -// Internal functions -fn.css = { - + }, set: function( object, css ){ - - if( !object ) return; - + // if the object is not valid quit... + if( !object || !object.id ) return; + for( var attr in css ){ // remove prefixes var key = attr.replace('-webkit-','').replace('-moz-',''); + // save attribute reference in the object + object._style = object._style || {}; + object._shaders = object._shaders || {}; + var changed = ( object._style[key] && object._style[key] == css[attr] ) ? false : true; // save old value? + object._style[key] = css[attr]; + // parse only changed atrributes + if( !changed ) continue; // supported attributes switch(key){ // - width @@ -55,12 +84,17 @@ fn.css = { // - color case "color": var color = this.colorToHex(css[attr]); - object.material.color.setHex(color); + if( object instanceof THREE.Scene){ + //this.fn.css.skybox.call(this, css[attr]); + this.webglLight({color : color}); + } else { + setColor( object, color ); + } break; // - transforms case "transform": var pos; - if(css[attr].search("translate3d") > -1 ){ + if(css[attr].search("translate3d") > -1 ){ pos = this.fn.css.translate.call( this, css[attr] ); // condition the position for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -69,7 +103,7 @@ fn.css = { object.position.set( pos.x, pos.y, pos.z ); } } - if(css[attr].search("rotate3d") > -1 ){ + if(css[attr].search("rotate3d") > -1 ){ pos = this.fn.css.rotate.call( this, css[attr] ); // condition the rotation for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -78,7 +112,7 @@ fn.css = { object.rotation.set( pos.x, pos.y, pos.z ); } } - if(css[attr].search("scale3d") > -1 ){ + if(css[attr].search("scale3d") > -1 ){ pos = this.fn.css.scale.call( this, css[attr] ); // condition the position for "bare" meshes if( object instanceof THREE.Mesh && object.type != "terrain"){ @@ -90,25 +124,38 @@ fn.css = { break; // - animation case "animation-duration": - console.log( key, css[attr]); + this.fn.css.animation.duration = parseInt( css[attr], 10) * 1000; // convert seconds to milliseconds break; case "animation-timing": - console.log( key, css[attr]); + this.fn.css.animation.easing = css[attr]; break; case "animation-delay": - console.log( key, css[attr]); + this.fn.css.animation.delay = css[attr]; break; case "animation-iteration-count": - console.log( key, css[attr]); + this.fn.css.animation.repeat = css[attr]; break; case "animation-direction": - console.log( key, css[attr]); + this.fn.css.animation.direction = css[attr]; break; case "animation-fill-mode": - console.log( key, css[attr]); + this.fn.css.animation.fill = css[attr]; break; case "animation-name": - console.log( key, css[attr]); + //console.log( key, css[attr]); + // assumption: name is the last animation attribute processed + this.fn.css.animation.name = css[attr]; + this.animate( this.fn.css.animation, object ); + this.fn.css.animation = {}; + break; + case "animation-timing-function": + // duplicate of animation-timing? + // if counting steps, save the number + var steps = css[attr].match(/steps\((\d)/); // not closed.. + this.fn.css.animation.easing = ( steps ) ? parseInt(steps[1], 10) : css[attr]; + break; + case "animation-play-state": + this.fn.css.animation.state = css[attr]; break; case "display": // set it as the active one... @@ -117,43 +164,134 @@ fn.css = { // background of a scene is a skydome... if( object instanceof THREE.Scene){ this.fn.css.skybox.call(this, css[attr]); - } - if( object.type == "terrain" ){ + } else if( object.type == "terrain" ){ + // make sure this get's processed on the next tick + //utils.delay( this.fn.css.terrain.bind(this), 100, css[attr] ); this.fn.css.terrain.call(this, css[attr]); - } else if ( object instanceof THREE.Mesh ) { + } else if ( object instanceof THREE.Mesh ) { this.fn.css.texture.call(this, object, css[attr]); + } else if ( object instanceof THREE.Object3D && object.children.length) { + // potentially the above condition can be removed if the ids are assigned properly in the markup... + try { + // find the child... + var mesh = object.children[0]; + this.fn.css.texture.call(this, mesh, css[attr]); + } catch( e ){ + console.log(e); + } + } else if( object instanceof THREE.Sprite ){ + var src = css[attr].replace(/\s|url\(|"|'|\)/g, ""); + object.material.map = utils.textureLoader( src ); + } + break; + case "background-size": + if( object instanceof THREE.Sprite ){ + // + this.fn.css.sprite.call(this, object, css[attr]); + } + break; + // "background-position" arrives split in axis + case "background-position-x": + if( object instanceof THREE.Sprite ){ + // update sprite + this.fn.css.sprite.call(this, object); + } + break; + case "background-position-y": + if( object instanceof THREE.Sprite ){ + // update sprite + this.fn.css.sprite.call(this, object); + } + break; + case "filter": + // variables + // - find element + var el, $el; + if( object instanceof THREE.Mesh && object.parent instanceof THREE.Object3D ){ + // parent is always an object...? + el = object.parent; + $el = object.parent.$el; + } else { + el = object; + $el = object.$el; + } + // get URLs + var urls = css[attr].replace(/url\(|"|'|\)/g, "").split('|'); // all shaders in one url? + // prerequisite + if( !urls.length ) break; + // get shaders + el._shaders = el._shaders || {}; + for( var i in urls ){ + var name = urls[i].substring(urls[i].lastIndexOf('/')+1); + el._shaders[name] = utils.getFile( urls[i] ); } + // add helper method + el.getShader = function( name ){ + return this._shaders[name] || null; + }; + // trigger event + $el.trigger('css-filter'); break; } - + } - + }, - + + // temporary container for parsed (animation) attributes... + animation: {}, + rotate: function( attr ){ - + var rot = {}; - // only supporting rotate3d for now... + var val; + // if( attr.search("rotate3d") > -1 ){ // replace all the bits we don't need - var val = attr.match(/rotate3d\(([\s\S]*?)\)/gi); + val = attr.match(/rotate3d\(([\s\S]*?)\)/gi); // match returns array... val = val[0].replace(/rotate3d\(|deg|\)| /gi, "").split(","); // first three numbers toggle axis application - fourth is the degrees rot = { - x: ( parseInt( val[0], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0, - y: ( parseInt( val[1], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0, - z: ( parseInt( val[2], 10 ) ) ? parseInt( val[3], 10 )*Math.PI/180 : 0 + x: parseFloat( val[0], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180), + y: parseFloat( val[1], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180), + z: parseFloat( val[2], 10 ) * parseFloat( val[3], 10 ) * (Math.PI/180) + }; + + } else if( attr.search("rotateX") > -1 ){ + // axis based rotation + val = attr.match(/rotateX\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateX\(|deg|\)| /gi, ""). + rot = { + x: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotateY") > -1 ){ + val = attr.match(/rotateY\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateY\(|deg|\)| /gi, ""); + rot = { + y: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotateZ") > -1 ){ + val = attr.match(/rotateZ\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotateZ\(|deg|\)| /gi, ""); + rot = { + z: parseFloat( val, 10 ) * (Math.PI/180) + }; + } else if( attr.search("rotate") > -1 ){ + val = attr.match(/rotate\(([\s\S]*?)\)/gi); + val = val[0].replace(/rotate\(|deg|\)| /gi, ""); + // if no axis is set assume Z? + rot = { + z: parseFloat( val, 10 ) * (Math.PI/180) }; - } - + return rot; - - }, - + + }, + translate: function( attr ){ - + var pos = {}; // only supporting translate3d for now... if( attr.search("translate3d") > -1 ){ @@ -163,21 +301,21 @@ fn.css = { val = val[0].replace(/translate3d\(|px|\)| /gi, "").split(","); // add the right keys pos = { - x: parseInt( val[0], 10 ) || 0, - y: parseInt( val[1], 10 ) || 0, - z: parseInt( val[2], 10 ) || 0 + x: parseFloat( val[0], 10 ) || 0, + y: parseFloat( val[1], 10 ) || 0, + z: parseFloat( val[2], 10 ) || 0 }; - + } - + return pos; - - }, - + + }, + scale: function( attr ){ - + var size = {}; - // only supporting rotate3d for now... + // only supporting scale3d for now... if( attr.search("scale3d") > -1 ){ // replace all the bits we don't need var val = attr.match(/scale3d\(([\s\S]*?)\)/gi); @@ -185,101 +323,138 @@ fn.css = { val = val[0].replace(/scale3d\(|\)| /gi, "").split(","); // first three numbers toggle axis application - fourth is the degrees size = { - x: parseInt( val[0], 10 ) || 0, - y: parseInt( val[1], 10 ) || 0, - z: parseInt( val[2], 10 ) || 0 + x: parseFloat( val[0], 10 ) || 0, + y: parseFloat( val[1], 10 ) || 0, + z: parseFloat( val[2], 10 ) || 0 }; - + } - + return size; - - }, - + + }, + texture: function( el, attr ){ - var map = attr.replace(/\s|url\(|\)/g, ""); - var material = this.webglMaterial({ map : map }); + var material; + var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); + if( img.length > 1 ){ + // shader material + // add available shaders + var uniforms = {}; + var params = {}; + var textureCube = new THREE.CubeTextureLoader().load( img ); + //var textureCube = app.layout.views.get('back').$3d.active.skybox.material.uniforms.tCube.value ); + textureCube.format = THREE.RGBFormat; + + uniforms.tCube = { + type: "t", + value: textureCube + }; + // add shaders if available + if(el._shaders){ + for( var i in el._shaders ){ + var shader = el._shaders[i]; + if( i.indexOf('.fs') > -1 ){ + params.fragmentShader = shader; + } + if( i.indexOf('.vs') > -1 ){ + params.vertexShader = shader; + } + } + } + + params.uniforms = uniforms; + params.needsUpdate = true; + + material = new THREE.ShaderMaterial( params ); + + } else { + // basic map material + material = this.webglMaterial({ map : img[0] }); + } el.material = material; - }, - + }, + terrain: function( attr ){ - var object = this.last; - - var img = attr.replace(/\s|url\(|\)/g, "").split(','); + var terrain = this.last; + //var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); + var img = attr.match(/url\(\s*[\'"]?(([^\\\\\'" \(\)]*(\\\\.)?)+)[\'"]?\s*\)/img); + // if(img instanceof Array){ + var heightmap, diffuse, specular; for( var i in img ){ - - if( img[i].search("heightmap") > -1 ){ - - var heightmapTexture = THREE.ImageUtils.loadTexture( img[i] ); - //var heightmapTexture = this.webglTexture( img[i] ); - object.material.uniforms.tDisplacement.value = heightmapTexture; - object.material.uniforms.uDisplacementScale.value = 375; - // heightmap also the second diffuse map? - var diffuseTexture2 = heightmapTexture; - diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tDiffuse2.value = diffuseTexture2; - object.material.uniforms.enableDiffuse2.value = true; - - } - if( img[i].search("diffuse") > -1 ){ - - var diffuseTexture1 = THREE.ImageUtils.loadTexture( img[i] ); - //var diffuseTexture1 = this.webglTexture( img[i] ); - diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tDiffuse1.value = diffuseTexture1; - object.material.uniforms.enableDiffuse1.value = true; - - } - if( img[i].search("specular") > -1 ){ - - var specularMap = THREE.ImageUtils.loadTexture( img[i] ); - //var specularMap = this.webglTexture( img[i] ); - specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; - - object.material.uniforms.tSpecular.value = specularMap; - object.material.uniforms.enableSpecular.value = true; - - } + // clean url(...) content + img[i] = img[i].replace(/\s|url\(|"|'|\)/g, ""); + + if( img[i].search("heightmap") > -1 ) heightmap = terrain.updateTexture('heightmap', img[i]); + + if( img[i].search("diffuse") > -1 ) diffuse = terrain.updateTexture('diffuse', img[i]); + + if( img[i].search("specular") > -1 ) specular = terrain.updateTexture('specular', img[i]); + } + // fallbacks + if(!heightmap && img[0]) terrain.updateTexture('heightmap', img[0]); + if(!diffuse && img[1]) terrain.updateTexture('diffuse', img[1]); + if(!specular && img[2]) terrain.updateTexture('specular', img[2]); + } else { - // one image... which texture is it?... + // one image... assume it's both heightmap and texture + terrain.updateTexture('heightmap', img); + terrain.updateTexture('diffuse', img); } - - /* - - leftovers ( normal and detail textures) - - //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; - - //uniformsTerrain[ "tNormal" ].value = heightmapTexture; - //uniformsTerrain[ "uNormalScale" ].value = 1; - - //uniformsTerrain[ "tDetail" ].value = detailTexture; - - //uniformsTerrain[ "uShininess" ].value = 30; - - */ - }, - - + + }, + + skybox: function( attr ){ - + // remove any whitespace, the url(..) and // attempt to break it into an array - var img = attr.replace(/\s|url\(|\)/g, "").split(','); + var img = attr.replace(/\s|url\(|"|'|\)/g, "").split(','); if(img instanceof Array){ - // expext a six-pack of images + // expect a six-pack of images this.addSkybox( img ); - + } else { // this is one image... not implemented yet } - + + }, + + sprite: function( el, attr ){ + // wait for the image to load + var loaded = setInterval(function(){ + // assume map is available... + if( !el.material.map.image || !el.material.map.image.width ) return; + // fallbacks + attr = attr || el._style["background-size"] || "0 0"; + var size = attr.split(" "); + var width = parseFloat(size[0], 10); + var height = parseFloat(size[1], 10); + // get position from style + var x = parseFloat( el._style["background-position-x"] || 0 ); + var y = parseFloat( el._style["background-position-y"] || 0 ); + + if( !width || !height ) return; + + // image dimensions + var imgWidth = el.material.map.image.width; + var imgHeight = el.material.map.image.height; + // + //el.material.uvOffset.set(1 / 5, 0); + //el.material.uvScale.set(1 / 5, 1); + el.material.map.offset.set( (imgWidth - width - x) / imgWidth, (imgHeight - height - y) / imgHeight ); // start from top left... + el.material.map.repeat.set(width / imgWidth, height / imgHeight); + //el.scale.set( width, height, 1 ); + //console.log("sprite loaded"); + // stop loop + clearInterval(loaded); + }, 200); + + } - + }; /* @@ -288,10 +463,10 @@ fn.css = { for( var attr in css ){ // supported attributes switch(attr){ - + } } - }, + }, */ @@ -311,7 +486,7 @@ var css2json = function (css){ } } } else if(typeof css == "string") { - css = css.split("; "); + css = css.split("; "); for (var j in css) { var l = css[j].split(": "); s[l[0].toLowerCase()] = (l[1]); @@ -320,3 +495,17 @@ var css2json = function (css){ return s; }; +function setColor( object, color ){ + object = object || {}; + // prerequisite + if( !object.material ) return; // create material instead? + // in case we have more than one materials + if( object.material.materials ){ + // check it it's an array first? + for(var i in object.material.materials ){ + object.material.materials[i].color.setHex(color); + } + } else { + object.material.color.setHex(color); + } +} diff --git a/lib/effects.js b/lib/effects.js index 8ef1293..e6a025e 100644 --- a/lib/effects.js +++ b/lib/effects.js @@ -1,5 +1,5 @@ -Three.prototype.animate = function(){ +Three.prototype.fx = function(){ //this.mesh.rotation.z = Date.now() / 1000; - + }; diff --git a/lib/events.js b/lib/events.js index b33d620..0d4d4e2 100644 --- a/lib/events.js +++ b/lib/events.js @@ -1,34 +1,126 @@ // watch an element for changes Three.prototype.watch = function( el ) { - // monitor new elements - $( el ).bind('DOMSubtreeModified', this.eventSubtree); + var self = this; + var selector = $( el ).selector || "shadow-root"; // fallback to main root + var element = $(this.el).toSelector() +" "+ selector; + + var node = document.getElementById("main").querySelector("shadow-root"), //$(this.el)[0], //$(element)[0], + bubbles = false; + + // shim + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + + var whatToObserve = { childList: true, attributes: true, subtree: true, attributeOldValue: true, attributeFilter: ['class', 'style']}; + //var whatToObserve = { childList: true, attributes: false, subtree: true }; + var attrObserver = new MutationObserver(function(mutationRecords) { + $.each(mutationRecords, function(index, mutationRecord) { + var e = mutationRecord; + if (mutationRecord.type === 'childList') { + if (mutationRecord.addedNodes.length > 0) { + //DOM node added, do something + //console.log("execute", mutationRecord ); + //console.log('DOMSubtreeModified', e.target.innerHTML.length, e.target ); + self.eventSubtree(e); + } else if (mutationRecord.removedNodes.length > 0) { + //DOM node removed, do something + } + } + else if (mutationRecord.type === 'attributes') { + if (mutationRecord.attributeName === 'class') { + //class changed, do something + self.eventAttribute(e); + } + } + }); + }); + + attrObserver.observe(node, whatToObserve); + + // monitor new elements + /* + $('body').on('DOMSubtreeModified', element, function(e){ + console.log(e); + self.eventSubtree(e); + }); // monitor attribute changes if (el.onpropertychange){ - $( el ).bind( 'propertychange', this.eventAttribute ); + $('body').on('propertychange', element, function(e){ + self.eventAttribute(e); + }); } else { - $( el ).bind( 'DOMAttrModified', this.eventAttribute ); + $('body').on('DOMAttrModified', element, function(e){ + self.eventAttribute(e); + }); } + */ + + var observeStyles = new MutationObserver(function (mutations) { + mutations.forEach(stylesModified); + }); + observeStyles.observe(node, { childList: false, attributes: true, subtree: true, attributeFilter: ['class', 'style'] }); + + // monitor css style changes - - + function stylesModified(mutation) { + var el = mutation.target, + name = mutation.attributeName, + newValue = mutation.target.getAttribute(name), + oldValue = mutation.oldValue; + // skip all id, data-id updates (not editable from the user) + //if( name == 'id' || name == 'data-id' ) return; + // styling updates + if( name == 'style' ){ + var object = self.objects[ el.getAttribute('data-id') ] || self.active.terrain; + var webgl = object.children[0] || object; + var css = css2json(newValue); // validate? + // HACK: why is terrain using this.last? + self.last = webgl; + self.fn.css.set.call(self, webgl, css ); + } + //console.log(name, newValue, oldValue); + } + }; // - new element Three.prototype.eventSubtree = function(e) { - - if (e.target.innerHTML.length > 0) { - // Handle new content - console.log( e.target.innerHTML ); - } + //e.stopPropagation(); // mutation event doesn't propagate? + + // variables + var $root = $( $(this.el).toSelector() +" shadow-root" ).get(0); + var $target = $(e.target).get(0); + + // don't go above the root + this.parent = ( $root == $target ) ? $(e.target) : $(e.target).parent(); + this.target = $(e.target); + + // exclude shadow-root + //if( $root == $target ) return; + // exclude empty targets + if(e.target.innerHTML.length === 0) return; + // Handle new content + //var html = e.target.innerHTML; + var html = $(e.target).html(); + //var wrapper = $(html).eq(0)[0]; + // FIX: exclude empty div tags (dead-ends) + //if( wrapper.tagName == "DIV" && + //if( wrapper.toString().substr(0, 5).toLowerCase() == "
" ) return; + // html = wrapper.childNodes[0].toString().trim(); + //this.newEl = $(e.target).children().last(); + // #46 parsing one tag at a time + //html = $(html).html("").get(0); + //this.newEl = $(html).last(); + this.append( html, { silent : true, target: this.target, traverse: false, watch: true }); + }; // - updated attribute Three.prototype.eventAttribute = function(e) { - + //e.stopPropagation(); + console.log("attribute", e.target ); - + }; // - updated style(s) - diff --git a/lib/main.js b/lib/main.js new file mode 100644 index 0000000..abf0bf4 --- /dev/null +++ b/lib/main.js @@ -0,0 +1,70 @@ +/** + * @name {{name}} + * {{description}} + * Version: {{version}} ({{build_date}}) + * + * @author {{author}} + * Created by: Makis Tracend (@tracend) + * + * Homepage: {{homepage}} + * @license {{#license licenses}}{{/license}} + */ + + +// RequestAnimationFrame shim - Source: http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +window.requestAnimFrame = ( function( callback ) { + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function ( callback ) { + window.setTimeout( callback, 1000 / 60 ); + }; +})(); + +(function (root, factory) { + + //"use strict"; + + //var define = define || false; + var jquery = root.$ || root.jQuery || root.ender; + + if (typeof define === 'function' && define.amd){ + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory( jquery ); + } + +}(this, function ( $ ) { + +// Local variables +var css, _css; +var files = {}; +var origin = location.origin || location.protocol + "//" + location.hostname + (location.port ? ":" + location.port: ""); + +// Create a fn container for internal methods +var fn = { + self : function(){ return this; } +}; + + +{{{lib}}} + + +// Prototype +Three.prototype.css = css; +Three.prototype.find = find; +Three.prototype.fn = fn; +//Three.prototype.fn.webgl = fn.webgl; +//Three.prototype.utils = utils; + +// #39 Wildcard extension - replace this hardcoding list with a proper wildcard method, once available (Proxy) +//Three.prototype.__noSuchMethod__ = fn.three; +Three.prototype.lookAt = function(){ + return this.fn.three.call(this, "lookAt", arguments); +}; + +})); diff --git a/lib/manipulation.js b/lib/manipulation.js index 589ca17..1e4ade5 100644 --- a/lib/manipulation.js +++ b/lib/manipulation.js @@ -1,213 +1,268 @@ // generic method to add an element -Three.prototype.add = function( options ){ +Three.prototype.add = function( attributes, options ){ + var self = this; + // fallbacks + options = options || {}; // use the active scene if not specified //var parent = scene || this.active.scene; // get the type from the tag name //var type = html.nodeName.toLowerCase(); // list of containers (we'll be using) - var groups = { - "camera" : "cameras", "scene" : "scenes", "mesh" : "objects", "plane" : "objects", "cube" : "objects", "sphere" : "objects", "cylinder" : "objects", "material" : "materials" - }; - var object; - + // exit if no type is specified - if( typeof options == "undefined" || typeof options.type == "undefined" ) return this; - + if( typeof attributes == "undefined" || typeof attributes.type == "undefined" ) return this; + // create 3d element - var webgl = this.webgl( options ); - // exit now if no webgl object was created (undefined condition should be removed) - if( !webgl || typeof webgl == "undefined") return this; - // add a new tag (if necessary) - //if ( options.html ){ - - // set a reference to the last el (for later) - this.last = webgl; - - // add to the relevant bucket - var container = groups[ options.type ] || false; - // create object container only for primitives... - if( container == "objects" ){ - // create new object - object = new THREE.Object3D(); - object.add(webgl); - } else { - object = webgl; - } - //this[ options.type+"s" ][0] = webgl; - // condition which elements have an active flag? - this.active[ options.type ] = object; - // - if( container ){ - // save in the objects bucket - this[container][object.id] = object; - } - // add to scene - if( options.type == "scene"){ - this.active.scene = object; - } else { - this.active.scene.add( object ); - } - // keep a reference of the object id - options["data-id"] = object.id || false; - // create the tag in the shadow dom - var $html = this.createHTML( options ); - - // apply css - var css = this.css( $html ); - this.fn.css.set.call(this, webgl, css ); - + this.webgl( attributes, function( webgl ){ + + // exit now if no webgl object was created (undefined condition should be removed) + if( !webgl || typeof webgl == "undefined") return this; + // add a new tag (if necessary) + //if ( attributes.html ){ + var object; + + // set a reference to the last el (for later) + self.last = webgl; + + // add to the relevant bucket + var container = self.groups[ attributes.type ] || false; + // create object container only for primitives... + if( container == "objects" && webgl instanceof THREE.Mesh ){ + // create new object + object = new THREE.Object3D(); + object.add(webgl); + // #40 copy name from mesh + object.name = webgl.name; + } else { + object = webgl; + } + //this[ attributes.type+"s" ][0] = webgl; + + // condition which elements have an active flag? + self.active[ attributes.type ] = object; + + // keep a reference of the object id + attributes["data-id"] = object.id || false; + + // FIX: stop now if duplicate id was generated (why?) + if( attributes.el.data('id') ) return; + + // create the tag in the shadow dom + var $html; + if( options.silent && attributes.el){ + // target should be already set? + //$html = $(self.target).find( attributes.type ); + // add data-id to existing containers + $html = attributes.el; + $html.attr("data-id" , attributes["data-id"]); + } else { + $html = self.createHTML( attributes ); + self.target = $html; + } + + // save reference of html tag in object + object.$el = $html; + + // apply css + var css = self.fn.css.styles.call(self, $html ); + self.fn.css.set.call(self, webgl, css ); + + // save in the objects bucket + if( container ){ + self[container][object.id] = object; + } + + // add to scene + if( attributes.type == "scene"){ + self.active.scene = object; + } else if( self.active.scene ){ + self.active.scene.add( object ); + } + + }); + return this; - }; - + Three.prototype.addScene = function( obj ){ - + var options = obj ||{}; - + options.type = "scene"; - + this.add(options); - + return this; - + }; - + // add camera(s) Three.prototype.addCamera = function( obj ){ - + var options = obj ||{}; - + options.type = "camera"; - + this.add(options); - + return this; - + }; - + // add meshes Three.prototype.addMesh = function( obj ){ - + var options = obj ||{}; - + options.type = "mesh"; - + this.add(options); - + return this; - + }; - + // add a plane Three.prototype.addPlane = function( obj ){ - + var options = obj ||{}; - + options.type = "plane"; - + this.add(options); - + return this; - + }; - + // add a sphere Three.prototype.addSphere = function( obj ){ - + var options = obj ||{}; - + options.type = "sphere"; - + this.add(options); - + return this; - + }; - + // add a cube Three.prototype.addCube = function( obj ){ - + var options = obj ||{}; - + options.type = "cube"; - + this.add(options); - + return this; - + }; - + // add a cylinder Three.prototype.addCylinder = function( obj ){ - + var options = obj ||{}; - + options.type = "cylinder"; - + this.add(options); - + return this; - + }; - + // add asset Three.prototype.addAsset = function( obj ){ - + var options = obj ||{}; - + options.type = "asset"; - + this.add(options); - + return this; - - }; - + + }; + Three.prototype.addSkybox = function( img ){ - - // does this camera have set values?? - var camera = new THREE.PerspectiveCamera( 50, $(this.container).width() / $(this.container).height(), 1, 100 ); - var scene = new THREE.Scene(); + //var scene = new THREE.Scene(); + var camera, geometry, material; + + if( img.length == 1){ + + //camera = new THREE.PerspectiveCamera( 50, $(this.el).width() / $(this.el).height(), 1, 1100 ); + //camera.target = new THREE.Vector3( 0, 0, 0 ); - var reflectionCube = THREE.ImageUtils.loadTextureCube( img ); - reflectionCube.format = THREE.RGBFormat; + // skysphere + geometry = new THREE.SphereGeometry( 1, 60, 40 ); + geometry.applyMatrix( new THREE.Matrix4().makeScale( -1, 1, 1 ) ); + material = new THREE.MeshBasicMaterial({ + map: utils.textureLoader( img[0] ) + }); - //var shader = THREE.ShaderUtils.lib.cube; - var shader = THREE.ShaderLib.cube; - shader.uniforms.tCube.value = reflectionCube; + } else { + // + var reflectionCube; + // skybox (with legacy support) + if(THREE.REVISION < 70){ + reflectionCube = THREE.ImageUtils.loadTextureCube( img ); + } else { + var cubeTextureLoader = new THREE.CubeTextureLoader(); + reflectionCube = cubeTextureLoader.load( img ); + } + reflectionCube.format = THREE.RGBFormat; - var material = new THREE.ShaderMaterial( { + // does this camera have set values?? + //camera = new THREE.PerspectiveCamera( 50, $(this.el).width() / $(this.el).height(), 1, 100 ); - fragmentShader: shader.fragmentShader, - vertexShader: shader.vertexShader, - uniforms: shader.uniforms, - depthWrite: false, - side: THREE.BackSide + //var shader = THREE.ShaderUtils.lib.cube; + var shader = THREE.ShaderLib.cube; + var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); + uniforms.tCube.value = reflectionCube; - }); + material = new THREE.ShaderMaterial( { + + fragmentShader: shader.fragmentShader, + vertexShader: shader.vertexShader, + uniforms: uniforms, + depthWrite: false, + side: THREE.BackSide + + }); + // the dimensions of the skybox will be resized to the limits of the active camera (far) + geometry = new THREE.BoxGeometry( 1, 1, 1 ); + } + + var mesh = new THREE.Mesh( geometry, material ); + /* + var object = new THREE.Object3D(); + object.add( mesh ); + // #40 copy name from mesh + object.name = mesh.name = "skybox"; + */ + this.active.scene.add( mesh ); - mesh = new THREE.Mesh( new THREE.CubeGeometry( 100, 100, 100 ), material ); - - scene.add( mesh ); - // save as active - this.active.skybox = { - scene : scene, - camera : camera - }; - + this.active.skybox = mesh; + //this.active.skybox = { + // scene : scene, + // camera : camera + //}; }; - + Three.prototype.addTerrain = function( obj ){ - + var options = obj ||{}; - + options.type = "terrain"; - + this.add(options); - + return this; - + }; diff --git a/lib/markup.js b/lib/markup.js index 5f88182..39240e2 100644 --- a/lib/markup.js +++ b/lib/markup.js @@ -1,59 +1,70 @@ // generic method to create an element -Three.prototype.html = function(html){ +Three.prototype.html = function(html, options){ var self = this; - + // fallbacks + options = options || {}; + options.target = options.target || this.target; + if( typeof options.traverse === "undefined") options.traverse = true; + // loop throught the elements of the dom $(html).filter('*').each(function(i, el){ - // is this a jQuery bug? + // is this a jQuery bug? var $el = (typeof el == "undefined") ? false : $(el); - + // exit if there is no parent set if( !$el ) return; - - - var options = {}; + // if there's a data id this is an attribute change we don't want to monitor + if( typeof $el.attr("data-id") !== "undefined" ) return; + + var attr = {}; // use the active scene if not specified //var parent = scene || this.active.scene; // get the type from the tag name - options.type = el.nodeName.toLowerCase(); - options.id = $el.attr("id"); - + attr.type = el.nodeName.toLowerCase(); + attr.id = $el.attr("id"); + // the set of attributes var attributes = self.getAttributes( el ); // - options = $.extend(options, attributes); - - self.add( options ); - - // loop throught the children - self.html( $el.html() ); - + attr = $.extend(attr, attributes); + + attr.el = options.target.children(":eq("+i+")"); + // if we can't find the new element quit + if( options.watch && !attr.el.length ) return; + self.add( attr, options ); + + // loop through the children (only if el not empty) + if( $el.html() !== "" && options.traverse) + self.html( $el.html(), options ); + }); - + + return this; + }; /* htmlScene : function( html ){ - + var self = this; var $scene = $(html); - //make this optional? + //make this optional? var id = $scene.attr("id"); // create a new scene this.scenes[id] = this.addScene( options ); // get css attributes var css = this.css( $scene ); this.cssScene( css ); - - // render all supported objects - - - }, + + // render all supported objects + + + }, htmlCamera : function( html ){ - + this.cameras[id] = this.addCamera( options ); - - }, + + }, */ Three.prototype.createHTML = function( options ){ // create markup @@ -67,34 +78,35 @@ Three.prototype.createHTML = function( options ){ $tag.attr("data-id", options["data-id"] ); } // add classes - if(options["class"] && options["class"].length) { + if(options["class"] && options["class"].length) { var classes = options["class"].join(" "); $tag.attr("class", classes ); } // add inline styles - if( options.style ){ + if( options.style ){ $tag.attr("style", options.style ); } // append to the dom $tag.appendTo(this.parent); - + // set as the new parent under certain conditions (for nesting)... if(options.type == "scene" || options.type == "asset" || options.type == "player"){ - this.parent = $tag; + this.parent = $tag; } - + // add listening events (if enabled) //if(this.options.watch) this.watch($tag); - + return $tag; }; -Three.prototype.append = function(html){ - +Three.prototype.append = function(html, options){ + options = options || {}; // pickup active scene //var scene = this.active.scene; // add the submitted markup (validation?) - //$(this.container).find("[data-id='"+ scene.id +"']").append( html ); - this.html( html ); - + //$(this.el).find("[data-id='"+ scene.id +"']").append( html ); + this.html( html, options ); + // #38 preserve chainability... + return this; }; \ No newline at end of file diff --git a/lib/selectors.js b/lib/selectors.js index 46fe09f..cf292b6 100644 --- a/lib/selectors.js +++ b/lib/selectors.js @@ -1,10 +1,47 @@ +// return an object using its id +Three.prototype.get = function( id ){ + + // find the element in the containers + var el = this.objects[id] || this.cameras[id] || this.scenes[id] || this.terrains[id] || null; + + return el; + +}; + + +find = function( query ){ -Three.prototype.find = function( query ){ - - var id = $(this.container).find("shadow-root "+ query).attr("data-id"); // find the element in the containers - var el = this.objects[id] || this.cameras[id] || this.scenes[id]; - - return el; + var el = this.fn.find.el.call(this, query); + // save element + this.last = el; + // preserve chainability + return this; + }; - \ No newline at end of file + + +// Internal + +fn.find = { + el : function( query ){ + + var id = $(this.el).find("shadow-root "+ query).attr("data-id"); + // find the element in the containers + var el = this.objects[id] || this.cameras[id] || this.scenes[id] || this.terrains[id] || null; + + return el; + } +}; + + +// #39 Wildcard extension to the Three.js namespace +fn.three = function(fn, query ){ + var object = this.last; + try{ + object[fn]( query ); + } catch( e ){ + console.log("Method not supported:", e ); + } + return this; +}; diff --git a/lib/terrain.js b/lib/terrain.js new file mode 100644 index 0000000..0ab63e8 --- /dev/null +++ b/lib/terrain.js @@ -0,0 +1,270 @@ + +// internal constructor for Terrain +var Terrain = function( options ){ + // prerequisites? + + // reference to the options + this.options = options; + + // binding resolution across axis + var resX = options.resolution, + resY = options.resolution; + + // in both cases the geometry is Buffer + var plane = new THREE.PlaneBufferGeometry( options.width, options.height, resX, resY ); + + // update normals after images are loaded? + plane.computeFaceNormals(); + plane.computeVertexNormals(); + //plane.computeTangents( plane ); + //THREE.BufferGeometryUtils.computeTangents( plane ); + utils.computeTangents( plane ); + + // look if we're rendering using a shader + var material = ( options.shader ) ? this.shaderMaterial() : this.basicMaterial(); + + // exit now id we didn't generate a material? + + // generate mesh + var terrain = new THREE.Mesh( plane, material ); + // needsUpdate as attribute + //terrain.geometry.attributes.normal.needsUpdate = true; + + // save type as part of the mesh + terrain.type = "terrain"; + + // save attributes + terrain._attributes = options; + + // helper methods + if( options.shader ){ + terrain.updateTexture = this.shaderTexture.bind(terrain); + } else { + terrain.computeElevation = this.computeElevation.bind(terrain); + terrain.updateTexture = this.basicTexture.bind(terrain); + } + + // save reference + this.terrain = terrain; + + return this; +}; + + +Terrain.prototype.shaderMaterial = function(){ + // prerequisites + if( !THREE.ShaderTerrain ) + return console.log("THREE.ShaderTerrain not loaded. Use data-shader='false' to generate a poly terrain"); + + var options = this.options; + var terrainShader = THREE.ShaderTerrain.terrain; + + var uniformsTerrain = THREE.UniformsUtils.clone( terrainShader.uniforms ); + + /* these are all moved to the css styling... + var heightmapTexture = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); + var diffuseTexture1 = THREE.ImageUtils.loadTexture( "assets/img/terrain/diffuse.jpg" ); + var diffuseTexture2 = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); + var specularMap = THREE.ImageUtils.loadTexture( "assets/img/terrain/specular.png"); + + diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; + diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; + //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; + specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; + + //uniformsTerrain[ "tNormal" ].value = heightmapTexture; + //uniformsTerrain[ "uNormalScale" ].value = 1; + + uniformsTerrain[ "tDisplacement" ].value = heightmapTexture; + uniformsTerrain[ "uDisplacementScale" ].value = 375; + + uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture1; + uniformsTerrain[ "tDiffuse2" ].value = diffuseTexture2; + uniformsTerrain[ "tSpecular" ].value = specularMap; + //uniformsTerrain[ "tDetail" ].value = diffuseTexture1; + + uniformsTerrain[ "enableDiffuse1" ].value = true; + uniformsTerrain[ "enableDiffuse2" ].value = true; + uniformsTerrain[ "enableSpecular" ].value = true; + + uniformsTerrain[ "uDiffuseColor" ].value.setHex( 0xffffff ); + uniformsTerrain[ "uSpecularColor" ].value.setHex( 0xffffff ); + uniformsTerrain[ "uAmbientColor" ].value.setHex( 0x111111 ); + + //uniformsTerrain[ "uShininess" ].value = 30; + */ + + // allow the terrain to emit ambient light from the scene + if( THREE.REVISION < 70 ){ + uniformsTerrain.uDiffuseColor.value.setHex( 0xffffff ); + uniformsTerrain.uSpecularColor.value.setHex( 0xffffff ); + uniformsTerrain.uAmbientColor.value.setHex( 0x111111 ); + } else { + uniformsTerrain.diffuse.value.setHex( 0xffffff ); + uniformsTerrain.specular.value.setHex( 0xffffff ); + //uniformsTerrain.ambient.value.setHex( 0x111111 ); + } + + // this should also be accessible by a background-size value (with percentage conversion) + uniformsTerrain.uRepeatOverlay.value.set( options.repeat, options.repeat ); + // + + var material = new THREE.ShaderMaterial( { + uniforms : uniformsTerrain, + vertexShader : terrainShader.vertexShader, + fragmentShader : terrainShader.fragmentShader, + lights : options.lights, + fog : options.fog, + needsUpdate: true + }); + + return material; + +}; + +Terrain.prototype.basicMaterial = function(){ + + var material = new THREE.MeshBasicMaterial( { map: utils.pixel(), overdraw: 0.5 } ); + // + return material; +}; + +// Helpers + +// Terrain helper to compute elevation from heightmap +Terrain.prototype.computeElevation = function( texture ){ + // prerequisite + if( this._attributes.shader ) return; + var terrain = this; // method binded to terrain object + + // canvas for image processing + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext("2d"); + var img = texture.image; + // canvas takes the polygon dimensions | vertices = faces +1 for every side + var width = terrain.geometry.parameters.widthSegments + 1; + var height = terrain.geometry.parameters.heightSegments + 1; + var terrainScale = terrain._attributes.scale; //terrain.material.uniforms.uDisplacementScale.value; + var terrainBias = - terrain._attributes.scale/2; //terrain.material.uniforms.uDisplacementBias.value; + var size = terrain.geometry.parameters.width; // option? + //var scale = size / width; + // - main data + var vertices = terrain.geometry.attributes.position; + var d = []; + + canvas.width = width; + canvas.height = height; + + ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height); + // scale image to polygons + //ctx.scale(width/img.width, height/img.height); // already resized from drawImage + // loop through image data + var data = ctx.getImageData(0,0, width, height).data; + + for( var i in data ){ + if ( i % 4 ) continue; // pick only every forth - item size 4: RGBA + // OLD method: calculating the whole vector + //var z = ( Math.floor(i/width) ) - (size/2); + //var x = (i - ( Math.floor(i/width)*width)) - (size/2); + //var y = (data[i]/255 * terrainScale) + terrainBias; // normalize height to a fraction + //vertices.push( new THREE.Vector3(x, y, z) ); + //vertices.push( (data[i]/255 * terrainScale) + terrainBias ); + + // updating the z axis of the vertices directly + var z = ( (data[i]/255 * terrainScale) + terrainBias ); // terrain has z axis up... + // instead combine all colors? + //var decimal = (data[i]+data[i+1]+data[i+2])/(3*255); + d.push( z ); + vertices.setZ( i/4, z ); + } + + // update the vertices in the terrain object + terrain.geometry.attributes.position.needsUpdate = true; +}; + +Terrain.prototype.shaderTexture = function(type, img){ + + var texture = utils.textureLoader( img ); //this.webglTexture( img ); + + if( type == 'heightmap' ){ + var terrainScale = this._attributes.scale; // modified through an option + + this.material.uniforms.tDisplacement.value = texture; + this.material.uniforms.uDisplacementScale.value = terrainScale; + this.material.uniforms.uDisplacementBias.value = - terrainScale/2; + // heightmap also the second diffuse map? + //var diffuseTexture2 = texture; + //diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; + //this.material.uniforms.tDiffuse2.value = diffuseTexture2; + //this.material.uniforms.enableDiffuse2.value = true; + } + if( type == 'diffuse' ){ + + texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + + this.material.uniforms.tDiffuse1.value = texture; + this.material.uniforms.enableDiffuse1.value = true; + + } + if( type == 'specular' ){ + //var texture = this.webglTexture( img ); + //texture.wrapS = texture.wrapT = THREE.RepeatWrapping; + + this.material.uniforms.tSpecular.value = texture; + this.material.uniforms.enableSpecular.value = true; + + } + // always update vertices... + // why don't these work with ShaderTerrain? + //this.geometry.attributes.position.needsUpdate = true; + //this.geometry.verticesNeedUpdate = true; + + /* + leftovers ( normal and detail textures) + + //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; + //uniformsTerrain[ "tNormal" ].value = heightmapTexture; + //uniformsTerrain[ "uNormalScale" ].value = 1; + //uniformsTerrain[ "tDetail" ].value = detailTexture; + //uniformsTerrain[ "uShininess" ].value = 30; + */ + + return texture; +}; + + +Terrain.prototype.basicTexture = function(type, img){ + var texture; + + if( type == 'heightmap' ){ + texture = utils.textureLoader( img, 'heightmap-loaded' ); + // texture isn't loaded in material, just used in computeElevation + // monitoring event + var self = this; + // remove pre-existing event... + var cb = function(e){ + self.computeElevation( texture ); + // trigger element event + self.$el.trigger('heightmap-updated'); + }; + document.removeEventListener('heightmap-loaded', cb); + document.addEventListener('heightmap-loaded', cb, false); + } + if( type == 'diffuse' ){ + texture = utils.textureLoader( img ); + var repeat = this._attributes.repeat; + // dirty re-write + texture.wrapT = THREE.RepeatWrapping; + texture.wrapS = THREE.RepeatWrapping; + texture.repeat.set( repeat, repeat ); + //texture.offset.set( 1, 1 ); + texture.needsUpdate = true; + + this.material.map = texture; + } + if( type == 'specular' ){ + // not supported? + } + + return texture; +}; diff --git a/lib/utils.js b/lib/utils.js index d1179fd..6f43186 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,25 +3,344 @@ Three.prototype.colorToHex = function (color) { return color.replace("#", "0x"); } var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color); - + var red = parseInt(digits[2], 10).toString(16); var green = parseInt(digits[3], 10).toString(16); var blue = parseInt(digits[4], 10).toString(16); - + // add leading zeros if necessary - + if(red.length == 1) red = "0"+red; if(green.length == 1) green = "0"+green; if(blue.length == 1) blue = "0"+blue; - + return '0x' + red + green + blue; }; - + Three.prototype.setProperties = function() { return { - width: $(this.container).width(), - height: $(this.container).height(), - aspect: ( $(this.container).width() / $(this.container).height() ) + width: $(this.el).width(), + height: $(this.el).height(), + aspect: ( $(this.el).width() / $(this.el).height() ) }; }; - \ No newline at end of file + + +// internal object of utilities +var utils = { + // Convert Dashed to CamelCase + // based on: https://gist.github.com/tracend/5530356 + camelCase : function( string ){ + return string.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); + }, + + // Based on undercore _.delay + delay: function (fn, timeout) { + timeout = timeout || 0; + var args = Array.prototype.slice.call(arguments, 2); + return setTimeout(function () { return fn.apply(null, args); }, timeout); + }, + + // unique (but not universal) id generator + unid: function(){ + return Math.round( Math.random() * (new Date()).getTime() ); + }, + + now: function(){ + if( !performance || !performance.now ) return new Date().getTime(); + return Math.floor( performance.now() ); // are the fractions of a millisecond significant? + }, + // returns a 1x1 invisible texture + // used when we have no texture data + pixel: function(){ + var image = document.createElement( 'img' ); + var texture = new THREE.Texture( image ); + // not neeeded? + image.addEventListener( 'load', function ( event ) { + texture.needsUpdate = true; + } ); + image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; + return texture; + }, + // texture loader (support legacy) + textureLoader: function( image, eventName ){ + var map = this.pixel(); + + if( THREE.REVISION < 70 ){ + // FIX: support base64 images + if( image.search(";base64,") > -1 ) image = image.replace(/data:image\/(png|jpg|jpeg);base64,/, ""); + map = THREE.ImageUtils.loadTexture( image ); + } else { + (new THREE.TextureLoader()).load(image, function( texture ){ + // update image source on the original map + map.image = texture.image; + map.needsUpdate = true; + // trigger event + if( eventName ){ + var event = new Event(eventName); + document.dispatchEvent( event ); + } + }); + } + // return immediantely (update asychronously) + return map; + }, + + // Convert the color information of an image to height data + // source: http://oos.moxiecode.com/js_webgl/terrain/index.html + getHeightData: function(img) { + var canvas = document.createElement( 'canvas' ); + canvas.width = 128; + canvas.height = 128; + var context = canvas.getContext( '2d' ); + + var size = 128 * 128, data = new Float32Array( size ); + + context.drawImage(img,0,0); + + for ( var i = 0; i < size; i ++ ) { + data[i] = 0; + } + + var imgd = context.getImageData(0, 0, 128, 128); + var pix = imgd.data; + + var j=0; + for (var k = 0, n = pix.length; k < n; k += (4)) { + var all = pix[k]+pix[k+1]+pix[k+2]; + data[j++] = all/30; + } + + return data; + }, + + getFile: function (url) { + // if already downloaded return the same content + if( files[url] ) return files[url]; + files[url] = $.ajax({ + type : "GET", + url : url, + dataType : "string", + async : false, + success : function(data) { + files[url] = data; + } + }).responseText; + return files[url]; + }, + + //THREE.BufferGeometryUtils + // @author mrdoob / http://mrdoob.com/ + computeTangents: function ( geometry ) { + + var index = geometry.index; + var attributes = geometry.attributes; + + // based on http://www.terathon.com/code/tangent.html + // (per vertex tangents) + + if ( index === null || + attributes.position === undefined || + attributes.normal === undefined || + attributes.uv === undefined ) { + + console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' ); + return; + + } + + var indices = index.array; + var positions = attributes.position.array; + var normals = attributes.normal.array; + var uvs = attributes.uv.array; + + var nVertices = positions.length / 3; + + if ( attributes.tangent === undefined ) { + + geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); + + } + + var tangents = attributes.tangent.array; + + var tan1 = [], tan2 = []; + + for ( var k = 0; k < nVertices; k ++ ) { + + tan1[ k ] = new THREE.Vector3(); + tan2[ k ] = new THREE.Vector3(); + + } + + var vA = new THREE.Vector3(), + vB = new THREE.Vector3(), + vC = new THREE.Vector3(), + + uvA = new THREE.Vector2(), + uvB = new THREE.Vector2(), + uvC = new THREE.Vector2(), + + sdir = new THREE.Vector3(), + tdir = new THREE.Vector3(); + + function handleTriangle( a, b, c ) { + + vA.fromArray( positions, a * 3 ); + vB.fromArray( positions, b * 3 ); + vC.fromArray( positions, c * 3 ); + + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); + + var x1 = vB.x - vA.x; + var x2 = vC.x - vA.x; + + var y1 = vB.y - vA.y; + var y2 = vC.y - vA.y; + + var z1 = vB.z - vA.z; + var z2 = vC.z - vA.z; + + var s1 = uvB.x - uvA.x; + var s2 = uvC.x - uvA.x; + + var t1 = uvB.y - uvA.y; + var t2 = uvC.y - uvA.y; + + var r = 1.0 / ( s1 * t2 - s2 * t1 ); + + sdir.set( + ( t2 * x1 - t1 * x2 ) * r, + ( t2 * y1 - t1 * y2 ) * r, + ( t2 * z1 - t1 * z2 ) * r + ); + + tdir.set( + ( s1 * x2 - s2 * x1 ) * r, + ( s1 * y2 - s2 * y1 ) * r, + ( s1 * z2 - s2 * z1 ) * r + ); + + tan1[ a ].add( sdir ); + tan1[ b ].add( sdir ); + tan1[ c ].add( sdir ); + + tan2[ a ].add( tdir ); + tan2[ b ].add( tdir ); + tan2[ c ].add( tdir ); + + } + + var groups = geometry.groups; + var group, start, count; + + if ( groups.length === 0 ) { + + groups = [ { + start: 0, + count: indices.length + } ]; + + } + + for ( var j = 0; j < groups.length; ++ j ) { + + group = groups[ j ]; + + start = group.start; + count = group.count; + + for ( var g = start, gl = start + count; g < gl; g += 3 ) { + + handleTriangle( + indices[ g + 0 ], + indices[ g + 1 ], + indices[ g + 2 ] + ); + + } + + } + + var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(); + var n = new THREE.Vector3(), n2 = new THREE.Vector3(); + var w, t, test; + + function handleVertex( v ) { + + n.fromArray( normals, v * 3 ); + n2.copy( n ); + + t = tan1[ v ]; + + // Gram-Schmidt orthogonalize + + tmp.copy( t ); + tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + + // Calculate handedness + + tmp2.crossVectors( n2, t ); + test = tmp2.dot( tan2[ v ] ); + w = ( test < 0.0 ) ? - 1.0 : 1.0; + + tangents[ v * 4 ] = tmp.x; + tangents[ v * 4 + 1 ] = tmp.y; + tangents[ v * 4 + 2 ] = tmp.z; + tangents[ v * 4 + 3 ] = w; + + } + + for ( var l = 0; l < groups.length; ++ l ) { + + group = groups[ l ]; + + start = group.start; + count = group.count; + + for ( var i = start, il = start + count; i < il; i += 3 ) { + + handleVertex( indices[ i + 0 ] ); + handleVertex( indices[ i + 1 ] ); + handleVertex( indices[ i + 2 ] ); + + } + + } + + } + +}; + + +/** + * jQuery.toSelector - get the selector text of a jQuery object + * https://gist.github.com/tracend/6402299 + * + * Created by Makis Tracend ( @tracend ) + * Released under the MIT license + * http://makesites.org/licenses/MIT + */ +(function( $ ) { + + $.fn.toSelector = function() { + + var node = $(this).get(0); + var tag = node.tagName.toLowerCase(); + var id = $(this).attr("id"); + var classes = node.className.split(/\s+/); + + var selector = tag; + if(typeof id !== "undefined"){ + selector += "#"+id; + } + if(typeof classes !== "undefined"){ + selector += "."+classes.join("."); + } + + return selector; + }; + +}( jQuery )); diff --git a/lib/three.js b/lib/webgl.js similarity index 55% rename from lib/three.js rename to lib/webgl.js index 973f2d7..c318d24 100644 --- a/lib/three.js +++ b/lib/webgl.js @@ -1,10 +1,10 @@ // generic method to create an element -Three.prototype.webgl = function( options ){ +Three.prototype.webgl = function( options, callback ){ // get the type from the tag name //var type = html.nodeName.toLowerCase(); var el; - // + // switch( options.type ){ case "scene": el = this.webglScene( options ); @@ -21,200 +21,217 @@ Three.prototype.webgl = function( options ){ case "light": el = this.webglLight( options ); break; - case "plane": + case "plane": el = this.webglPlane( options ); break; - case "sphere": + case "sphere": el = this.webglSphere( options ); break; - case "cube": + case "cube": el = this.webglCube( options ); break; - case "cylinder": + case "cylinder": el = this.webglCylinder( options ); break; - case "terrain": + case "sprite": + el = this.webglSprite( options ); + break; + case "terrain": el = this.webglTerrain( options ); break; - default: + default: // a generic lookup in the internal methods... - el = (typeof this.fn.webgl[options.type] != "undefined" ) ? this.fn.webgl[options.type].apply(this, [options] ) : false; + if(typeof this.fn.webgl[options.type] != "undefined" ) this.fn.webgl[options.type].apply(this, [options, callback] ); break; } - - return el; - + + return callback(el); + }; - + // move all internal methods here... fn.webgl = { - + }; -Three.prototype.webglScene = function( options ){ - +Three.prototype.webglScene = function( attributes ){ + var defaults = { id : false }; - - var settings = $.extend(defaults, options); - + + var options = $.extend(defaults, attributes); + var scene = new THREE.Scene(); - - // save in the objects bucket + + // save in the objects bucket this.scenes[scene.id] = scene; - + + // save attributes + scene._attributes = options; + return scene; - + }; - + Three.prototype.webglCamera = function( attributes ){ - // + // var camera; - + var defaults = { - fov: 50, - aspect: this.properties.aspect, - near: 1, - far: 1000, + fov: 50, + aspect: this.properties.aspect, + near: 1, + far: 1000, scene: this.active.scene }; // use the active scene if not specified //var parent = scene || this.active.scene; var options = $.extend(defaults, attributes); - + if( options.orthographic){ // add orthographic camera - } else { + } else { camera = new THREE.PerspectiveCamera( options.fov, options.aspect, options.near, options.far ); } - + + // save attributes + camera._attributes = options; + return camera; }; - + Three.prototype.webglMesh = function( attributes ){ var mesh; var defaults = { - id : false, - wireframe: false, + id : false, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + //var material = new THREE.MeshBasicMaterial( { color: options.color } ); //var mash = new THREE.Mesh( geometry, material ); // wireframe toggle? new THREE.MeshBasicMaterial( {color: Math.random() * 0xffffff, wireframe: true }); - + return mesh; }; - + Three.prototype.webglMaterial = function( attributes ){ - + var material, settings; - + var defaults = { - id : false, - color: 0x000000, - wireframe: false, - map: false, + id : false, + color: 0x000000, + wireframe: false, + map: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); // grab the shaders from the global space var shaders = window.Shaders || {}; - + // check if there is a shader with the id name - if( options.id && shaders[ options.id ] ){ + if( options.id && shaders[ options.id ] ){ settings = {}; - + var shader = Shaders[ options.id ]; if( shader.uniforms ) settings.uniforms = THREE.UniformsUtils.clone(shader.uniforms); if( shader.vertexShader ) settings.vertexShader = shader.vertexShader; if( shader.fragmentShader ) settings.fragmentShader = shader.fragmentShader; - if( options.map && shader.uniforms) settings.uniforms.texture.texture= THREE.ImageUtils.loadTexture( options.map ); + if( options.map && shader.uniforms) settings.uniforms.texture.texture= utils.textureLoader( options.map ); material = new THREE.ShaderMaterial( settings ); - + } else { // create a basic material settings = {}; - if( options.map ) settings.map = THREE.ImageUtils.loadTexture( options.map ); + if( options.map ) settings.map = utils.textureLoader( options.map ); if( options.color && !options.map ) settings.color = options.color; if( options.wireframe ) settings.wireframe = options.wireframe; material = new THREE.MeshBasicMaterial( settings ); - + } - - return material; + + return material; }; - + Three.prototype.webglTexture = function( src ){ - + // texture - + var texture = new THREE.Texture(); - + var loader = new THREE.ImageLoader(); loader.addEventListener( 'load', function ( event ) { - + texture.image = event.content; texture.needsUpdate = true; - + } ); loader.load( src ); return texture; - + }; Three.prototype.webglLight = function( attributes ){ - //var light + + this.active.scene.add( new THREE.AmbientLight( parseInt( attributes.color, 16 ) ) ); + + //var light //return light; }; - + Three.prototype.webglPlane = function( attributes ){ // plane - by default a 1x1 square var defaults = { width: 1, height: 1, - color: 0x000000, - wireframe: false, + color: 0x000000, + wireframe: false, scene: this.active.scene }; - + var options = $.extend(defaults, attributes); - - var geometry = new THREE.PlaneGeometry( options.width, options.height ); + + var Constructor = ( options.buffer ) ? THREE.PlaneBufferGeometry : THREE.PlaneGeometry; + + var geometry = new Constructor( options.width, options.height ); // make this optional? geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; - + }; - + Three.prototype.webglSphere = function( attributes ){ - + var defaults = { - id : false, + id : false, radius : 1, segments : 16, - rings : 16, - color: 0x000000, - wireframe: false, - map: false, + rings : 16, + color: 0x000000, + wireframe: false, + map: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + var geometry = new THREE.SphereGeometry( options.radius, options.segments, options.rings); // make this optional? //geometry.overdraw = true; @@ -224,152 +241,147 @@ Three.prototype.webglSphere = function( attributes ){ mesh.matrixAutoUpdate = false; // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; }; - + Three.prototype.webglCube = function( attributes ){ - + var defaults = { - id : false, - width : 1, - height : 1, - depth : 1, - color: 0x000000, - wireframe: false, + id : false, + width : 1, + height : 1, + depth : 1, + color: 0x000000, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - - var geometry = new THREE.CubeGeometry( options.width, options.height, options.depth); + + var geometry = new THREE.BoxGeometry( options.width, options.height, options.depth); // make this optional? geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; }; - + Three.prototype.webglCylinder = function( attributes ){ - + var defaults = { - id : false, - radiusTop : 100, - radiusBottom : 100, - segmentsRadius : 400, - segmentsHeight : 50, - openEnded : false, - color: 0x000000, - wireframe: false, + id : false, + radiusTop : 1, + radiusBottom : 1, + segmentsRadius : 4, + segmentsHeight : 16, + openEnded : false, + color: 0x000000, + wireframe: false, scene: this.active.scene - }; - + }; + var options = $.extend(defaults, attributes); - + var geometry = new THREE.CylinderGeometry( options.radiusTop, options.radiusBottom, options.segmentsRadius, options.segmentsHeight, options.openEnded, false); // make this optional? //geometry.overdraw = true; - geometry.dynamic = true; + geometry.dynamic = true; var material = new THREE.MeshBasicMaterial( { color: options.color, wireframe: options.wireframe } ); var mesh = new THREE.Mesh( geometry, material ); - + // set attributes if( options.id ) mesh.name = options.id; - + + // save attributes + mesh._attributes = options; + return mesh; - - }; - -Three.prototype.webglTerrain = function( attributes ){ - // assuming that terrain is generated from a heightmap - support class="mesh" in the future? - var terrain; - + + }; + +Three.prototype.webglSprite = function( attributes ){ + + // sprite + + attributes = attributes || {}; + var defaults = { - + map : false, + color: 0xffffff, + fog: false, + transparent: true, + opacity: 1 + //alignment: THREE.SpriteAlignment.topLeft + //useScreenCoordinates: true + //scene: this.active.scene }; - - - this.active.scene.add( new THREE.AmbientLight( 0x111111 ) ); - directionalLight = new THREE.DirectionalLight( 0xffffff, 1.15 ); - directionalLight.position.set( 500, 2000, 0 ); - this.active.scene.add( directionalLight ); - - - var plane = new THREE.PlaneGeometry( 6000, 6000, 256, 256 ); + var options = $.extend(defaults, attributes); + // FIX map + if ( attributes.map ) { + options.map = utils.textureLoader( attributes.map ); + } else { + //placeholder pixel + options.map = utils.pixel(); + } + // save id (name) for later + var name = options.id; + // FIX: delete unsupported options (why not define the options supported?) + delete options.id; + delete options['class']; + delete options.el; + delete options.style; - plane.computeFaceNormals(); - plane.computeVertexNormals(); - plane.computeTangents(); + var material = new THREE.SpriteMaterial( options ); + material.scaleByViewport = true; + material.blending = THREE.AdditiveBlending; - // - - var terrainShader = THREE.ShaderTerrain.terrain; - - uniformsTerrain = THREE.UniformsUtils.clone( terrainShader.uniforms ); - /* - var heightmapTexture = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); - var diffuseTexture1 = THREE.ImageUtils.loadTexture( "assets/img/terrain/diffuse.jpg" ); - var diffuseTexture2 = THREE.ImageUtils.loadTexture( "assets/img/terrain/heightmap.png" ); - var specularMap = THREE.ImageUtils.loadTexture( "assets/img/terrain/specular.png"); - - diffuseTexture1.wrapS = diffuseTexture1.wrapT = THREE.RepeatWrapping; - diffuseTexture2.wrapS = diffuseTexture2.wrapT = THREE.RepeatWrapping; - //detailTexture.wrapS = detailTexture.wrapT = THREE.RepeatWrapping; - specularMap.wrapS = specularMap.wrapT = THREE.RepeatWrapping; - - //uniformsTerrain[ "tNormal" ].value = heightmapTexture; - //uniformsTerrain[ "uNormalScale" ].value = 1; - - uniformsTerrain[ "tDisplacement" ].value = heightmapTexture; - uniformsTerrain[ "uDisplacementScale" ].value = 375; - - uniformsTerrain[ "tDiffuse1" ].value = diffuseTexture1; - uniformsTerrain[ "tDiffuse2" ].value = diffuseTexture2; - uniformsTerrain[ "tSpecular" ].value = specularMap; - //uniformsTerrain[ "tDetail" ].value = diffuseTexture1; - - uniformsTerrain[ "enableDiffuse1" ].value = true; - uniformsTerrain[ "enableDiffuse2" ].value = true; - uniformsTerrain[ "enableSpecular" ].value = true; - - uniformsTerrain[ "uDiffuseColor" ].value.setHex( 0xffffff ); - uniformsTerrain[ "uSpecularColor" ].value.setHex( 0xffffff ); - uniformsTerrain[ "uAmbientColor" ].value.setHex( 0x111111 ); - - //uniformsTerrain[ "uShininess" ].value = 30; - - uniformsTerrain[ "uRepeatOverlay" ].value.set( 6, 6 ); - */ - - uniformsTerrain.uDiffuseColor.value.setHex( 0xffffff ); - uniformsTerrain.uSpecularColor.value.setHex( 0xffffff ); - uniformsTerrain.uAmbientColor.value.setHex( 0x111111 ); - - uniformsTerrain.uRepeatOverlay.value.set( 6, 6 ); - // + var sprite = new THREE.Sprite( material ); + // save name (id) back to the object + sprite.name = name; - // fog is expensive - disable for now... - var material = new THREE.ShaderMaterial( { - uniforms : uniformsTerrain, - vertexShader : terrainShader.vertexShader, - fragmentShader : terrainShader.fragmentShader, - lights : true, - fog : false - }); + // save attributes + sprite._attributes = options; - terrain = new THREE.Mesh( plane, material ); + return sprite; + + }; + +Three.prototype.webglTerrain = function( attributes ){ + // fallbacks + attributes = attributes || {}; + + var defaults = { + lights: true, + fog: true, + scale: 256, + width: 6000, + height: 6000, + resolution: 256, + shader: true, + repeat: 1 // diffuse map repeat + }; + + var options = $.extend(defaults, attributes); + + // logic contained + // assuming that terrain is generated from a heightmap - support class="mesh" in the future? + var terrain = (new Terrain( options )).terrain; - // save type as part of the mesh - terrain.type = "terrain"; - //terrain.visible=false; this.active.scene.add( terrain ); - + return terrain; - + }; diff --git a/package.json b/package.json index 6373bc2..87b1947 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,23 @@ { - "private" : true, - "name" : "jquery.three", - "version" : "0.6.0", - "licenses": [ + "name" : "jquery.three", + "version" : "0.9.8", + "author" : "makesites", + "homepage" : "http://github.com/makesites/jquery-three", + "description" : "jQuery Three() - jQuery extension with 3D methods (using Three.js)", + "keywords": ["jquery-plugin"], + "licenses" : [ { "type": "MIT License", "url": "http://makesites.org/licenses/MIT" } ], - "engine" : { - "node" : ">0.8.x" - }, + "engine" : { + "node" : ">0.8.x" + }, "devDependencies" : { - "commander" : "~0.5", - "jshint" : "~0.9", - "uglify-js2" : "~2.1", + "commander" : "~0.5", + "jshint" : "jshint@2.9.1", + "uglify-js" : "2.6.2", "hbs" : "~1.0" - } + } } diff --git a/readme.md b/readme.md index 8c3c2b0..2d10c38 100644 --- a/readme.md +++ b/readme.md @@ -1,25 +1,41 @@ -## jQuery Three +# jQuery Three -A plugin / extension of the jQuery API for 3d objects (using Three.js) +A plugin / extension of the jQuery API for 3d objects (using Three.js) +jQuery Three was developed to bridge the gap between WebGL and the DOM by using existing conventions web designers are already familiar with. -## Introduction +Effectively it provides a higher level api that abstracts Three.js methods to known common conventions from regular web development. + + +## Dependencies + +* jQuery v2.x +* THREE.js rev.75 -jQuery Three was developed to bridge the gap between WebGL and the DOM by using existing conventions web designers are already familiar with. -Effectively it provides a higher level api that abstracts Three.js methods to known common conventions from web development. +## Examples + +* [Skybox](http://makesites.org/jquery-three/examples/skybox.html) +* [Skysphere](http://makesites.org/jquery-three/examples/skysphere.html) +* [First Person controls](http://makesites.org/jquery-three/examples/fps.html) +* [Earth Texture](http://makesites.org/jquery-three/examples/earth.html) +* [Append with Handlebars,js](http://makesites.org/jquery-three/examples/handlebars.html) +* [Binary Loader](http://makesites.org/jquery-three/examples/binary.html) +* [Sprite animation](http://makesites.org/jquery-three/examples/sprite.html) +* [VR shader](http://makesites.org/jquery-three/examples/vr.html) +* [Water shader](http://makesites.org/jquery-three/examples/water.html) ## Install -Get the latest (stable) version using bower: +Get the latest (stable) version using bower: ``` bower install jquery.three ``` ## Usage -Enable 3D actions on any container using: +Enable 3D actions on any container using: ``` $("container").three( options, callback ); @@ -28,6 +44,16 @@ $("container").three( options, callback ); Read the [wiki](https://github.com/makesites/jquery-three/wiki) docs for more details on the [methods](https://github.com/makesites/jquery-three/wiki/Methods) and [tag support](https://github.com/makesites/jquery-three/wiki/Tags). +## Options + +There are the setup options used when initiating the ```.three()``` method: + +* **alpha**: (boolean, default: true) Renders the WebGL canvas transparent so you can stack other elements behind it. +* **deps**: (object, default: {}) Listing dependency scripts loaded as extensions of THREE.js +* **paused**: (boolean, default: false) Start with a paused loop - or set as a flag to pause anytime. +* **watch**: (boolean, default: false) If set it monitors the DOM for updates and syncs the changes with THREE.js + + ## Credits Created by [Makis Tracend](http://github.com/tracend) [ [full list of contributors](https://github.com/makesites/jquery-three/graphs/contributors) ] diff --git a/three.jquery.json b/three.jquery.json new file mode 100644 index 0000000..6a14a3f --- /dev/null +++ b/three.jquery.json @@ -0,0 +1,37 @@ +{ + "name": "three", + "version": "0.9.8", + "title": "jQuery Three", + "description": "A plugin / extension of the jQuery API for 3d objects (using Three.js)", + "keywords": [ + "three.js", + "3d", + "graphics", + "games", + "visuals" + ], + "author": { + "name": "Makesites", + "url": "http://makesites.org" + }, + "maintainers": [ + { + "name": "Makis Tracend", + "email": "makis@makesit.es", + "url": "http://github.com/tracend" + } + ], + "bugs": "https://github.com/makesites/jquery-three/issues", + "homepage": "https://github.com/makesites/jquery-three", + "docs": "https://github.com/makesites/jquery-three/wiki", + "download": "http://plugins.jquery.com/three", + "licenses": [ + { + "type": "MIT License", + "url": "http://makesites.org/licenses/MIT" + } + ], + "dependencies": { + "jquery": "~2.0.3" + } +}