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