From 6c5f267a1e8c1523d144ffd8c8ae80e3ebc223e6 Mon Sep 17 00:00:00 2001 From: Navarr Barnier Date: Thu, 16 Aug 2012 17:36:50 -0400 Subject: [PATCH] Initial Commit --- backend/backend.php | 126 + backend/resources/3d/Cube.js | 185 + backend/resources/3d/ImageUtils.js | 32 + backend/resources/3d/Three.js | 189 + backend/resources/3d/WebGLRenderer.js | 4024 +++++++++++++++++ backend/rmdir.php | 14 + iframe.html | 20 + images/bg_line.png | Bin 0 -> 1341 bytes images/skins/earthiverse/arm_left_back.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_left_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/arm_left_front.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_left_inner.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_left_outer.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_left_top.png | Bin 0 -> 855 bytes images/skins/earthiverse/arm_right_back.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_right_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/arm_right_front.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_right_inner.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_right_outer.png | Bin 0 -> 950 bytes images/skins/earthiverse/arm_right_top.png | Bin 0 -> 855 bytes images/skins/earthiverse/base.png | Bin 0 -> 328 bytes images/skins/earthiverse/base_x2.png | Bin 0 -> 516 bytes images/skins/earthiverse/body_back.png | Bin 0 -> 950 bytes images/skins/earthiverse/body_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/body_front.png | Bin 0 -> 950 bytes images/skins/earthiverse/body_left.png | Bin 0 -> 950 bytes images/skins/earthiverse/body_right.png | Bin 0 -> 950 bytes images/skins/earthiverse/body_top.png | Bin 0 -> 855 bytes images/skins/earthiverse/hat_back.png | Bin 0 -> 334 bytes images/skins/earthiverse/hat_bottom.png | Bin 0 -> 334 bytes images/skins/earthiverse/hat_front.png | Bin 0 -> 334 bytes images/skins/earthiverse/hat_left.png | Bin 0 -> 334 bytes images/skins/earthiverse/hat_right.png | Bin 0 -> 334 bytes images/skins/earthiverse/hat_top.png | Bin 0 -> 334 bytes images/skins/earthiverse/head_back.png | Bin 0 -> 895 bytes images/skins/earthiverse/head_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/head_front.png | Bin 0 -> 919 bytes images/skins/earthiverse/head_left.png | Bin 0 -> 895 bytes images/skins/earthiverse/head_right.png | Bin 0 -> 895 bytes images/skins/earthiverse/head_top.png | Bin 0 -> 854 bytes images/skins/earthiverse/leg_left_back.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_left_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/leg_left_front.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_left_inner.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_left_outer.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_left_top.png | Bin 0 -> 856 bytes images/skins/earthiverse/leg_right_back.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_right_bottom.png | Bin 0 -> 856 bytes images/skins/earthiverse/leg_right_front.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_right_inner.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_right_outer.png | Bin 0 -> 944 bytes images/skins/earthiverse/leg_right_top.png | Bin 0 -> 856 bytes index.php | 126 + style.css | 14 + 54 files changed, 4730 insertions(+) create mode 100644 backend/backend.php create mode 100644 backend/resources/3d/Cube.js create mode 100644 backend/resources/3d/ImageUtils.js create mode 100644 backend/resources/3d/Three.js create mode 100644 backend/resources/3d/WebGLRenderer.js create mode 100644 backend/rmdir.php create mode 100644 iframe.html create mode 100644 images/bg_line.png create mode 100644 images/skins/earthiverse/arm_left_back.png create mode 100644 images/skins/earthiverse/arm_left_bottom.png create mode 100644 images/skins/earthiverse/arm_left_front.png create mode 100644 images/skins/earthiverse/arm_left_inner.png create mode 100644 images/skins/earthiverse/arm_left_outer.png create mode 100644 images/skins/earthiverse/arm_left_top.png create mode 100644 images/skins/earthiverse/arm_right_back.png create mode 100644 images/skins/earthiverse/arm_right_bottom.png create mode 100644 images/skins/earthiverse/arm_right_front.png create mode 100644 images/skins/earthiverse/arm_right_inner.png create mode 100644 images/skins/earthiverse/arm_right_outer.png create mode 100644 images/skins/earthiverse/arm_right_top.png create mode 100644 images/skins/earthiverse/base.png create mode 100644 images/skins/earthiverse/base_x2.png create mode 100644 images/skins/earthiverse/body_back.png create mode 100644 images/skins/earthiverse/body_bottom.png create mode 100644 images/skins/earthiverse/body_front.png create mode 100644 images/skins/earthiverse/body_left.png create mode 100644 images/skins/earthiverse/body_right.png create mode 100644 images/skins/earthiverse/body_top.png create mode 100644 images/skins/earthiverse/hat_back.png create mode 100644 images/skins/earthiverse/hat_bottom.png create mode 100644 images/skins/earthiverse/hat_front.png create mode 100644 images/skins/earthiverse/hat_left.png create mode 100644 images/skins/earthiverse/hat_right.png create mode 100644 images/skins/earthiverse/hat_top.png create mode 100644 images/skins/earthiverse/head_back.png create mode 100644 images/skins/earthiverse/head_bottom.png create mode 100644 images/skins/earthiverse/head_front.png create mode 100644 images/skins/earthiverse/head_left.png create mode 100644 images/skins/earthiverse/head_right.png create mode 100644 images/skins/earthiverse/head_top.png create mode 100644 images/skins/earthiverse/leg_left_back.png create mode 100644 images/skins/earthiverse/leg_left_bottom.png create mode 100644 images/skins/earthiverse/leg_left_front.png create mode 100644 images/skins/earthiverse/leg_left_inner.png create mode 100644 images/skins/earthiverse/leg_left_outer.png create mode 100644 images/skins/earthiverse/leg_left_top.png create mode 100644 images/skins/earthiverse/leg_right_back.png create mode 100644 images/skins/earthiverse/leg_right_bottom.png create mode 100644 images/skins/earthiverse/leg_right_front.png create mode 100644 images/skins/earthiverse/leg_right_inner.png create mode 100644 images/skins/earthiverse/leg_right_outer.png create mode 100644 images/skins/earthiverse/leg_right_top.png create mode 100644 index.php create mode 100644 style.css diff --git a/backend/backend.php b/backend/backend.php new file mode 100644 index 0000000..64b2266 --- /dev/null +++ b/backend/backend.php @@ -0,0 +1,126 @@ +\nThanks."; + exit; +} + +function minecraft_skin_3d_part($original, $user, $xpos, $ypos, $width, $height, $texturesize, $name, $flipx, $flipy) { + $temp = imagecreatetruecolor($texturesize,$texturesize); + imagealphablending($temp, false); + imagesavealpha($temp, true); + if($flipx == TRUE && $flipy == TRUE) { + $xpos = $xpos + $width -1; + $width = 0 - $width; + $ypos = $ypos + $height -1; + $height = 0 - $height; + } else if($flipx == TRUE) { + $xpos = $xpos + $width-1; + $width = 0 - $width; + } else if($flipy == TRUE) { + $ypos = $ypos + $height-1; + $height = 0 - $height; + } + imagecopyresampled($temp, $original, 0, 0, $xpos, $ypos, $texturesize, $texturesize, $width, $height); + imagepng($temp, "images/skins/".$user."/".$name.".png"); + imagedestroy($temp); +} + +function minecraft_skin_download($user) { + if(!file_exists('images/skins/'.$user.'/base.png')) { + if(@getimagesize('http://s3.amazonaws.com/MinecraftSkins/'.$user.'.png')) { + //Make a new directory + If(!is_dir('images/skins/'.$user)) { + mkdir('images/skins/'.$user,0777); + } + //Download the skin from Minecraft.net and put it in /images/skins/ + $url = 'http://s3.amazonaws.com/MinecraftSkins/'.$user.'.png'; + $img = 'images/skins/'.$user.'/base.png'; + file_put_contents($img, file_get_contents($url)); + + //Create another image twice the size + $original = imagecreatefrompng('images/skins/'.$user.'/base.png'); + + //Create Base_x2 + //If you want, you can delete the next 6 rows after these comments without worrying. + //I just use these to add faces to usernames in the stats lists with some css magic. + $temp = imagecreatetruecolor(128,64); + imagealphablending($temp, false); + imagesavealpha($temp, true); + imagecopyresized($temp, $original, 0, 0, 0, 0, 128, 64, 64, 32); + imagepng($temp, "images/skins/".$user."/base_x2.png"); + imagedestroy($temp); + + ///////////////////////// + // Body Parts (for 3D) // + ///////////////////////// + + minecraft_skin_3d_part($original,$user,40,0,8,8,256,"hat_top", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,48,0,8,8,256,"hat_bottom", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,32,8,8,8,256,"hat_left", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,40,8,8,8,256,"hat_front", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,48,8,8,8,256,"hat_right", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,56,8,8,8,256,"hat_back", FALSE, FALSE); + + minecraft_skin_3d_part($original,$user,8,0,8,8,256,"head_top", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,16,0,8,8,256,"head_bottom", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,0,8,8,8,256,"head_left", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,8,8,8,8,256,"head_front", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,16,8,8,8,256,"head_right", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,24,8,8,8,256,"head_back", FALSE, FALSE); + + minecraft_skin_3d_part($original,$user,20,16,8,4,256,"body_top", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,28,16,8,4,256,"body_bottom", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,16,20,4,12,256,"body_right", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,20,20,8,12,256,"body_front", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,28,20,4,12,256,"body_left", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,32,20,8,12,256,"body_back", FALSE, FALSE); + + minecraft_skin_3d_part($original,$user,44,16,4,4,256,"arm_left_top", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,48,16,4,4,256,"arm_left_bottom", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,40,20,4,12,256,"arm_left_outer", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,44,20,4,12,256,"arm_left_front", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,48,20,4,12,256,"arm_left_inner", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,52,20,4,12,256,"arm_left_back", FALSE, FALSE); + + minecraft_skin_3d_part($original,$user,44,16,4,4,256,"arm_right_top", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,48,16,4,4,256,"arm_right_bottom", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,40,20,4,12,256,"arm_right_outer", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,44,20,4,12,256,"arm_right_front", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,48,20,4,12,256,"arm_right_inner", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,52,20,4,12,256,"arm_right_back", TRUE, FALSE); + + minecraft_skin_3d_part($original,$user,4,16,4,4,256,"leg_left_top", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,8,16,4,4,256,"leg_left_bottom", FALSE, TRUE); + minecraft_skin_3d_part($original,$user,0,20,4,12,256,"leg_left_outer", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,4,20,4,12,256,"leg_left_front", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,8,20,4,12,256,"leg_left_inner", FALSE, FALSE); + minecraft_skin_3d_part($original,$user,12,20,4,12,256,"leg_left_back", FALSE, FALSE); + + minecraft_skin_3d_part($original,$user,4,16,4,4,256,"leg_right_top", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,8,16,4,4,256,"leg_right_bottom", TRUE, TRUE); + minecraft_skin_3d_part($original,$user,0,20,4,12,256,"leg_right_outer", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,4,20,4,12,256,"leg_right_front", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,8,20,4,12,256,"leg_right_inner", TRUE, FALSE); + minecraft_skin_3d_part($original,$user,12,20,4,12,256,"leg_right_back", TRUE, FALSE); + + //Release original from memory (Skin from minecraft.net) + imagedestroy($original); + } + } +} + +function minecraft_skin_delete($user) { + rrmdir('images/skins/'.$user); +} + +// Functions not created by me +include_once('rmdir.php'); // Script found on php.net that removes all the files in a folder, then the folder itself +?> diff --git a/backend/resources/3d/Cube.js b/backend/resources/3d/Cube.js new file mode 100644 index 0000000..a6b4e53 --- /dev/null +++ b/backend/resources/3d/Cube.js @@ -0,0 +1,185 @@ +/** + * @author mr.doob / http://mrdoob.com/ + * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as + */ + +var Cube = function ( width, height, depth, segments_width, segments_height, materials, flipped, sides ) { + + THREE.Geometry.call( this ); + + var scope = this, + width_half = width / 2, + height_half = height / 2, + depth_half = depth / 2, + flip = flipped ? - 1 : 1; + + if ( materials !== undefined ) { + + if ( materials instanceof Array ) { + + this.materials = materials; + + } else { + + this.materials = []; + + for ( var i = 0; i < 6; i ++ ) { + + this.materials.push( [ materials ] ); + + } + + } + + } else { + + this.materials = []; + + } + + this.sides = { px: true, nx: true, py: true, ny: true, pz: true, nz: true }; + + if( sides != undefined ) { + + for( var s in sides ) { + + if ( this.sides[ s ] != undefined ) { + + this.sides[ s ] = sides[ s ]; + + } + + } + + } + + this.sides.px && buildPlane( 'z', 'y', 1 * flip, - 1, depth, height, - width_half, this.materials[ 0 ] ); // px + this.sides.nx && buildPlane( 'z', 'y', - 1 * flip, - 1, depth, height, width_half, this.materials[ 1 ] ); // nx + this.sides.py && buildPlane( 'x', 'z', 1 * flip, 1, width, depth, height_half, this.materials[ 2 ] ); // py + this.sides.ny && buildPlane( 'x', 'z', 1 * flip, - 1, width, depth, - height_half, this.materials[ 3 ] ); // ny + this.sides.pz && buildPlane( 'x', 'y', 1 * flip, - 1, width, height, depth_half, this.materials[ 4 ] ); // pz + this.sides.nz && buildPlane( 'x', 'y', - 1 * flip, - 1, width, height, - depth_half, this.materials[ 5 ] ); // nz + + mergeVertices(); + + function buildPlane( u, v, udir, vdir, width, height, depth, material ) { + + var w, ix, iy, + gridX = segments_width || 1, + gridY = segments_height || 1, + gridX1 = gridX + 1, + gridY1 = gridY + 1, + width_half = width / 2, + height_half = height / 2, + segment_width = width / gridX, + segment_height = height / gridY, + offset = scope.vertices.length; + + if ( ( u == 'x' && v == 'y' ) || ( u == 'y' && v == 'x' ) ) { + + w = 'z'; + + } else if ( ( u == 'x' && v == 'z' ) || ( u == 'z' && v == 'x' ) ) { + + w = 'y'; + + } else if ( ( u == 'z' && v == 'y' ) || ( u == 'y' && v == 'z' ) ) { + + w = 'x'; + + } + + + for( iy = 0; iy < gridY1; iy++ ) { + + for( ix = 0; ix < gridX1; ix++ ) { + + var vector = new THREE.Vector3(); + vector[ u ] = ( ix * segment_width - width_half ) * udir; + vector[ v ] = ( iy * segment_height - height_half ) * vdir; + vector[ w ] = depth; + + scope.vertices.push( new THREE.Vertex( vector ) ); + + } + + } + + for( iy = 0; iy < gridY; iy++ ) { + + for( ix = 0; ix < gridX; ix++ ) { + + var a = ix + gridX1 * iy; + var b = ix + gridX1 * ( iy + 1 ); + var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = ( ix + 1 ) + gridX1 * iy; + + scope.faces.push( new THREE.Face4( a + offset, b + offset, c + offset, d + offset, null, material ) ); + scope.uvs.push( [ + new THREE.UV( ix / gridX, iy / gridY ), + new THREE.UV( ix / gridX, ( iy + 1 ) / gridY ), + new THREE.UV( ( ix + 1 ) / gridX, ( iy + 1 ) / gridY ), + new THREE.UV( ( ix + 1 ) / gridX, iy / gridY ) + ] ); + + } + + } + + } + + function mergeVertices() { + + var unique = [], changes = []; + + for ( var i = 0, il = scope.vertices.length; i < il; i ++ ) { + + var v = scope.vertices[ i ], + duplicate = false; + + for ( var j = 0, jl = unique.length; j < jl; j ++ ) { + + var vu = unique[ j ]; + + if( v.position.x == vu.position.x && v.position.y == vu.position.y && v.position.z == vu.position.z ) { + + changes[ i ] = j; + duplicate = true; + break; + + } + + } + + if ( ! duplicate ) { + + changes[ i ] = unique.length; + unique.push( new THREE.Vertex( v.position.clone() ) ); + + } + + } + + for ( i = 0, il = scope.faces.length; i < il; i ++ ) { + + var face = scope.faces[ i ]; + + face.a = changes[ face.a ]; + face.b = changes[ face.b ]; + face.c = changes[ face.c ]; + face.d = changes[ face.d ]; + + } + + scope.vertices = unique; + + } + + this.computeCentroids(); + this.computeFaceNormals(); + this.sortFacesByMaterial(); + +}; + +Cube.prototype = new THREE.Geometry(); +Cube.prototype.constructor = Cube; diff --git a/backend/resources/3d/ImageUtils.js b/backend/resources/3d/ImageUtils.js new file mode 100644 index 0000000..ee52f61 --- /dev/null +++ b/backend/resources/3d/ImageUtils.js @@ -0,0 +1,32 @@ +var ImageUtils = { + + loadTexture: function ( path, mapping, callback ) { + + var image = new Image(); + image.onload = function () { this.loaded = true; if( callback ) callback( this ); }; + image.src = path; + + return new THREE.Texture( image, mapping ); + + }, + + loadArray: function ( array, callback ) { + + var i, l, images = []; + + images.loadCount = 0; + + for ( i = 0, l = array.length; i < l; ++i ) { + + images[ i ] = new Image(); + images[ i ].loaded = 0; + images[ i ].onload = function () { images.loadCount += 1; this.loaded = true; if( callback ) callback( this ); }; + images[ i ].src = array[ i ]; + + } + + return images; + + } + +}; \ No newline at end of file diff --git a/backend/resources/3d/Three.js b/backend/resources/3d/Three.js new file mode 100644 index 0000000..c8b976b --- /dev/null +++ b/backend/resources/3d/Three.js @@ -0,0 +1,189 @@ +// Three.js r31 - http://github.com/mrdoob/three.js +var THREE=THREE||{};THREE.Color=function(a){this.autoUpdate=true;this.setHex(a)}; +THREE.Color.prototype={setRGB:function(a,c,f){this.r=a;this.g=c;this.b=f;if(this.autoUpdate){this.updateHex();this.updateStyleString()}},setHex:function(a){this.hex=~~a&16777215;if(this.autoUpdate){this.updateRGBA();this.updateStyleString()}},updateHex:function(){this.hex=~~(this.r*255)<<16^~~(this.g*255)<<8^~~(this.b*255)},updateRGBA:function(){this.r=(this.hex>>16&255)/255;this.g=(this.hex>>8&255)/255;this.b=(this.hex&255)/255},updateStyleString:function(){this.__styleString="rgb("+~~(this.r*255)+ +","+~~(this.g*255)+","+~~(this.b*255)+")"},clone:function(){return new THREE.Color(this.hex)},toString:function(){return"THREE.Color ( r: "+this.r+", g: "+this.g+", b: "+this.b+", hex: "+this.hex+" )"}};THREE.Vector2=function(a,c){this.x=a||0;this.y=c||0}; +THREE.Vector2.prototype={set:function(a,c){this.x=a;this.y=c;return this},copy:function(a){this.x=a.x;this.y=a.y;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;return this},add:function(a,c){this.x=a.x+c.x;this.y=a.y+c.y;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;return this},sub:function(a,c){this.x=a.x-c.x;this.y=a.y-c.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},unit:function(){this.multiplyScalar(1/this.length());return this},length:function(){return Math.sqrt(this.x* +this.x+this.y*this.y)},lengthSq:function(){return this.x*this.x+this.y*this.y},negate:function(){this.x=-this.x;this.y=-this.y;return this},clone:function(){return new THREE.Vector2(this.x,this.y)},toString:function(){return"THREE.Vector2 ("+this.x+", "+this.y+")"}};THREE.Vector3=function(a,c,f){this.x=a||0;this.y=c||0;this.z=f||0}; +THREE.Vector3.prototype={set:function(a,c,f){this.x=a;this.y=c;this.z=f;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,c){this.x=a.x+c.x;this.y=a.y+c.y;this.z=a.z+c.z;return this},addSelf:function(a){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},sub:function(a,c){this.x=a.x-c.x;this.y=a.y-c.y;this.z=a.z-c.z;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;return this}, +cross:function(a,c){this.x=a.y*c.z-a.z*c.y;this.y=a.z*c.x-a.x*c.z;this.z=a.x*c.y-a.y*c.x;return this},crossSelf:function(a){var c=this.x,f=this.y,e=this.z;this.x=f*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-f*a.x;return this},multiply:function(a,c){this.x=a.x*c.x;this.y=a.y*c.y;this.z=a.z*c.z;return this},multiplySelf:function(a){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},divideScalar:function(a){this.x/=a;this.y/=a;this.z/= +a;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},distanceTo:function(a){var c=this.x-a.x,f=this.y-a.y;a=this.z-a.z;return Math.sqrt(c*c+f*f+a*a)},distanceToSquared:function(a){var c=this.x-a.x,f=this.y-a.y;a=this.z-a.z;return c*c+f*f+a*a},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},normalize:function(){var a= +Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);a>0?this.multiplyScalar(1/a):this.set(0,0,0);return this},setLength:function(a){return this.normalize().multiplyScalar(a)},isZero:function(){return Math.abs(this.x)<1.0E-4&&Math.abs(this.y)<1.0E-4&&Math.abs(this.z)<1.0E-4},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)},toString:function(){return"THREE.Vector3 ( "+this.x+", "+this.y+", "+this.z+" )"}}; +THREE.Vector4=function(a,c,f,e){this.x=a||0;this.y=c||0;this.z=f||0;this.w=e||1}; +THREE.Vector4.prototype={set:function(a,c,f,e){this.x=a;this.y=c;this.z=f;this.w=e;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w||1;return this},add:function(a,c){this.x=a.x+c.x;this.y=a.y+c.y;this.z=a.z+c.z;this.w=a.w+c.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,c){this.x=a.x-c.x;this.y=a.y-c.y;this.z=a.z-c.z;this.w=a.w-c.w;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w; +return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){this.x/=a;this.y/=a;this.z/=a;this.w/=a;return this},lerpSelf:function(a,c){this.x+=(a.x-this.x)*c;this.y+=(a.y-this.y)*c;this.z+=(a.z-this.z)*c;this.w+=(a.w-this.w)*c},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},toString:function(){return"THREE.Vector4 ("+this.x+", "+this.y+", "+this.z+", "+this.w+")"}}; +THREE.Ray=function(a,c){this.origin=a||new THREE.Vector3;this.direction=c||new THREE.Vector3}; +THREE.Ray.prototype={intersectScene:function(a){var c,f,e=a.objects,i=[];a=0;for(c=e.length;a0&&Q>0&&n+Q<1}var f,e,i,k,d,s,m,p,D,F, +z,C=a.geometry,O=C.vertices,S=[];f=0;for(e=C.faces.length;fm?e:m;i=i>p? +i:p}a()};this.add3Points=function(m,p,D,F,z,C){if(s){s=false;c=mD?m>z?m:z:D>z?D:z;i=p>F?p>C?p:C:F>C?F:C}else{c=mD?m>z?m>e?m:e:z>e?z:e:D>z?D>e?D:e:z>e?z:e;i=p>F?p>C?p>i?p:i:C>i?C:i:F>C?F>i?F:i:C>i?C:i}a()};this.addRectangle=function(m){if(s){s=false;c=m.getLeft();f=m.getTop();e=m.getRight();i=m.getBottom()}else{c=cm.getRight()?e:m.getRight();i=i>m.getBottom()?i:m.getBottom()}a()};this.inflate=function(m){c-=m;f-=m;e+=m;i+=m;a()};this.minSelf=function(m){c=c>m.getLeft()?c:m.getLeft();f=f>m.getTop()?f:m.getTop();e=e=0&&Math.min(i,m.getBottom())-Math.max(f,m.getTop())>=0};this.empty=function(){s=true;i=e=f=c=0;a()};this.isEmpty=function(){return s};this.toString= +function(){return"THREE.Rectangle ( left: "+c+", right: "+e+", top: "+f+", bottom: "+i+", width: "+k+", height: "+d+" )"}};THREE.Matrix3=function(){this.m=[]};THREE.Matrix3.prototype={transpose:function(){var a;a=this.m[1];this.m[1]=this.m[3];this.m[3]=a;a=this.m[2];this.m[2]=this.m[6];this.m[6]=a;a=this.m[5];this.m[5]=this.m[7];this.m[7]=a;return this}}; +THREE.Matrix4=function(a,c,f,e,i,k,d,s,m,p,D,F,z,C,O,S){this.n11=a||1;this.n12=c||0;this.n13=f||0;this.n14=e||0;this.n21=i||0;this.n22=k||1;this.n23=d||0;this.n24=s||0;this.n31=m||0;this.n32=p||0;this.n33=D||1;this.n34=F||0;this.n41=z||0;this.n42=C||0;this.n43=O||0;this.n44=S||1}; +THREE.Matrix4.prototype={identity:function(){this.n11=1;this.n21=this.n14=this.n13=this.n12=0;this.n22=1;this.n32=this.n31=this.n24=this.n23=0;this.n33=1;this.n43=this.n42=this.n41=this.n34=0;this.n44=1;return this},set:function(a,c,f,e,i,k,d,s,m,p,D,F,z,C,O,S){this.n11=a;this.n12=c;this.n13=f;this.n14=e;this.n21=i;this.n22=k;this.n23=d;this.n24=s;this.n31=m;this.n32=p;this.n33=D;this.n34=F;this.n41=z;this.n42=C;this.n43=O;this.n44=S;return this},copy:function(a){this.n11=a.n11;this.n12=a.n12;this.n13= +a.n13;this.n14=a.n14;this.n21=a.n21;this.n22=a.n22;this.n23=a.n23;this.n24=a.n24;this.n31=a.n31;this.n32=a.n32;this.n33=a.n33;this.n34=a.n34;this.n41=a.n41;this.n42=a.n42;this.n43=a.n43;this.n44=a.n44;return this},lookAt:function(a,c,f){var e=new THREE.Vector3,i=new THREE.Vector3,k=new THREE.Vector3;k.sub(a,c).normalize();e.cross(f,k).normalize();i.cross(k,e).normalize();this.n11=e.x;this.n12=e.y;this.n13=e.z;this.n14=-e.dot(a);this.n21=i.x;this.n22=i.y;this.n23=i.z;this.n24=-i.dot(a);this.n31=k.x; +this.n32=k.y;this.n33=k.z;this.n34=-k.dot(a);this.n43=this.n42=this.n41=0;this.n44=1;return this},multiplyVector3:function(a){var c=a.x,f=a.y,e=a.z,i=1/(this.n41*c+this.n42*f+this.n43*e+this.n44);a.x=(this.n11*c+this.n12*f+this.n13*e+this.n14)*i;a.y=(this.n21*c+this.n22*f+this.n23*e+this.n24)*i;a.z=(this.n31*c+this.n32*f+this.n33*e+this.n34)*i;return a},multiplyVector4:function(a){var c=a.x,f=a.y,e=a.z,i=a.w;a.x=this.n11*c+this.n12*f+this.n13*e+this.n14*i;a.y=this.n21*c+this.n22*f+this.n23*e+this.n24* +i;a.z=this.n31*c+this.n32*f+this.n33*e+this.n34*i;a.w=this.n41*c+this.n42*f+this.n43*e+this.n44*i;return a},crossVector:function(a){var c=new THREE.Vector4;c.x=this.n11*a.x+this.n12*a.y+this.n13*a.z+this.n14*a.w;c.y=this.n21*a.x+this.n22*a.y+this.n23*a.z+this.n24*a.w;c.z=this.n31*a.x+this.n32*a.y+this.n33*a.z+this.n34*a.w;c.w=a.w?this.n41*a.x+this.n42*a.y+this.n43*a.z+this.n44*a.w:1;return c},multiply:function(a,c){var f=a.n11,e=a.n12,i=a.n13,k=a.n14,d=a.n21,s=a.n22,m=a.n23,p=a.n24,D=a.n31,F=a.n32, +z=a.n33,C=a.n34,O=a.n41,S=a.n42,Q=a.n43,q=a.n44,h=c.n11,j=c.n12,r=c.n13,n=c.n14,t=c.n21,l=c.n22,o=c.n23,x=c.n24,u=c.n31,A=c.n32,w=c.n33,v=c.n34,G=c.n41,Z=c.n42,H=c.n43,T=c.n44;this.n11=f*h+e*t+i*u+k*G;this.n12=f*j+e*l+i*A+k*Z;this.n13=f*r+e*o+i*w+k*H;this.n14=f*n+e*x+i*v+k*T;this.n21=d*h+s*t+m*u+p*G;this.n22=d*j+s*l+m*A+p*Z;this.n23=d*r+s*o+m*w+p*H;this.n24=d*n+s*x+m*v+p*T;this.n31=D*h+F*t+z*u+C*G;this.n32=D*j+F*l+z*A+C*Z;this.n33=D*r+F*o+z*w+C*H;this.n34=D*n+F*x+z*v+C*T;this.n41=O*h+S*t+Q*u+q*G; +this.n42=O*j+S*l+Q*A+q*Z;this.n43=O*r+S*o+Q*w+q*H;this.n44=O*n+S*x+Q*v+q*T;return this},multiplySelf:function(a){var c=this.n11,f=this.n12,e=this.n13,i=this.n14,k=this.n21,d=this.n22,s=this.n23,m=this.n24,p=this.n31,D=this.n32,F=this.n33,z=this.n34,C=this.n41,O=this.n42,S=this.n43,Q=this.n44,q=a.n11,h=a.n21,j=a.n31,r=a.n41,n=a.n12,t=a.n22,l=a.n32,o=a.n42,x=a.n13,u=a.n23,A=a.n33,w=a.n43,v=a.n14,G=a.n24,Z=a.n34;a=a.n44;this.n11=c*q+f*h+e*j+i*r;this.n12=c*n+f*t+e*l+i*o;this.n13=c*x+f*u+e*A+i*w;this.n14= +c*v+f*G+e*Z+i*a;this.n21=k*q+d*h+s*j+m*r;this.n22=k*n+d*t+s*l+m*o;this.n23=k*x+d*u+s*A+m*w;this.n24=k*v+d*G+s*Z+m*a;this.n31=p*q+D*h+F*j+z*r;this.n32=p*n+D*t+F*l+z*o;this.n33=p*x+D*u+F*A+z*w;this.n34=p*v+D*G+F*Z+z*a;this.n41=C*q+O*h+S*j+Q*r;this.n42=C*n+O*t+S*l+Q*o;this.n43=C*x+O*u+S*A+Q*w;this.n44=C*v+O*G+S*Z+Q*a;return this},multiplyScalar:function(a){this.n11*=a;this.n12*=a;this.n13*=a;this.n14*=a;this.n21*=a;this.n22*=a;this.n23*=a;this.n24*=a;this.n31*=a;this.n32*=a;this.n33*=a;this.n34*=a;this.n41*= +a;this.n42*=a;this.n43*=a;this.n44*=a;return this},determinant:function(){return this.n14*this.n23*this.n32*this.n41-this.n13*this.n24*this.n32*this.n41-this.n14*this.n22*this.n33*this.n41+this.n12*this.n24*this.n33*this.n41+this.n13*this.n22*this.n34*this.n41-this.n12*this.n23*this.n34*this.n41-this.n14*this.n23*this.n31*this.n42+this.n13*this.n24*this.n31*this.n42+this.n14*this.n21*this.n33*this.n42-this.n11*this.n24*this.n33*this.n42-this.n13*this.n21*this.n34*this.n42+this.n11*this.n23*this.n34* +this.n42+this.n14*this.n22*this.n31*this.n43-this.n12*this.n24*this.n31*this.n43-this.n14*this.n21*this.n32*this.n43+this.n11*this.n24*this.n32*this.n43+this.n12*this.n21*this.n34*this.n43-this.n11*this.n22*this.n34*this.n43-this.n13*this.n22*this.n31*this.n44+this.n12*this.n23*this.n31*this.n44+this.n13*this.n21*this.n32*this.n44-this.n11*this.n23*this.n32*this.n44-this.n12*this.n21*this.n33*this.n44+this.n11*this.n22*this.n33*this.n44},transpose:function(){function a(c,f,e){var i=c[f];c[f]=c[e]; +c[e]=i}a(this,"n21","n12");a(this,"n31","n13");a(this,"n32","n23");a(this,"n41","n14");a(this,"n42","n24");a(this,"n43","n34");return this},clone:function(){var a=new THREE.Matrix4;a.n11=this.n11;a.n12=this.n12;a.n13=this.n13;a.n14=this.n14;a.n21=this.n21;a.n22=this.n22;a.n23=this.n23;a.n24=this.n24;a.n31=this.n31;a.n32=this.n32;a.n33=this.n33;a.n34=this.n34;a.n41=this.n41;a.n42=this.n42;a.n43=this.n43;a.n44=this.n44;return a},flatten:function(){return[this.n11,this.n21,this.n31,this.n41,this.n12, +this.n22,this.n32,this.n42,this.n13,this.n23,this.n33,this.n43,this.n14,this.n24,this.n34,this.n44]},toString:function(){return"| "+this.n11+" "+this.n12+" "+this.n13+" "+this.n14+" |\n| "+this.n21+" "+this.n22+" "+this.n23+" "+this.n24+" |\n| "+this.n31+" "+this.n32+" "+this.n33+" "+this.n34+" |\n| "+this.n41+" "+this.n42+" "+this.n43+" "+this.n44+" |"}};THREE.Matrix4.translationMatrix=function(a,c,f){var e=new THREE.Matrix4;e.n14=a;e.n24=c;e.n34=f;return e}; +THREE.Matrix4.scaleMatrix=function(a,c,f){var e=new THREE.Matrix4;e.n11=a;e.n22=c;e.n33=f;return e};THREE.Matrix4.rotationXMatrix=function(a){var c=new THREE.Matrix4;c.n22=c.n33=Math.cos(a);c.n32=Math.sin(a);c.n23=-c.n32;return c};THREE.Matrix4.rotationYMatrix=function(a){var c=new THREE.Matrix4;c.n11=c.n33=Math.cos(a);c.n13=Math.sin(a);c.n31=-c.n13;return c};THREE.Matrix4.rotationZMatrix=function(a){var c=new THREE.Matrix4;c.n11=c.n22=Math.cos(a);c.n21=Math.sin(a);c.n12=-c.n21;return c}; +THREE.Matrix4.rotationAxisAngleMatrix=function(a,c){var f=new THREE.Matrix4,e=Math.cos(c),i=Math.sin(c),k=1-e,d=a.x,s=a.y,m=a.z;f.n11=k*d*d+e;f.n12=k*d*s-i*m;f.n13=k*d*m+i*s;f.n21=k*d*s+i*m;f.n22=k*s*s+e;f.n23=k*s*m-i*d;f.n31=k*d*m-i*s;f.n32=k*s*m+i*d;f.n33=k*m*m+e;return f}; +THREE.Matrix4.makeInvert=function(a){var c=new THREE.Matrix4;c.n11=a.n23*a.n34*a.n42-a.n24*a.n33*a.n42+a.n24*a.n32*a.n43-a.n22*a.n34*a.n43-a.n23*a.n32*a.n44+a.n22*a.n33*a.n44;c.n12=a.n14*a.n33*a.n42-a.n13*a.n34*a.n42-a.n14*a.n32*a.n43+a.n12*a.n34*a.n43+a.n13*a.n32*a.n44-a.n12*a.n33*a.n44;c.n13=a.n13*a.n24*a.n42-a.n14*a.n23*a.n42+a.n14*a.n22*a.n43-a.n12*a.n24*a.n43-a.n13*a.n22*a.n44+a.n12*a.n23*a.n44;c.n14=a.n14*a.n23*a.n32-a.n13*a.n24*a.n32-a.n14*a.n22*a.n33+a.n12*a.n24*a.n33+a.n13*a.n22*a.n34-a.n12* +a.n23*a.n34;c.n21=a.n24*a.n33*a.n41-a.n23*a.n34*a.n41-a.n24*a.n31*a.n43+a.n21*a.n34*a.n43+a.n23*a.n31*a.n44-a.n21*a.n33*a.n44;c.n22=a.n13*a.n34*a.n41-a.n14*a.n33*a.n41+a.n14*a.n31*a.n43-a.n11*a.n34*a.n43-a.n13*a.n31*a.n44+a.n11*a.n33*a.n44;c.n23=a.n14*a.n23*a.n41-a.n13*a.n24*a.n41-a.n14*a.n21*a.n43+a.n11*a.n24*a.n43+a.n13*a.n21*a.n44-a.n11*a.n23*a.n44;c.n24=a.n13*a.n24*a.n31-a.n14*a.n23*a.n31+a.n14*a.n21*a.n33-a.n11*a.n24*a.n33-a.n13*a.n21*a.n34+a.n11*a.n23*a.n34;c.n31=a.n22*a.n34*a.n41-a.n24*a.n32* +a.n41+a.n24*a.n31*a.n42-a.n21*a.n34*a.n42-a.n22*a.n31*a.n44+a.n21*a.n32*a.n44;c.n32=a.n14*a.n32*a.n41-a.n12*a.n34*a.n41-a.n14*a.n31*a.n42+a.n11*a.n34*a.n42+a.n12*a.n31*a.n44-a.n11*a.n32*a.n44;c.n33=a.n13*a.n24*a.n41-a.n14*a.n22*a.n41+a.n14*a.n21*a.n42-a.n11*a.n24*a.n42-a.n12*a.n21*a.n44+a.n11*a.n22*a.n44;c.n34=a.n14*a.n22*a.n31-a.n12*a.n24*a.n31-a.n14*a.n21*a.n32+a.n11*a.n24*a.n32+a.n12*a.n21*a.n34-a.n11*a.n22*a.n34;c.n41=a.n23*a.n32*a.n41-a.n22*a.n33*a.n41-a.n23*a.n31*a.n42+a.n21*a.n33*a.n42+a.n22* +a.n31*a.n43-a.n21*a.n32*a.n43;c.n42=a.n12*a.n33*a.n41-a.n13*a.n32*a.n41+a.n13*a.n31*a.n42-a.n11*a.n33*a.n42-a.n12*a.n31*a.n43+a.n11*a.n32*a.n43;c.n43=a.n13*a.n22*a.n41-a.n12*a.n23*a.n41-a.n13*a.n21*a.n42+a.n11*a.n23*a.n42+a.n12*a.n21*a.n43-a.n11*a.n22*a.n43;c.n44=a.n12*a.n23*a.n31-a.n13*a.n22*a.n31+a.n13*a.n21*a.n32-a.n11*a.n23*a.n32-a.n12*a.n21*a.n33+a.n11*a.n22*a.n33;c.multiplyScalar(1/a.determinant());return c}; +THREE.Matrix4.makeInvert3x3=function(a){var c=a.flatten();a=new THREE.Matrix3;var f=c[10]*c[5]-c[6]*c[9],e=-c[10]*c[1]+c[2]*c[9],i=c[6]*c[1]-c[2]*c[5],k=-c[10]*c[4]+c[6]*c[8],d=c[10]*c[0]-c[2]*c[8],s=-c[6]*c[0]+c[2]*c[4],m=c[9]*c[4]-c[5]*c[8],p=-c[9]*c[0]+c[1]*c[8],D=c[5]*c[0]-c[1]*c[4];c=c[0]*f+c[1]*k+c[2]*m;if(c==0)throw"matrix not invertible";c=1/c;a.m[0]=c*f;a.m[1]=c*e;a.m[2]=c*i;a.m[3]=c*k;a.m[4]=c*d;a.m[5]=c*s;a.m[6]=c*m;a.m[7]=c*p;a.m[8]=c*D;return a}; +THREE.Matrix4.makeFrustum=function(a,c,f,e,i,k){var d,s,m;d=new THREE.Matrix4;s=2*i/(c-a);m=2*i/(e-f);a=(c+a)/(c-a);f=(e+f)/(e-f);e=-(k+i)/(k-i);i=-2*k*i/(k-i);d.n11=s;d.n12=0;d.n13=a;d.n14=0;d.n21=0;d.n22=m;d.n23=f;d.n24=0;d.n31=0;d.n32=0;d.n33=e;d.n34=i;d.n41=0;d.n42=0;d.n43=-1;d.n44=0;return d};THREE.Matrix4.makePerspective=function(a,c,f,e){var i;a=f*Math.tan(a*Math.PI/360);i=-a;return THREE.Matrix4.makeFrustum(i*c,a*c,i,a,f,e)}; +THREE.Matrix4.makeOrtho=function(a,c,f,e,i,k){var d,s,m,p;d=new THREE.Matrix4;s=c-a;m=f-e;p=k-i;a=(c+a)/s;f=(f+e)/m;i=(k+i)/p;d.n11=2/s;d.n12=0;d.n13=0;d.n14=-a;d.n21=0;d.n22=2/m;d.n23=0;d.n24=-f;d.n31=0;d.n32=0;d.n33=-2/p;d.n34=-i;d.n41=0;d.n42=0;d.n43=0;d.n44=1;return d}; +THREE.Vertex=function(a,c){this.position=a||new THREE.Vector3;this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.normal=c||new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.normalScreen=new THREE.Vector3;this.tangent=new THREE.Vector4;this.__visible=true};THREE.Vertex.prototype={toString:function(){return"THREE.Vertex ( position: "+this.position+", normal: "+this.normal+" )"}}; +THREE.Face3=function(a,c,f,e,i){this.a=a;this.b=c;this.c=f;this.centroid=new THREE.Vector3;this.normal=e instanceof THREE.Vector3?e:new THREE.Vector3;this.vertexNormals=e instanceof Array?e:[];this.materials=i instanceof Array?i:[i]};THREE.Face3.prototype={toString:function(){return"THREE.Face3 ( "+this.a+", "+this.b+", "+this.c+" )"}}; +THREE.Face4=function(a,c,f,e,i,k){this.a=a;this.b=c;this.c=f;this.d=e;this.centroid=new THREE.Vector3;this.normal=i instanceof THREE.Vector3?i:new THREE.Vector3;this.vertexNormals=i instanceof Array?i:[];this.materials=k instanceof Array?k:[k]};THREE.Face4.prototype={toString:function(){return"THREE.Face4 ( "+this.a+", "+this.b+", "+this.c+" "+this.d+" )"}};THREE.UV=function(a,c){this.u=a||0;this.v=c||0}; +THREE.UV.prototype={copy:function(a){this.u=a.u;this.v=a.v},toString:function(){return"THREE.UV ("+this.u+", "+this.v+")"}};THREE.Geometry=function(){this.vertices=[];this.faces=[];this.uvs=[];this.boundingSphere=this.boundingBox=null;this.geometryChunks={};this.hasTangents=false}; +THREE.Geometry.prototype={computeCentroids:function(){var a,c,f;a=0;for(c=this.faces.length;a0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x], +y:[this.vertices[0].position.y,this.vertices[0].position.y],z:[this.vertices[0].position.z,this.vertices[0].position.z]};for(var c=1,f=this.vertices.length;cthis.boundingBox.x[1])this.boundingBox.x[1]=a.position.x;if(a.position.ythis.boundingBox.y[1])this.boundingBox.y[1]=a.position.y;if(a.position.z< +this.boundingBox.z[0])this.boundingBox.z[0]=a.position.z;else if(a.position.z>this.boundingBox.z[1])this.boundingBox.z[1]=a.position.z}}},computeBoundingSphere:function(){for(var a=this.boundingSphere===null?0:this.boundingSphere.radius,c=0,f=this.vertices.length;c65535){p[s].counter+=1;m=p[s].hash+"_"+p[s].counter;if(this.geometryChunks[m]==undefined)this.geometryChunks[m]={faces:[],materials:d,vertices:0}}this.geometryChunks[m].faces.push(e); +this.geometryChunks[m].vertices+=k}},toString:function(){return"THREE.Geometry ( vertices: "+this.vertices+", faces: "+this.faces+", uvs: "+this.uvs+" )"}}; +THREE.Camera=function(a,c,f,e){this.fov=a;this.aspect=c;this.near=f;this.far=e;this.position=new THREE.Vector3;this.target={position:new THREE.Vector3};this.autoUpdateMatrix=true;this.projectionMatrix=null;this.matrix=new THREE.Matrix4;this.up=new THREE.Vector3(0,1,0);this.translateX=function(i){i=this.target.position.clone().subSelf(this.position).normalize().multiplyScalar(i);i.cross(i.clone(),this.up);this.position.addSelf(i);this.target.position.addSelf(i)};this.translateZ=function(i){i=this.target.position.clone().subSelf(this.position).normalize().multiplyScalar(i); +this.position.subSelf(i);this.target.position.subSelf(i)};this.updateMatrix=function(){this.matrix.lookAt(this.position,this.target.position,this.up)};this.updateProjectionMatrix=function(){this.projectionMatrix=THREE.Matrix4.makePerspective(this.fov,this.aspect,this.near,this.far)};this.updateProjectionMatrix()};THREE.Camera.prototype={toString:function(){return"THREE.Camera ( "+this.position+", "+this.target.position+" )"}};THREE.Light=function(a){this.color=new THREE.Color(a)}; +THREE.AmbientLight=function(a){THREE.Light.call(this,a)};THREE.AmbientLight.prototype=new THREE.Light;THREE.AmbientLight.prototype.constructor=THREE.AmbientLight;THREE.DirectionalLight=function(a,c){THREE.Light.call(this,a);this.position=new THREE.Vector3(0,1,0);this.intensity=c||1};THREE.DirectionalLight.prototype=new THREE.Light;THREE.DirectionalLight.prototype.constructor=THREE.DirectionalLight; +THREE.PointLight=function(a,c){THREE.Light.call(this,a);this.position=new THREE.Vector3;this.intensity=c||1};THREE.DirectionalLight.prototype=new THREE.Light;THREE.DirectionalLight.prototype.constructor=THREE.PointLight; +THREE.Object3D=function(){this.id=THREE.Object3DCounter.value++;this.position=new THREE.Vector3;this.rotation=new THREE.Vector3;this.scale=new THREE.Vector3(1,1,1);this.matrix=new THREE.Matrix4;this.translationMatrix=new THREE.Matrix4;this.rotationMatrix=new THREE.Matrix4;this.scaleMatrix=new THREE.Matrix4;this.screen=new THREE.Vector3;this.visible=this.autoUpdateMatrix=true}; +THREE.Object3D.prototype={updateMatrix:function(){this.matrixPosition=THREE.Matrix4.translationMatrix(this.position.x,this.position.y,this.position.z);this.rotationMatrix=THREE.Matrix4.rotationXMatrix(this.rotation.x);this.rotationMatrix.multiplySelf(THREE.Matrix4.rotationYMatrix(this.rotation.y));this.rotationMatrix.multiplySelf(THREE.Matrix4.rotationZMatrix(this.rotation.z));this.scaleMatrix=THREE.Matrix4.scaleMatrix(this.scale.x,this.scale.y,this.scale.z);this.matrix.copy(this.matrixPosition); +this.matrix.multiplySelf(this.rotationMatrix);this.matrix.multiplySelf(this.scaleMatrix)}};THREE.Object3DCounter={value:0};THREE.Particle=function(a){THREE.Object3D.call(this);this.materials=a instanceof Array?a:[a];this.autoUpdateMatrix=false};THREE.Particle.prototype=new THREE.Object3D;THREE.Particle.prototype.constructor=THREE.Particle;THREE.Line=function(a,c){THREE.Object3D.call(this);this.geometry=a;this.materials=c instanceof Array?c:[c]};THREE.Line.prototype=new THREE.Object3D; +THREE.Line.prototype.constructor=THREE.Line;THREE.Mesh=function(a,c){THREE.Object3D.call(this);this.geometry=a;this.materials=c instanceof Array?c:[c];this.overdraw=this.doubleSided=this.flipSided=false;this.geometry.boundingSphere||this.geometry.computeBoundingSphere()};THREE.Mesh.prototype=new THREE.Object3D;THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.FlatShading=0;THREE.SmoothShading=1;THREE.NormalBlending=0;THREE.AdditiveBlending=1;THREE.SubtractiveBlending=2; +THREE.LineBasicMaterial=function(a){this.color=new THREE.Color(16777215);this.opacity=1;this.blending=THREE.NormalBlending;this.linewidth=1;this.linejoin=this.linecap="round";if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending;if(a.linewidth!==undefined)this.linewidth=a.linewidth;if(a.linecap!==undefined)this.linecap=a.linecap;if(a.linejoin!==undefined)this.linejoin=a.linejoin}}; +THREE.LineBasicMaterial.prototype={toString:function(){return"THREE.LineBasicMaterial (
color: "+this.color+"
opacity: "+this.opacity+"
blending: "+this.blending+"
linewidth: "+this.linewidth+"
linecap: "+this.linecap+"
linejoin: "+this.linejoin+"
)"}}; +THREE.MeshBasicMaterial=function(a){this.id=THREE.MeshBasicMaterialCounter.value++;this.color=new THREE.Color(16777215);this.env_map=this.map=null;this.combine=THREE.MultiplyOperation;this.reflectivity=1;this.refraction_ratio=0.98;this.fog=true;this.opacity=1;this.shading=THREE.SmoothShading;this.blending=THREE.NormalBlending;this.wireframe=false;this.wireframe_linewidth=1;this.wireframe_linejoin=this.wireframe_linecap="round";if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map= +a.map;if(a.env_map!==undefined)this.env_map=a.env_map;if(a.combine!==undefined)this.combine=a.combine;if(a.reflectivity!==undefined)this.reflectivity=a.reflectivity;if(a.refraction_ratio!==undefined)this.refraction_ratio=a.refraction_ratio;if(a.fog!==undefined)this.fog=a.fog;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undefined)this.blending=a.blending;if(a.wireframe!==undefined)this.wireframe=a.wireframe;if(a.wireframe_linewidth!== +undefined)this.wireframe_linewidth=a.wireframe_linewidth;if(a.wireframe_linecap!==undefined)this.wireframe_linecap=a.wireframe_linecap;if(a.wireframe_linejoin!==undefined)this.wireframe_linejoin=a.wireframe_linejoin}}; +THREE.MeshBasicMaterial.prototype={toString:function(){return"THREE.MeshBasicMaterial (
id: "+this.id+"
color: "+this.color+"
map: "+this.map+"
env_map: "+this.env_map+"
combine: "+this.combine+"
reflectivity: "+this.reflectivity+"
refraction_ratio: "+this.refraction_ratio+"
opacity: "+this.opacity+"
blending: "+this.blending+"
wireframe: "+this.wireframe+"
wireframe_linewidth: "+this.wireframe_linewidth+"
wireframe_linecap: "+this.wireframe_linecap+ +"
wireframe_linejoin: "+this.wireframe_linejoin+"
)"}};THREE.MeshBasicMaterialCounter={value:0}; +THREE.MeshLambertMaterial=function(a){this.id=THREE.MeshLambertMaterialCounter.value++;this.color=new THREE.Color(16777215);this.env_map=this.map=null;this.combine=THREE.MultiplyOperation;this.reflectivity=1;this.refraction_ratio=0.98;this.fog=true;this.opacity=1;this.shading=THREE.SmoothShading;this.blending=THREE.NormalBlending;this.wireframe=false;this.wireframe_linewidth=1;this.wireframe_linejoin=this.wireframe_linecap="round";if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map= +a.map;if(a.env_map!==undefined)this.env_map=a.env_map;if(a.combine!==undefined)this.combine=a.combine;if(a.reflectivity!==undefined)this.reflectivity=a.reflectivity;if(a.refraction_ratio!==undefined)this.refraction_ratio=a.refraction_ratio;if(a.fog!==undefined)this.fog=a.fog;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undefined)this.blending=a.blending;if(a.wireframe!==undefined)this.wireframe=a.wireframe;if(a.wireframe_linewidth!== +undefined)this.wireframe_linewidth=a.wireframe_linewidth;if(a.wireframe_linecap!==undefined)this.wireframe_linecap=a.wireframe_linecap;if(a.wireframe_linejoin!==undefined)this.wireframe_linejoin=a.wireframe_linejoin}}; +THREE.MeshLambertMaterial.prototype={toString:function(){return"THREE.MeshLambertMaterial (
id: "+this.id+"
color: "+this.color+"
map: "+this.map+"
env_map: "+this.env_map+"
combine: "+this.combine+"
reflectivity: "+this.reflectivity+"
refraction_ratio: "+this.refraction_ratio+"
opacity: "+this.opacity+"
shading: "+this.shading+"
blending: "+this.blending+"
wireframe: "+this.wireframe+"
wireframe_linewidth: "+this.wireframe_linewidth+"
wireframe_linecap: "+ +this.wireframe_linecap+"
wireframe_linejoin: "+this.wireframe_linejoin+"
)"}};THREE.MeshLambertMaterialCounter={value:0}; +THREE.MeshPhongMaterial=function(a){this.id=THREE.MeshPhongMaterialCounter.value++;this.color=new THREE.Color(16777215);this.ambient=new THREE.Color(328965);this.specular=new THREE.Color(1118481);this.shininess=30;this.env_map=this.specular_map=this.map=null;this.combine=THREE.MultiplyOperation;this.reflectivity=1;this.refraction_ratio=0.98;this.fog=true;this.opacity=1;this.shading=THREE.SmoothShading;this.blending=THREE.NormalBlending;this.wireframe=false;this.wireframe_linewidth=1;this.wireframe_linejoin= +this.wireframe_linecap="round";if(a){if(a.color!==undefined)this.color=new THREE.Color(a.color);if(a.ambient!==undefined)this.ambient=new THREE.Color(a.ambient);if(a.specular!==undefined)this.specular=new THREE.Color(a.specular);if(a.shininess!==undefined)this.shininess=a.shininess;if(a.map!==undefined)this.map=a.map;if(a.specular_map!==undefined)this.specular_map=a.specular_map;if(a.env_map!==undefined)this.env_map=a.env_map;if(a.combine!==undefined)this.combine=a.combine;if(a.reflectivity!==undefined)this.reflectivity= +a.reflectivity;if(a.refraction_ratio!==undefined)this.refraction_ratio=a.refraction_ratio;if(a.fog!==undefined)this.fog=a.fog;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undefined)this.blending=a.blending;if(a.wireframe!==undefined)this.wireframe=a.wireframe;if(a.wireframe_linewidth!==undefined)this.wireframe_linewidth=a.wireframe_linewidth;if(a.wireframe_linecap!==undefined)this.wireframe_linecap=a.wireframe_linecap;if(a.wireframe_linejoin!== +undefined)this.wireframe_linejoin=a.wireframe_linejoin}}; +THREE.MeshPhongMaterial.prototype={toString:function(){return"THREE.MeshPhongMaterial (
id: "+this.id+"
color: "+this.color+"
ambient: "+this.ambient+"
specular: "+this.specular+"
shininess: "+this.shininess+"
map: "+this.map+"
specular_map: "+this.specular_map+"
env_map: "+this.env_map+"
combine: "+this.combine+"
reflectivity: "+this.reflectivity+"
refraction_ratio: "+this.refraction_ratio+"
opacity: "+this.opacity+"
shading: "+this.shading+"
wireframe: "+ +this.wireframe+"
wireframe_linewidth: "+this.wireframe_linewidth+"
wireframe_linecap: "+this.wireframe_linecap+"
wireframe_linejoin: "+this.wireframe_linejoin+"
)"}};THREE.MeshPhongMaterialCounter={value:0}; +THREE.MeshDepthMaterial=function(a){this.opacity=1;this.shading=THREE.SmoothShading;this.blending=THREE.NormalBlending;this.wireframe=false;this.wireframe_linewidth=1;this.wireframe_linejoin=this.wireframe_linecap="round";if(a){if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}};THREE.MeshDepthMaterial.prototype={toString:function(){return"THREE.MeshDepthMaterial"}}; +THREE.MeshNormalMaterial=function(a){this.opacity=1;this.shading=THREE.FlatShading;this.blending=THREE.NormalBlending;if(a){if(a.opacity!==undefined)this.opacity=a.opacity;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undefined)this.blending=a.blending}};THREE.MeshNormalMaterial.prototype={toString:function(){return"THREE.MeshNormalMaterial"}};THREE.MeshFaceMaterial=function(){};THREE.MeshFaceMaterial.prototype={toString:function(){return"THREE.MeshFaceMaterial"}}; +THREE.MeshShaderMaterial=function(a){this.id=THREE.MeshShaderMaterialCounter.value++;this.vertex_shader=this.fragment_shader="void main() {}";this.uniforms={};this.opacity=1;this.shading=THREE.SmoothShading;this.blending=THREE.NormalBlending;this.wireframe=false;this.wireframe_linewidth=1;this.wireframe_linejoin=this.wireframe_linecap="round";if(a){if(a.fragment_shader!==undefined)this.fragment_shader=a.fragment_shader;if(a.vertex_shader!==undefined)this.vertex_shader=a.vertex_shader;if(a.uniforms!== +undefined)this.uniforms=a.uniforms;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undefined)this.blending=a.blending;if(a.wireframe!==undefined)this.wireframe=a.wireframe;if(a.wireframe_linewidth!==undefined)this.wireframe_linewidth=a.wireframe_linewidth;if(a.wireframe_linecap!==undefined)this.wireframe_linecap=a.wireframe_linecap;if(a.wireframe_linejoin!==undefined)this.wireframe_linejoin=a.wireframe_linejoin}}; +THREE.MeshShaderMaterial.prototype={toString:function(){return"THREE.MeshShaderMaterial (
id: "+this.id+"
blending: "+this.blending+"
wireframe: "+this.wireframe+"
wireframe_linewidth: "+this.wireframe_linewidth+"
wireframe_linecap: "+this.wireframe_linecap+"
wireframe_linejoin: "+this.wireframe_linejoin+"
)"}};THREE.MeshShaderMaterialCounter={value:0}; +THREE.ParticleBasicMaterial=function(a){this.color=new THREE.Color(16777215);this.map=null;this.opacity=1;this.blending=THREE.NormalBlending;this.offset=new THREE.Vector2;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map=a.map;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}}; +THREE.ParticleBasicMaterial.prototype={toString:function(){return"THREE.ParticleBasicMaterial (
color: "+this.color+"
map: "+this.map+"
opacity: "+this.opacity+"
blending: "+this.blending+"
)"}};THREE.ParticleCircleMaterial=function(a){this.color=new THREE.Color(16777215);this.opacity=1;this.blending=THREE.NormalBlending;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}}; +THREE.ParticleCircleMaterial.prototype={toString:function(){return"THREE.ParticleCircleMaterial (
color: "+this.color+"
opacity: "+this.opacity+"
blending: "+this.blending+"
)"}};THREE.ParticleDOMMaterial=function(a){this.domElement=a};THREE.ParticleDOMMaterial.prototype={toString:function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}}; +THREE.Texture=function(a,c,f,e,i,k){this.image=a;this.mapping=c!==undefined?c:new THREE.UVMapping;this.wrap_s=f!==undefined?f:THREE.ClampToEdgeWrapping;this.wrap_t=e!==undefined?e:THREE.ClampToEdgeWrapping;this.mag_filter=i!==undefined?i:THREE.LinearFilter;this.min_filter=k!==undefined?k:THREE.LinearMipMapLinearFilter}; +THREE.Texture.prototype={clone:function(){return new THREE.Texture(this.image,this.mapping,this.wrap_s,this.wrap_t,this.mag_filter,this.min_filter)},toString:function(){return"THREE.Texture (
image: "+this.image+"
wrap_s: "+this.wrap_s+"
wrap_t: "+this.wrap_t+"
mag_filter: "+this.mag_filter+"
min_filter: "+this.min_filter+"
)"}};THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2; +THREE.NearestFilter=3;THREE.NearestMipMapNearestFilter=4;THREE.NearestMipMapLinearFilter=5;THREE.LinearFilter=6;THREE.LinearMipMapNearestFilter=7;THREE.LinearMipMapLinearFilter=8;var Uniforms={clone:function(a){var c,f,e,i={};for(c in a){i[c]={};for(f in a[c]){e=a[c][f];i[c][f]=e instanceof THREE.Color||e instanceof THREE.Vector3||e instanceof THREE.Texture?e.clone():e}}return i},merge:function(a){var c,f,e,i={};for(c=0;c=0&&w>=0&&v>=0&&G>=0)return true;else if(A<0&&w<0||v<0&&G<0)return false;else{if(A<0)x=Math.max(x,A/(A-w));else if(w<0)u=Math.min(u,A/(A-w));if(v<0)x=Math.max(x,v/(v-G));else if(G<0)u=Math.min(u,v/(v-G));if(uA&&H.z0&&Q.z<1){z=O[C]=O[C]||new THREE.RenderableParticle;z.x=Q.x/Q.w;z.y=Q.y/Q.w;z.z=Q.z;z.rotation=I.rotation.z;z.scale.x=I.scale.x*Math.abs(z.x-(Q.x+o.projectionMatrix.n11)/(Q.w+o.projectionMatrix.n14)); +z.scale.y=I.scale.y*Math.abs(z.y-(Q.y+o.projectionMatrix.n22)/(Q.w+o.projectionMatrix.n24));z.materials=I.materials;u.push(z);C++}}}}x&&u.sort(a);return u};this.unprojectVector=function(l,o){var x=new THREE.Matrix4;x.multiply(THREE.Matrix4.makeInvert(o.matrix),THREE.Matrix4.makeInvert(o.projectionMatrix));x.multiplyVector3(l);return l}}; +THREE.DOMRenderer=function(){THREE.Renderer.call(this);var a=null,c=new THREE.Projector,f,e,i,k;this.domElement=document.createElement("div");this.setSize=function(d,s){f=d;e=s;i=f/2;k=e/2};this.render=function(d,s){var m,p,D,F,z,C,O,S;a=c.projectScene(d,s);m=0;for(p=a.length;m0){B.r+=ca.r*$;B.g+=ca.g*$;B.b+=ca.b*$}}else if($ instanceof THREE.PointLight){aa.sub($.position,U);aa.normalize();$=N.dot(aa)*ea;if($>0){B.r+=ca.r*$;B.g+=ca.g*$;B.b+=ca.b*$}}}}function Pa(y,U,N){if(N.opacity!=0){a(N.opacity);c(N.blending); +var B,L,$,ca,ea,fa;if(N instanceof THREE.ParticleBasicMaterial){if(N.map){ca=N.map;ea=ca.width>>1;fa=ca.height>>1;L=U.scale.x*s;$=U.scale.y*m;N=L*ea;B=$*fa;E.set(y.x-N,y.y-B,y.x+N,y.y+B);if(X.instersects(E)){p.save();p.translate(y.x,y.y);p.rotate(-U.rotation);p.scale(L,-$);p.translate(-ea,-fa);p.drawImage(ca,0,0);p.restore()}}}else if(N instanceof THREE.ParticleCircleMaterial){if(P){Y.r=ga.r+oa.r+pa.r;Y.g=ga.g+oa.g+pa.g;Y.b=ga.b+oa.b+pa.b;u.r=N.color.r*Y.r;u.g=N.color.g*Y.g;u.b=N.color.b*Y.b;u.updateStyleString()}else u.__styleString= +N.color.__styleString;N=U.scale.x*s;B=U.scale.y*m;E.set(y.x-N,y.y-B,y.x+N,y.y+B);if(X.instersects(E)){L=u.__styleString;if(S!=L)p.fillStyle=S=L;p.save();p.translate(y.x,y.y);p.rotate(-U.rotation);p.scale(N,B);p.beginPath();p.arc(0,0,1,0,Na,true);p.closePath();p.fill();p.restore()}}}}function Qa(y,U,N,B){if(B.opacity!=0){a(B.opacity);c(B.blending);p.beginPath();p.moveTo(y.positionScreen.x,y.positionScreen.y);p.lineTo(U.positionScreen.x,U.positionScreen.y);p.closePath();if(B instanceof THREE.LineBasicMaterial){u.__styleString= +B.color.__styleString;y=B.linewidth;if(Q!=y)p.lineWidth=Q=y;y=u.__styleString;if(O!=y)p.strokeStyle=O=y;p.stroke();E.inflate(B.linewidth*2)}}}function Ja(y,U,N,B,L,$){if(L.opacity!=0){a(L.opacity);c(L.blending);r=y.positionScreen.x;n=y.positionScreen.y;t=U.positionScreen.x;l=U.positionScreen.y;o=N.positionScreen.x;x=N.positionScreen.y;p.beginPath();p.moveTo(r,n);p.lineTo(t,l);p.lineTo(o,x);p.lineTo(r,n);p.closePath();if(L instanceof THREE.MeshBasicMaterial)if(L.map)L.map.image.loaded&&L.map.mapping instanceof +THREE.UVMapping&&wa(r,n,t,l,o,x,L.map.image,B.uvs[0].u,B.uvs[0].v,B.uvs[1].u,B.uvs[1].v,B.uvs[2].u,B.uvs[2].v);else if(L.env_map){if(L.env_map.image.loaded)if(L.env_map.mapping instanceof THREE.SphericalReflectionMapping){y=na.matrix;aa.copy(B.vertexNormalsWorld[0]);V=(aa.x*y.n11+aa.y*y.n12+aa.z*y.n13)*0.5+0.5;I=-(aa.x*y.n21+aa.y*y.n22+aa.z*y.n23)*0.5+0.5;aa.copy(B.vertexNormalsWorld[1]);M=(aa.x*y.n11+aa.y*y.n12+aa.z*y.n13)*0.5+0.5;R=-(aa.x*y.n21+aa.y*y.n22+aa.z*y.n23)*0.5+0.5;aa.copy(B.vertexNormalsWorld[2]); +K=(aa.x*y.n11+aa.y*y.n12+aa.z*y.n13)*0.5+0.5;J=-(aa.x*y.n21+aa.y*y.n22+aa.z*y.n23)*0.5+0.5;wa(r,n,t,l,o,x,L.env_map.image,V,I,M,R,K,J)}}else L.wireframe?Ba(L.color.__styleString,L.wireframe_linewidth):Ca(L.color.__styleString);else if(L instanceof THREE.MeshLambertMaterial){if(L.map&&!L.wireframe){L.map.mapping instanceof THREE.UVMapping&&wa(r,n,t,l,o,x,L.map.image,B.uvs[0].u,B.uvs[0].v,B.uvs[1].u,B.uvs[1].v,B.uvs[2].u,B.uvs[2].v);c(THREE.SubtractiveBlending)}if(P)if(!L.wireframe&&L.shading==THREE.SmoothShading&& +B.vertexNormalsWorld.length==3){A.r=w.r=v.r=ga.r;A.g=w.g=v.g=ga.g;A.b=w.b=v.b=ga.b;Aa($,B.v1.positionWorld,B.vertexNormalsWorld[0],A);Aa($,B.v2.positionWorld,B.vertexNormalsWorld[1],w);Aa($,B.v3.positionWorld,B.vertexNormalsWorld[2],v);G.r=(w.r+v.r)*0.5;G.g=(w.g+v.g)*0.5;G.b=(w.b+v.b)*0.5;T=Ka(A,w,v,G);wa(r,n,t,l,o,x,T,0,0,1,0,0,1)}else{Y.r=ga.r;Y.g=ga.g;Y.b=ga.b;Aa($,B.centroidWorld,B.normalWorld,Y);u.r=L.color.r*Y.r;u.g=L.color.g*Y.g;u.b=L.color.b*Y.b;u.updateStyleString();L.wireframe?Ba(u.__styleString, +L.wireframe_linewidth):Ca(u.__styleString)}else L.wireframe?Ba(L.color.__styleString,L.wireframe_linewidth):Ca(L.color.__styleString)}else if(L instanceof THREE.MeshDepthMaterial){Z=na.near;H=na.far;A.r=A.g=A.b=1-Fa(y.positionScreen.z,Z,H);w.r=w.g=w.b=1-Fa(U.positionScreen.z,Z,H);v.r=v.g=v.b=1-Fa(N.positionScreen.z,Z,H);G.r=(w.r+v.r)*0.5;G.g=(w.g+v.g)*0.5;G.b=(w.b+v.b)*0.5;T=Ka(A,w,v,G);wa(r,n,t,l,o,x,T,0,0,1,0,0,1)}else if(L instanceof THREE.MeshNormalMaterial){u.r=Ga(B.normalWorld.x);u.g=Ga(B.normalWorld.y); +u.b=Ga(B.normalWorld.z);u.updateStyleString();L.wireframe?Ba(u.__styleString,L.wireframe_linewidth):Ca(u.__styleString)}}}function Ba(y,U){if(O!=y)p.strokeStyle=O=y;if(Q!=U)p.lineWidth=Q=U;p.stroke();E.inflate(U*2)}function Ca(y){if(S!=y)p.fillStyle=S=y;p.fill()}function wa(y,U,N,B,L,$,ca,ea,fa,ka,ia,la,xa){var qa,ma;qa=ca.width-1;ma=ca.height-1;ea*=qa;fa*=ma;ka*=qa;ia*=ma;la*=qa;xa*=ma;N-=y;B-=U;L-=y;$-=U;ka-=ea;ia-=fa;la-=ea;xa-=fa;ma=1/(ka*xa-la*ia);qa=(xa*N-ia*L)*ma;ia=(xa*B-ia*$)*ma;N=(ka*L- +la*N)*ma;B=(ka*$-la*B)*ma;y=y-qa*ea-N*fa;U=U-ia*ea-B*fa;p.save();p.transform(qa,ia,N,B,y,U);p.clip();p.drawImage(ca,0,0);p.restore()}function Ka(y,U,N,B){var L=~~(y.r*255),$=~~(y.g*255);y=~~(y.b*255);var ca=~~(U.r*255),ea=~~(U.g*255);U=~~(U.b*255);var fa=~~(N.r*255),ka=~~(N.g*255);N=~~(N.b*255);var ia=~~(B.r*255),la=~~(B.g*255);B=~~(B.b*255);ha[0]=L<0?0:L>255?255:L;ha[1]=$<0?0:$>255?255:$;ha[2]=y<0?0:y>255?255:y;ha[4]=ca<0?0:ca>255?255:ca;ha[5]=ea<0?0:ea>255?255:ea;ha[6]=U<0?0:U>255?255:U;ha[8]=fa< +0?0:fa>255?255:fa;ha[9]=ka<0?0:ka>255?255:ka;ha[10]=N<0?0:N>255?255:N;ha[12]=ia<0?0:ia>255?255:ia;ha[13]=la<0?0:la>255?255:la;ha[14]=B<0?0:B>255?255:B;ua.putImageData(Ea,0,0);za.drawImage(ta,0,0);return va}function Fa(y,U,N){y=(y-U)/(N-U);return y*y*(3-2*y)}function Ga(y){y=(y+1)*0.5;return y<0?0:y>1?1:y}function Ha(y,U){var N=U.x-y.x,B=U.y-y.y,L=1/Math.sqrt(N*N+B*B);N*=L;B*=L;U.x+=N;U.y+=B;y.x-=N;y.y-=B}var Da,La,ba,ja,sa,Ia,Ma,ya;p.setTransform(1,0,0,-1,s,m);this.autoClear&&this.clear();f=e.projectScene(da, +na,this.sortElements);(P=da.lights.length>0)&&Oa(da);Da=0;for(La=f.length;Da0){M.r+=J.color.r*X;M.g+=J.color.g*X;M.b+=J.color.b*X}}else if(J instanceof THREE.PointLight){x.sub(J.position,I.centroidWorld);x.normalize();X=I.normalWorld.dot(x)*J.intensity;if(X>0){M.r+=J.color.r*X;M.g+=J.color.g*X;M.b+=J.color.b*X}}}}function c(V,I,M,R,K,J){v=e(G++);v.setAttribute("d","M "+V.positionScreen.x+ +" "+V.positionScreen.y+" L "+I.positionScreen.x+" "+I.positionScreen.y+" L "+M.positionScreen.x+","+M.positionScreen.y+"z");if(K instanceof THREE.MeshBasicMaterial)j.__styleString=K.color.__styleString;else if(K instanceof THREE.MeshLambertMaterial)if(h){r.r=n.r;r.g=n.g;r.b=n.b;a(J,R,r);j.r=K.color.r*r.r;j.g=K.color.g*r.g;j.b=K.color.b*r.b;j.updateStyleString()}else j.__styleString=K.color.__styleString;else if(K instanceof THREE.MeshDepthMaterial){o=1-K.__2near/(K.__farPlusNear-R.z*K.__farMinusNear); +j.setRGB(o,o,o)}else K instanceof THREE.MeshNormalMaterial&&j.setRGB(i(R.normalWorld.x),i(R.normalWorld.y),i(R.normalWorld.z));K.wireframe?v.setAttribute("style","fill: none; stroke: "+j.__styleString+"; stroke-width: "+K.wireframe_linewidth+"; stroke-opacity: "+K.opacity+"; stroke-linecap: "+K.wireframe_linecap+"; stroke-linejoin: "+K.wireframe_linejoin):v.setAttribute("style","fill: "+j.__styleString+"; fill-opacity: "+K.opacity);s.appendChild(v)}function f(V,I,M,R,K,J,X){v=e(G++);v.setAttribute("d", +"M "+V.positionScreen.x+" "+V.positionScreen.y+" L "+I.positionScreen.x+" "+I.positionScreen.y+" L "+M.positionScreen.x+","+M.positionScreen.y+" L "+R.positionScreen.x+","+R.positionScreen.y+"z");if(J instanceof THREE.MeshBasicMaterial)j.__styleString=J.color.__styleString;else if(J instanceof THREE.MeshLambertMaterial)if(h){r.r=n.r;r.g=n.g;r.b=n.b;a(X,K,r);j.r=J.color.r*r.r;j.g=J.color.g*r.g;j.b=J.color.b*r.b;j.updateStyleString()}else j.__styleString=J.color.__styleString;else if(J instanceof THREE.MeshDepthMaterial){o= +1-J.__2near/(J.__farPlusNear-K.z*J.__farMinusNear);j.setRGB(o,o,o)}else J instanceof THREE.MeshNormalMaterial&&j.setRGB(i(K.normalWorld.x),i(K.normalWorld.y),i(K.normalWorld.z));J.wireframe?v.setAttribute("style","fill: none; stroke: "+j.__styleString+"; stroke-width: "+J.wireframe_linewidth+"; stroke-opacity: "+J.opacity+"; stroke-linecap: "+J.wireframe_linecap+"; stroke-linejoin: "+J.wireframe_linejoin):v.setAttribute("style","fill: "+j.__styleString+"; fill-opacity: "+J.opacity);s.appendChild(v)} +function e(V){if(u[V]==null){u[V]=document.createElementNS("http://www.w3.org/2000/svg","path");T==0&&u[V].setAttribute("shape-rendering","crispEdges");return u[V]}return u[V]}function i(V){return V<0?Math.min((1+V)*0.5,0.5):0.5+Math.min(V*0.5,0.5)}var k=null,d=new THREE.Projector,s=document.createElementNS("http://www.w3.org/2000/svg","svg"),m,p,D,F,z,C,O,S,Q=new THREE.Rectangle,q=new THREE.Rectangle,h=false,j=new THREE.Color(16777215),r=new THREE.Color(16777215),n=new THREE.Color(0),t=new THREE.Color(0), +l=new THREE.Color(0),o,x=new THREE.Vector3,u=[],A=[],w=[],v,G,Z,H,T=1;this.domElement=s;this.sortElements=this.sortObjects=this.autoClear=true;this.setQuality=function(V){switch(V){case "high":T=1;break;case "low":T=0}};this.setSize=function(V,I){m=V;p=I;D=m/2;F=p/2;s.setAttribute("viewBox",-D+" "+-F+" "+m+" "+p);s.setAttribute("width",m);s.setAttribute("height",p);Q.set(-D,-F,D,F)};this.clear=function(){for(;s.childNodes.length>0;)s.removeChild(s.childNodes[0])};this.render=function(V,I){var M,R, +K,J,X,W,E,P;this.autoClear&&this.clear();k=d.projectScene(V,I,this.sortElements);H=Z=G=0;if(h=V.lights.length>0){E=V.lights;n.setRGB(0,0,0);t.setRGB(0,0,0);l.setRGB(0,0,0);M=0;for(R=E.length;M0){R.__webGLUVBuffer=d.createBuffer();d.bindBuffer(d.ARRAY_BUFFER,R.__webGLUVBuffer);d.bufferData(d.ARRAY_BUFFER, +new Float32Array(I),d.STATIC_DRAW)}R.__webGLFaceBuffer=d.createBuffer();d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,R.__webGLFaceBuffer);d.bufferData(d.ELEMENT_ARRAY_BUFFER,new Uint16Array(G),d.STATIC_DRAW);R.__webGLLineBuffer=d.createBuffer();d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,R.__webGLLineBuffer);d.bufferData(d.ELEMENT_ARRAY_BUFFER,new Uint16Array(Z),d.STATIC_DRAW);R.__webGLFaceCount=G.length;R.__webGLLineCount=Z.length}};this.renderBuffer=function(h,j,r,n,t){var l,o,x,u;if(!n.program){if(n instanceof +THREE.MeshDepthMaterial){c(n,THREE.ShaderLib.depth);n.uniforms.mNear.value=h.near;n.uniforms.mFar.value=h.far}else if(n instanceof THREE.MeshNormalMaterial)c(n,THREE.ShaderLib.normal);else if(n instanceof THREE.MeshBasicMaterial){c(n,THREE.ShaderLib.basic);f(n,r)}else if(n instanceof THREE.MeshLambertMaterial){c(n,THREE.ShaderLib.lambert);f(n,r)}else if(n instanceof THREE.MeshPhongMaterial){c(n,THREE.ShaderLib.phong);f(n,r)}if(scene){var A,w,v;A=u=o=0;for(w=j.length;A0?"#define VERTEX_TEXTURES":"","#define MAX_DIR_LIGHTS "+u.maxDirLights,"#define MAX_POINT_LIGHTS "+u.maxPointLights,u.map?"#define USE_MAP":"",u.env_map?"#define USE_ENVMAP":"","uniform mat4 objectMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"].join("\n"); +d.attachShader(w,e("fragment",v+o));d.attachShader(w,e("vertex",u+A));d.linkProgram(w);d.getProgramParameter(w,d.LINK_STATUS)||alert("Could not initialise shaders\nVALIDATE_STATUS: "+d.getProgramParameter(w,d.VALIDATE_STATUS)+", gl error ["+d.getError()+"]");w.uniforms={};w.attributes={};n.program=w;o=["viewMatrix","modelViewMatrix","projectionMatrix","normalMatrix","objectMatrix","cameraPosition"];for(l in n.uniforms)o.push(l);l=n.program;A=0;for(w=o.length;A=0){d.bindBuffer(d.ARRAY_BUFFER,t.__webGLNormalBuffer);d.vertexAttribPointer(x.normal, +3,d.FLOAT,false,0,0);d.enableVertexAttribArray(x.normal)}if(x.tangent>=0){d.bindBuffer(d.ARRAY_BUFFER,t.__webGLTangentBuffer);d.vertexAttribPointer(x.tangent,4,d.FLOAT,false,0,0);d.enableVertexAttribArray(x.tangent)}if(x.uv>=0)if(t.__webGLUVBuffer){d.bindBuffer(d.ARRAY_BUFFER,t.__webGLUVBuffer);d.vertexAttribPointer(x.uv,2,d.FLOAT,false,0,0);d.enableVertexAttribArray(x.uv)}else d.disableVertexAttribArray(x.uv);if(n.wireframe){d.lineWidth(n.wireframe_linewidth);d.bindBuffer(d.ELEMENT_ARRAY_BUFFER, +t.__webGLLineBuffer);d.drawElements(d.LINES,t.__webGLLineCount,d.UNSIGNED_SHORT,0)}else{d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,t.__webGLFaceBuffer);d.drawElements(d.TRIANGLES,t.__webGLFaceCount,d.UNSIGNED_SHORT,0)}};this.renderPass=function(h,j,r,n,t,l,o){var x,u,A,w,v;A=0;for(w=n.materials.length;A=0;r--){n=h.__webGLObjects[r].object;j==n&&h.__webGLObjects.splice(r, +1)}};this.setupMatrices=function(h,j){h.autoUpdateMatrix&&h.updateMatrix();m.multiply(j.matrix,h.matrix);F.set(m.flatten());p=THREE.Matrix4.makeInvert3x3(m).transpose();C.set(p.m);O.set(h.matrix.flatten())};this.loadMatrices=function(h){d.uniformMatrix4fv(h.uniforms.viewMatrix,false,D);d.uniformMatrix4fv(h.uniforms.modelViewMatrix,false,F);d.uniformMatrix4fv(h.uniforms.projectionMatrix,false,z);d.uniformMatrix3fv(h.uniforms.normalMatrix,false,C);d.uniformMatrix4fv(h.uniforms.objectMatrix,false,O)}; +this.loadCamera=function(h,j){d.uniform3f(h.uniforms.cameraPosition,j.position.x,j.position.y,j.position.z)};this.setBlending=function(h){switch(h){case THREE.AdditiveBlending:d.blendEquation(d.FUNC_ADD);d.blendFunc(d.ONE,d.ONE);break;case THREE.SubtractiveBlending:d.blendFunc(d.DST_COLOR,d.ZERO);break;default:d.blendEquation(d.FUNC_ADD);d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA)}};this.setFaceCulling=function(h,j){if(h){!j||j=="ccw"?d.frontFace(d.CCW):d.frontFace(d.CW);if(h=="back")d.cullFace(d.BACK); +else h=="front"?d.cullFace(d.FRONT):d.cullFace(d.FRONT_AND_BACK);d.enable(d.CULL_FACE)}else d.disable(d.CULL_FACE)};this.supportsVertexTextures=function(){return d.getParameter(d.MAX_VERTEX_TEXTURE_IMAGE_UNITS)>0}}; +THREE.Snippets={fog_pars_fragment:"#ifdef USE_FOG\nuniform vec3 fogColor;\n#ifdef FOG_EXP2\nuniform float fogDensity;\n#else\nuniform float fogNear;\nuniform float fogFar;\n#endif\n#endif",fog_fragment:"#ifdef USE_FOG\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n#ifdef FOG_EXP2\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n#else\nfloat fogFactor = smoothstep( fogNear, fogFar, depth );\n#endif\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, 1.0 ), fogFactor );\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\nvarying vec3 vReflect;\nuniform float reflectivity;\nuniform samplerCube env_map;\nuniform int combine;\n#endif", +envmap_fragment:"#ifdef USE_ENVMAP\ncubeColor = textureCube( env_map, vec3( -vReflect.x, vReflect.yz ) );\nif ( combine == 1 ) {\ngl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );\n} else {\ngl_FragColor = gl_FragColor * cubeColor;\n}\n#endif",envmap_pars_vertex:"#ifdef USE_ENVMAP\nvarying vec3 vReflect;\nuniform float refraction_ratio;\nuniform bool useRefract;\n#endif",envmap_vertex:"#ifdef USE_ENVMAP\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nif ( useRefract ) {\nvReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refraction_ratio );\n} else {\nvReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );\n}\n#endif", +map_pars_fragment:"#ifdef USE_MAP\nvarying vec2 vUv;\nuniform sampler2D map;\n#endif",map_pars_vertex:"#ifdef USE_MAP\nvarying vec2 vUv;\n#endif",map_fragment:"#ifdef USE_MAP\nmapColor = texture2D( map, vUv );\n#endif",map_vertex:"#ifdef USE_MAP\nvUv = uv;\n#endif",lights_pars_vertex:"uniform bool enableLighting;\nuniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\n#ifdef PHONG\nvarying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];\n#endif\n#endif", +lights_vertex:"if ( !enableLighting ) {\nvLightWeighting = vec3( 1.0 );\n} else {\nvLightWeighting = ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nfloat directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );\nvLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;\n}\n#endif\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 pointLightVector = normalize( lPosition.xyz - mvPosition.xyz );\nfloat pointLightWeighting = max( dot( transformedNormal, pointLightVector ), 0.0 );\nvLightWeighting += pointLightColor[ i ] * pointLightWeighting;\n#ifdef PHONG\nvPointLightVector[ i ] = pointLightVector;\n#endif\n}\n#endif\n}", +lights_pars_fragment:"#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nvarying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];\n#endif\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;",lights_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\nvec4 mSpecular = vec4( specular, opacity );\n#if MAX_POINT_LIGHTS > 0\nvec4 pointDiffuse = vec4( 0.0 );\nvec4 pointSpecular = vec4( 0.0 );\nfor( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {\nvec3 pointVector = normalize( vPointLightVector[ i ] );\nvec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );\nfloat pointDotNormalHalf = dot( normal, pointHalfVector );\nfloat pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );\nfloat pointSpecularWeight = 0.0;\nif ( pointDotNormalHalf >= 0.0 )\npointSpecularWeight = pow( pointDotNormalHalf, shininess );\npointDiffuse += mColor * pointDiffuseWeight;\npointSpecular += mSpecular * pointSpecularWeight;\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec4 dirDiffuse = vec4( 0.0 );\nvec4 dirSpecular = vec4( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nvec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );\nfloat dirDotNormalHalf = dot( normal, dirHalfVector );\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\nfloat dirSpecularWeight = 0.0;\nif ( dirDotNormalHalf >= 0.0 )\ndirSpecularWeight = pow( dirDotNormalHalf, shininess );\ndirDiffuse += mColor * dirDiffuseWeight;\ndirSpecular += mSpecular * dirSpecularWeight;\n}\n#endif\nvec4 totalLight = vec4( ambient, opacity );\n#if MAX_DIR_LIGHTS > 0\ntotalLight += dirDiffuse + dirSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalLight += pointDiffuse + pointSpecular;\n#endif"}; +THREE.UniformsLib={common:{color:{type:"c",value:new THREE.Color(15658734)},opacity:{type:"f",value:1},map:{type:"t",value:0,texture:null},env_map:{type:"t",value:1,texture:null},useRefract:{type:"i",value:0},reflectivity:{type:"f",value:1},refraction_ratio:{type:"f",value:0.98},combine:{type:"i",value:0},fogDensity:{type:"f",value:2.5E-4},fogNear:{type:"f",value:1},fogFar:{type:"f",value:2E3},fogColor:{type:"c",value:new THREE.Color(16777215)}},lights:{enableLighting:{type:"i",value:1},ambientLightColor:{type:"fv", +value:[]},directionalLightDirection:{type:"fv",value:[]},directionalLightColor:{type:"fv",value:[]},pointLightPosition:{type:"fv",value:[]},pointLightColor:{type:"fv",value:[]}}}; +THREE.ShaderLib={depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3}},fragment_shader:"uniform float mNear;\nuniform float mFar;\nvoid main() {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat color = 1.0 - smoothstep( mNear, mFar, depth );\ngl_FragColor = vec4( vec3( color ), 1.0 );\n}",vertex_shader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"},normal:{uniforms:{},fragment_shader:"varying vec3 vNormal;\nvoid main() {\ngl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, 1.0 );\n}", +vertex_shader:"varying vec3 vNormal;\nvoid main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvNormal = normalize( normalMatrix * normal );\ngl_Position = projectionMatrix * mvPosition;\n}"},basic:{uniforms:THREE.UniformsLib.common,fragment_shader:["uniform vec3 color;\nuniform float opacity;",THREE.Snippets.map_pars_fragment,THREE.Snippets.envmap_pars_fragment,THREE.Snippets.fog_pars_fragment,"void main() {\nvec4 mColor = vec4( color, opacity );\nvec4 mapColor = vec4( 1.0 );\nvec4 cubeColor = vec4( 1.0 );", +THREE.Snippets.map_fragment,"gl_FragColor = mColor * mapColor;",THREE.Snippets.envmap_fragment,THREE.Snippets.fog_fragment,"}"].join("\n"),vertex_shader:[THREE.Snippets.map_pars_vertex,THREE.Snippets.envmap_pars_vertex,"void main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",THREE.Snippets.map_vertex,THREE.Snippets.envmap_vertex,"gl_Position = projectionMatrix * mvPosition;\n}"].join("\n")},lambert:{uniforms:Uniforms.merge([THREE.UniformsLib.common,THREE.UniformsLib.lights]),fragment_shader:["uniform vec3 color;\nuniform float opacity;\nvarying vec3 vLightWeighting;", +THREE.Snippets.map_pars_fragment,THREE.Snippets.envmap_pars_fragment,THREE.Snippets.fog_pars_fragment,"void main() {\nvec4 mColor = vec4( color, opacity );\nvec4 mapColor = vec4( 1.0 );\nvec4 cubeColor = vec4( 1.0 );",THREE.Snippets.map_fragment,"gl_FragColor = mColor * mapColor * vec4( vLightWeighting, 1.0 );",THREE.Snippets.envmap_fragment,THREE.Snippets.fog_fragment,"}"].join("\n"),vertex_shader:["varying vec3 vLightWeighting;",THREE.Snippets.map_pars_vertex,THREE.Snippets.envmap_pars_vertex, +THREE.Snippets.lights_pars_vertex,"void main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",THREE.Snippets.map_vertex,THREE.Snippets.envmap_vertex,"vec3 transformedNormal = normalize( normalMatrix * normal );",THREE.Snippets.lights_vertex,"gl_Position = projectionMatrix * mvPosition;\n}"].join("\n")},phong:{uniforms:Uniforms.merge([THREE.UniformsLib.common,THREE.UniformsLib.lights,{ambient:{type:"c",value:new THREE.Color(328965)},specular:{type:"c",value:new THREE.Color(1118481)}, +shininess:{type:"f",value:30}}]),fragment_shader:["uniform vec3 color;\nuniform float opacity;\nuniform vec3 ambient;\nuniform vec3 specular;\nuniform float shininess;\nvarying vec3 vLightWeighting;",THREE.Snippets.map_pars_fragment,THREE.Snippets.envmap_pars_fragment,THREE.Snippets.fog_pars_fragment,THREE.Snippets.lights_pars_fragment,"void main() {\nvec4 mColor = vec4( color, opacity );\nvec4 mapColor = vec4( 1.0 );\nvec4 cubeColor = vec4( 1.0 );",THREE.Snippets.map_fragment,THREE.Snippets.lights_fragment, +"gl_FragColor = mapColor * totalLight * vec4( vLightWeighting, 1.0 );",THREE.Snippets.envmap_fragment,THREE.Snippets.fog_fragment,"}"].join("\n"),vertex_shader:["#define PHONG\nvarying vec3 vLightWeighting;\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;",THREE.Snippets.map_pars_vertex,THREE.Snippets.envmap_pars_vertex,THREE.Snippets.lights_pars_vertex,"void main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",THREE.Snippets.map_vertex,THREE.Snippets.envmap_vertex,"#ifndef USE_ENVMAP\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\n#endif\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 transformedNormal = normalize( normalMatrix * normal );\nvNormal = transformedNormal;", +THREE.Snippets.lights_vertex,"gl_Position = projectionMatrix * mvPosition;\n}"].join("\n")}};THREE.RenderableObject=function(){this.z=this.object=null};THREE.RenderableFace3=function(){this.z=null;this.v1=new THREE.Vertex;this.v2=new THREE.Vertex;this.v3=new THREE.Vertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[];this.faceMaterials=this.meshMaterials=null;this.overdraw=false;this.uvs=[null,null,null]}; +THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=null;this.scale=new THREE.Vector2;this.materials=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.Vertex;this.v2=new THREE.Vertex;this.materials=null}; diff --git a/backend/resources/3d/WebGLRenderer.js b/backend/resources/3d/WebGLRenderer.js new file mode 100644 index 0000000..d7645cd --- /dev/null +++ b/backend/resources/3d/WebGLRenderer.js @@ -0,0 +1,4024 @@ +/** + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ + +THREE.WebGLRenderer = function ( parameters ) { + + // Currently you can use just up to 4 directional / point lights total. + // Chrome barfs on shader linking when there are more than 4 lights :( + + // The problem comes from shader using too many varying vectors. + + // This is not GPU limitation as the same shader works ok in Firefox + // and Chrome with "--use-gl=desktop" flag. + + // Difference comes from Chrome on Windows using by default ANGLE, + // thus going DirectX9 route (while FF uses OpenGL). + + // See http://code.google.com/p/chromium/issues/detail?id=63491 + + var _canvas = document.createElement( 'canvas' ), _gl, + _oldProgram = null, + _oldFramebuffer = null, + + _this = this, + + // gl state cache + + _oldDoubleSided = null, + _oldFlipSided = null, + _oldBlending = null, + _oldDepth = null, + + _viewportX = 0, + _viewportY = 0, + _viewportWidth = 0, + _viewportHeight = 0, + + // camera matrices caches + + _frustum = [ + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4() + ], + + _projScreenMatrix = new THREE.Matrix4(), + _projectionMatrixArray = new Float32Array( 16 ), + _viewMatrixArray = new Float32Array( 16 ), + + _vector3 = new THREE.Vector4(), + + // light arrays cache + + _lights = { + + ambient: [ 0, 0, 0 ], + directional: { length: 0, colors: new Array(), positions: new Array() }, + point: { length: 0, colors: new Array(), positions: new Array() } + + }, + + // parameters defaults + + antialias = true, + clearColor = new THREE.Color( 0x000000 ), + clearAlpha = 0; + + if ( parameters ) { + + if ( parameters.antialias !== undefined ) antialias = parameters.antialias; + if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor ); + if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha; + + } + + this.domElement = _canvas; + this.autoClear = true; + this.sortObjects = true; + + initGL( antialias, clearColor, clearAlpha ); + + this.context = _gl; + + //alert( dumpObject( getGLParams() ) ); + + this.setSize = function ( width, height ) { + + _canvas.width = width; + _canvas.height = height; + + this.setViewport( 0, 0, _canvas.width, _canvas.height ); + + }; + + this.setViewport = function ( x, y, width, height ) { + + _viewportX = x; + _viewportY = y; + + _viewportWidth = width; + _viewportHeight = height; + + _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight ); + + }; + + this.setScissor = function ( x, y, width, height ) { + + _gl.scissor( x, y, width, height ); + + }; + + this.enableScissorTest = function ( enable ) { + + if ( enable ) + _gl.enable( _gl.SCISSOR_TEST ); + else + _gl.disable( _gl.SCISSOR_TEST ); + + }; + + this.enableDepthBufferWrite = function ( enable ) { + + _gl.depthMask( enable ); + + }; + + this.setClearColorHex = function ( hex, alpha ) { + + var color = new THREE.Color( hex ); + _gl.clearColor( color.r, color.g, color.b, alpha ); + + }; + + this.setClearColor = function ( color, alpha ) { + + _gl.clearColor( color.r, color.g, color.b, alpha ); + + }; + + this.clear = function () { + + _gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT ); + + }; + + + function setupLights ( program, lights ) { + + var l, ll, light, r = 0, g = 0, b = 0, + color, position, intensity, + + zlights = _lights, + + dcolors = zlights.directional.colors, + dpositions = zlights.directional.positions, + + pcolors = zlights.point.colors, + ppositions = zlights.point.positions, + + dlength = 0, + plength = 0, + + doffset = 0, + poffset = 0; + + for ( l = 0, ll = lights.length; l < ll; l++ ) { + + light = lights[ l ]; + color = light.color; + position = light.position; + intensity = light.intensity; + + if ( light instanceof THREE.AmbientLight ) { + + r += color.r; + g += color.g; + b += color.b; + + } else if ( light instanceof THREE.DirectionalLight ) { + + doffset = dlength * 3; + + dcolors[ doffset ] = color.r * intensity; + dcolors[ doffset + 1 ] = color.g * intensity; + dcolors[ doffset + 2 ] = color.b * intensity; + + dpositions[ doffset ] = position.x; + dpositions[ doffset + 1 ] = position.y; + dpositions[ doffset + 2 ] = position.z; + + dlength += 1; + + } else if( light instanceof THREE.PointLight ) { + + poffset = plength * 3; + + pcolors[ poffset ] = color.r * intensity; + pcolors[ poffset + 1 ] = color.g * intensity; + pcolors[ poffset + 2 ] = color.b * intensity; + + ppositions[ poffset ] = position.x; + ppositions[ poffset + 1 ] = position.y; + ppositions[ poffset + 2 ] = position.z; + + plength += 1; + + } + + } + + // null eventual remains from removed lights + // (this is to avoid if in shader) + + for( l = dlength * 3; l < dcolors.length; l++ ) dcolors[ l ] = 0.0; + for( l = plength * 3; l < pcolors.length; l++ ) pcolors[ l ] = 0.0; + + zlights.point.length = plength; + zlights.directional.length = dlength; + + zlights.ambient[ 0 ] = r; + zlights.ambient[ 1 ] = g; + zlights.ambient[ 2 ] = b; + + }; + + function createParticleBuffers ( geometry ) { + + geometry.__webGLVertexBuffer = _gl.createBuffer(); + geometry.__webGLColorBuffer = _gl.createBuffer(); + + }; + + function createLineBuffers ( geometry ) { + + geometry.__webGLVertexBuffer = _gl.createBuffer(); + geometry.__webGLColorBuffer = _gl.createBuffer(); + + }; + + function createRibbonBuffers ( geometry ) { + + geometry.__webGLVertexBuffer = _gl.createBuffer(); + geometry.__webGLColorBuffer = _gl.createBuffer(); + + }; + + function createMeshBuffers ( geometryGroup ) { + + geometryGroup.__webGLVertexBuffer = _gl.createBuffer(); + geometryGroup.__webGLNormalBuffer = _gl.createBuffer(); + geometryGroup.__webGLTangentBuffer = _gl.createBuffer(); + geometryGroup.__webGLColorBuffer = _gl.createBuffer(); + geometryGroup.__webGLUVBuffer = _gl.createBuffer(); + geometryGroup.__webGLUV2Buffer = _gl.createBuffer(); + + geometryGroup.__webGLSkinVertexABuffer = _gl.createBuffer(); + geometryGroup.__webGLSkinVertexBBuffer = _gl.createBuffer(); + geometryGroup.__webGLSkinIndicesBuffer = _gl.createBuffer(); + geometryGroup.__webGLSkinWeightsBuffer = _gl.createBuffer(); + + geometryGroup.__webGLFaceBuffer = _gl.createBuffer(); + geometryGroup.__webGLLineBuffer = _gl.createBuffer(); + + }; + + function initLineBuffers ( geometry ) { + + var nvertices = geometry.vertices.length; + + geometry.__vertexArray = new Float32Array( nvertices * 3 ); + geometry.__colorArray = new Float32Array( nvertices * 3 ); + + geometry.__webGLLineCount = nvertices; + + }; + + function initRibbonBuffers ( geometry ) { + + var nvertices = geometry.vertices.length; + + geometry.__vertexArray = new Float32Array( nvertices * 3 ); + geometry.__colorArray = new Float32Array( nvertices * 3 ); + + geometry.__webGLVertexCount = nvertices; + + }; + + function initParticleBuffers ( geometry ) { + + var nvertices = geometry.vertices.length; + + geometry.__vertexArray = new Float32Array( nvertices * 3 ); + geometry.__colorArray = new Float32Array( nvertices * 3 ); + + geometry.__sortArray = []; + + geometry.__webGLParticleCount = nvertices; + + }; + + function initMeshBuffers ( geometryGroup, object ) { + + var f, fl, nvertices = 0, ntris = 0, nlines = 0, + obj_faces = object.geometry.faces, + chunk_faces = geometryGroup.faces; + + for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) { + + fi = chunk_faces[ f ]; + face = obj_faces[ fi ]; + + if ( face instanceof THREE.Face3 ) { + + nvertices += 3; + ntris += 1; + nlines += 3; + + } else if ( face instanceof THREE.Face4 ) { + + nvertices += 4; + ntris += 2; + nlines += 4; + + } + + } + + // TODO: only create arrays for attributes existing in the object + + geometryGroup.__vertexArray = new Float32Array( nvertices * 3 ); + geometryGroup.__normalArray = new Float32Array( nvertices * 3 ); + geometryGroup.__tangentArray = new Float32Array( nvertices * 4 ); + geometryGroup.__colorArray = new Float32Array( nvertices * 3 ); + geometryGroup.__uvArray = new Float32Array( nvertices * 2 ); + geometryGroup.__uv2Array = new Float32Array( nvertices * 2 ); + + geometryGroup.__skinVertexAArray = new Float32Array( nvertices * 4 ); + geometryGroup.__skinVertexBArray = new Float32Array( nvertices * 4 ); + geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 ); + geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 ); + + geometryGroup.__faceArray = new Uint16Array( ntris * 3 ); + geometryGroup.__lineArray = new Uint16Array( nlines * 2 ); + + geometryGroup.__needsSmoothNormals = bufferNeedsSmoothNormals ( geometryGroup, object ); + + geometryGroup.__webGLFaceCount = ntris * 3; + geometryGroup.__webGLLineCount = nlines * 2; + + }; + + function setMeshBuffers ( geometryGroup, object, hint ) { + + var f, fl, fi, face, vertexNormals, faceNormal, normal, + uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, + c1, c2, c3, c4, + sw1, sw2, sw3, sw4, + si1, si2, si3, si4, + sa1, sa2, sa3, sa4, + sb1, sb2, sb3, sb4, + m, ml, i, + vn, uvi, uv2i, + + vertexIndex = 0, + + offset = 0, + offset_uv = 0, + offset_uv2 = 0, + offset_face = 0, + offset_normal = 0, + offset_tangent = 0, + offset_line = 0, + offset_color = 0, + offset_skin = 0, + + vertexArray = geometryGroup.__vertexArray, + uvArray = geometryGroup.__uvArray, + uv2Array = geometryGroup.__uv2Array, + normalArray = geometryGroup.__normalArray, + tangentArray = geometryGroup.__tangentArray, + colorArray = geometryGroup.__colorArray, + + skinVertexAArray = geometryGroup.__skinVertexAArray, + skinVertexBArray = geometryGroup.__skinVertexBArray, + skinIndexArray = geometryGroup.__skinIndexArray, + skinWeightArray = geometryGroup.__skinWeightArray, + + faceArray = geometryGroup.__faceArray, + lineArray = geometryGroup.__lineArray, + + needsSmoothNormals = geometryGroup.__needsSmoothNormals, + + geometry = object.geometry, // this is shared for all chunks + + dirtyVertices = geometry.__dirtyVertices, + dirtyElements = geometry.__dirtyElements, + dirtyUvs = geometry.__dirtyUvs, + dirtyNormals = geometry.__dirtyNormals, + dirtyTangents = geometry.__dirtyTangents, + dirtyColors = geometry.__dirtyColors, + + vertices = geometry.vertices, + chunk_faces = geometryGroup.faces, + obj_faces = geometry.faces, + obj_uvs = geometry.uvs, + obj_uvs2 = geometry.uvs2, + obj_colors = geometry.colors, + + obj_skinVerticesA = geometry.skinVerticesA, + obj_skinVerticesB = geometry.skinVerticesB, + obj_skinIndices = geometry.skinIndices, + obj_skinWeights = geometry.skinWeights; + + for ( f = 0, fl = chunk_faces.length; f < fl; f++ ) { + + fi = chunk_faces[ f ]; + face = obj_faces[ fi ]; + uv = obj_uvs[ fi ]; + uv2 = obj_uvs2[ fi ]; + + vertexNormals = face.vertexNormals; + faceNormal = face.normal; + + if ( face instanceof THREE.Face3 ) { + + if ( dirtyVertices ) { + + v1 = vertices[ face.a ].position; + v2 = vertices[ face.b ].position; + v3 = vertices[ face.c ].position; + + vertexArray[ offset ] = v1.x; + vertexArray[ offset + 1 ] = v1.y; + vertexArray[ offset + 2 ] = v1.z; + + vertexArray[ offset + 3 ] = v2.x; + vertexArray[ offset + 4 ] = v2.y; + vertexArray[ offset + 5 ] = v2.z; + + vertexArray[ offset + 6 ] = v3.x; + vertexArray[ offset + 7 ] = v3.y; + vertexArray[ offset + 8 ] = v3.z; + + offset += 9; + + } + + if ( obj_skinWeights.length ) { + + // weights + + sw1 = obj_skinWeights[ face.a ]; + sw2 = obj_skinWeights[ face.b ]; + sw3 = obj_skinWeights[ face.c ]; + + skinWeightArray[ offset_skin ] = sw1.x; + skinWeightArray[ offset_skin + 1 ] = sw1.y; + skinWeightArray[ offset_skin + 2 ] = sw1.z; + skinWeightArray[ offset_skin + 3 ] = sw1.w; + + skinWeightArray[ offset_skin + 4 ] = sw2.x; + skinWeightArray[ offset_skin + 5 ] = sw2.y; + skinWeightArray[ offset_skin + 6 ] = sw2.z; + skinWeightArray[ offset_skin + 7 ] = sw2.w; + + skinWeightArray[ offset_skin + 8 ] = sw3.x; + skinWeightArray[ offset_skin + 9 ] = sw3.y; + skinWeightArray[ offset_skin + 10 ] = sw3.z; + skinWeightArray[ offset_skin + 11 ] = sw3.w; + + // indices + + si1 = obj_skinIndices[ face.a ]; + si2 = obj_skinIndices[ face.b ]; + si3 = obj_skinIndices[ face.c ]; + + skinIndexArray[ offset_skin ] = si1.x; + skinIndexArray[ offset_skin + 1 ] = si1.y; + skinIndexArray[ offset_skin + 2 ] = si1.z; + skinIndexArray[ offset_skin + 3 ] = si1.w; + + skinIndexArray[ offset_skin + 4 ] = si2.x; + skinIndexArray[ offset_skin + 5 ] = si2.y; + skinIndexArray[ offset_skin + 6 ] = si2.z; + skinIndexArray[ offset_skin + 7 ] = si2.w; + + skinIndexArray[ offset_skin + 8 ] = si3.x; + skinIndexArray[ offset_skin + 9 ] = si3.y; + skinIndexArray[ offset_skin + 10 ] = si3.z; + skinIndexArray[ offset_skin + 11 ] = si3.w; + + // vertices A + + sa1 = obj_skinVerticesA[ face.a ]; + sa2 = obj_skinVerticesA[ face.b ]; + sa3 = obj_skinVerticesA[ face.c ]; + + skinVertexAArray[ offset_skin ] = sa1.x; + skinVertexAArray[ offset_skin + 1 ] = sa1.y; + skinVertexAArray[ offset_skin + 2 ] = sa1.z; + skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader + + skinVertexAArray[ offset_skin + 4 ] = sa2.x; + skinVertexAArray[ offset_skin + 5 ] = sa2.y; + skinVertexAArray[ offset_skin + 6 ] = sa2.z; + skinVertexAArray[ offset_skin + 7 ] = 1; + + skinVertexAArray[ offset_skin + 8 ] = sa3.x; + skinVertexAArray[ offset_skin + 9 ] = sa3.y; + skinVertexAArray[ offset_skin + 10 ] = sa3.z; + skinVertexAArray[ offset_skin + 11 ] = 1; + + // vertices B + + sb1 = obj_skinVerticesB[ face.a ]; + sb2 = obj_skinVerticesB[ face.b ]; + sb3 = obj_skinVerticesB[ face.c ]; + + skinVertexBArray[ offset_skin ] = sb1.x; + skinVertexBArray[ offset_skin + 1 ] = sb1.y; + skinVertexBArray[ offset_skin + 2 ] = sb1.z; + skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader + + skinVertexBArray[ offset_skin + 4 ] = sb2.x; + skinVertexBArray[ offset_skin + 5 ] = sb2.y; + skinVertexBArray[ offset_skin + 6 ] = sb2.z; + skinVertexBArray[ offset_skin + 7 ] = 1; + + skinVertexBArray[ offset_skin + 8 ] = sb3.x; + skinVertexBArray[ offset_skin + 9 ] = sb3.y; + skinVertexBArray[ offset_skin + 10 ] = sb3.z; + skinVertexBArray[ offset_skin + 11 ] = 1; + + offset_skin += 12; + + } + + if ( dirtyColors && obj_colors.length ) { + + c1 = obj_colors[ face.a ]; + c2 = obj_colors[ face.b ]; + c3 = obj_colors[ face.c ]; + + colorArray[ offset_color ] = c1.r; + colorArray[ offset_color + 1 ] = c1.g; + colorArray[ offset_color + 2 ] = c1.b; + + colorArray[ offset_color + 3 ] = c2.r; + colorArray[ offset_color + 4 ] = c2.g; + colorArray[ offset_color + 5 ] = c2.b; + + colorArray[ offset_color + 6 ] = c3.r; + colorArray[ offset_color + 7 ] = c3.g; + colorArray[ offset_color + 8 ] = c3.b; + + offset_color += 9; + + } + + if ( dirtyTangents && geometry.hasTangents ) { + + t1 = vertices[ face.a ].tangent; + t2 = vertices[ face.b ].tangent; + t3 = vertices[ face.c ].tangent; + + tangentArray[ offset_tangent ] = t1.x; + tangentArray[ offset_tangent + 1 ] = t1.y; + tangentArray[ offset_tangent + 2 ] = t1.z; + tangentArray[ offset_tangent + 3 ] = t1.w; + + tangentArray[ offset_tangent + 4 ] = t2.x; + tangentArray[ offset_tangent + 5 ] = t2.y; + tangentArray[ offset_tangent + 6 ] = t2.z; + tangentArray[ offset_tangent + 7 ] = t2.w; + + tangentArray[ offset_tangent + 8 ] = t3.x; + tangentArray[ offset_tangent + 9 ] = t3.y; + tangentArray[ offset_tangent + 10 ] = t3.z; + tangentArray[ offset_tangent + 11 ] = t3.w; + + offset_tangent += 12; + + } + + if ( dirtyNormals ) { + + if ( vertexNormals.length == 3 && needsSmoothNormals ) { + + for ( i = 0; i < 3; i ++ ) { + + vn = vertexNormals[ i ]; + + normalArray[ offset_normal ] = vn.x; + normalArray[ offset_normal + 1 ] = vn.y; + normalArray[ offset_normal + 2 ] = vn.z; + + offset_normal += 3; + + } + + } else { + + for ( i = 0; i < 3; i ++ ) { + + normalArray[ offset_normal ] = faceNormal.x; + normalArray[ offset_normal + 1 ] = faceNormal.y; + normalArray[ offset_normal + 2 ] = faceNormal.z; + + offset_normal += 3; + + } + + } + + } + + if ( dirtyUvs && uv ) { + + for ( i = 0; i < 3; i ++ ) { + + uvi = uv[ i ]; + + uvArray[ offset_uv ] = uvi.u; + uvArray[ offset_uv + 1 ] = uvi.v; + + offset_uv += 2; + + } + + } + + if ( dirtyUvs && uv2 ) { + + for ( i = 0; i < 3; i ++ ) { + + uv2i = uv2[ i ]; + + uv2Array[ offset_uv2 ] = uv2i.u; + uv2Array[ offset_uv2 + 1 ] = uv2i.v; + + offset_uv2 += 2; + + } + + } + + if( dirtyElements ) { + + faceArray[ offset_face ] = vertexIndex; + faceArray[ offset_face + 1 ] = vertexIndex + 1; + faceArray[ offset_face + 2 ] = vertexIndex + 2; + + offset_face += 3; + + lineArray[ offset_line ] = vertexIndex; + lineArray[ offset_line + 1 ] = vertexIndex + 1; + + lineArray[ offset_line + 2 ] = vertexIndex; + lineArray[ offset_line + 3 ] = vertexIndex + 2; + + lineArray[ offset_line + 4 ] = vertexIndex + 1; + lineArray[ offset_line + 5 ] = vertexIndex + 2; + + offset_line += 6; + + vertexIndex += 3; + + } + + + } else if ( face instanceof THREE.Face4 ) { + + if ( dirtyVertices ) { + + v1 = vertices[ face.a ].position; + v2 = vertices[ face.b ].position; + v3 = vertices[ face.c ].position; + v4 = vertices[ face.d ].position; + + vertexArray[ offset ] = v1.x; + vertexArray[ offset + 1 ] = v1.y; + vertexArray[ offset + 2 ] = v1.z; + + vertexArray[ offset + 3 ] = v2.x; + vertexArray[ offset + 4 ] = v2.y; + vertexArray[ offset + 5 ] = v2.z; + + vertexArray[ offset + 6 ] = v3.x; + vertexArray[ offset + 7 ] = v3.y; + vertexArray[ offset + 8 ] = v3.z; + + vertexArray[ offset + 9 ] = v4.x; + vertexArray[ offset + 10 ] = v4.y; + vertexArray[ offset + 11 ] = v4.z; + + offset += 12; + + } + + if ( obj_skinWeights.length ) { + + // weights + + sw1 = obj_skinWeights[ face.a ]; + sw2 = obj_skinWeights[ face.b ]; + sw3 = obj_skinWeights[ face.c ]; + sw4 = obj_skinWeights[ face.d ]; + + skinWeightArray[ offset_skin ] = sw1.x; + skinWeightArray[ offset_skin + 1 ] = sw1.y; + skinWeightArray[ offset_skin + 2 ] = sw1.z; + skinWeightArray[ offset_skin + 3 ] = sw1.w; + + skinWeightArray[ offset_skin + 4 ] = sw2.x; + skinWeightArray[ offset_skin + 5 ] = sw2.y; + skinWeightArray[ offset_skin + 6 ] = sw2.z; + skinWeightArray[ offset_skin + 7 ] = sw2.w; + + skinWeightArray[ offset_skin + 8 ] = sw3.x; + skinWeightArray[ offset_skin + 9 ] = sw3.y; + skinWeightArray[ offset_skin + 10 ] = sw3.z; + skinWeightArray[ offset_skin + 11 ] = sw3.w; + + skinWeightArray[ offset_skin + 12 ] = sw4.x; + skinWeightArray[ offset_skin + 13 ] = sw4.y; + skinWeightArray[ offset_skin + 14 ] = sw4.z; + skinWeightArray[ offset_skin + 15 ] = sw4.w; + + // indices + + si1 = obj_skinIndices[ face.a ]; + si2 = obj_skinIndices[ face.b ]; + si3 = obj_skinIndices[ face.c ]; + si4 = obj_skinIndices[ face.d ]; + + skinIndexArray[ offset_skin ] = si1.x; + skinIndexArray[ offset_skin + 1 ] = si1.y; + skinIndexArray[ offset_skin + 2 ] = si1.z; + skinIndexArray[ offset_skin + 3 ] = si1.w; + + skinIndexArray[ offset_skin + 4 ] = si2.x; + skinIndexArray[ offset_skin + 5 ] = si2.y; + skinIndexArray[ offset_skin + 6 ] = si2.z; + skinIndexArray[ offset_skin + 7 ] = si2.w; + + skinIndexArray[ offset_skin + 8 ] = si3.x; + skinIndexArray[ offset_skin + 9 ] = si3.y; + skinIndexArray[ offset_skin + 10 ] = si3.z; + skinIndexArray[ offset_skin + 11 ] = si3.w; + + skinIndexArray[ offset_skin + 12 ] = si4.x; + skinIndexArray[ offset_skin + 13 ] = si4.y; + skinIndexArray[ offset_skin + 14 ] = si4.z; + skinIndexArray[ offset_skin + 15 ] = si4.w; + + // vertices A + + sa1 = obj_skinVerticesA[ face.a ]; + sa2 = obj_skinVerticesA[ face.b ]; + sa3 = obj_skinVerticesA[ face.c ]; + sa4 = obj_skinVerticesA[ face.d ]; + + skinVertexAArray[ offset_skin ] = sa1.x; + skinVertexAArray[ offset_skin + 1 ] = sa1.y; + skinVertexAArray[ offset_skin + 2 ] = sa1.z; + skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader + + skinVertexAArray[ offset_skin + 4 ] = sa2.x; + skinVertexAArray[ offset_skin + 5 ] = sa2.y; + skinVertexAArray[ offset_skin + 6 ] = sa2.z; + skinVertexAArray[ offset_skin + 7 ] = 1; + + skinVertexAArray[ offset_skin + 8 ] = sa3.x; + skinVertexAArray[ offset_skin + 9 ] = sa3.y; + skinVertexAArray[ offset_skin + 10 ] = sa3.z; + skinVertexAArray[ offset_skin + 11 ] = 1; + + skinVertexAArray[ offset_skin + 12 ] = sa4.x; + skinVertexAArray[ offset_skin + 13 ] = sa4.y; + skinVertexAArray[ offset_skin + 14 ] = sa4.z; + skinVertexAArray[ offset_skin + 15 ] = 1; + + // vertices B + + sb1 = obj_skinVerticesB[ face.a ]; + sb2 = obj_skinVerticesB[ face.b ]; + sb3 = obj_skinVerticesB[ face.c ]; + sb4 = obj_skinVerticesB[ face.d ]; + + skinVertexBArray[ offset_skin ] = sb1.x; + skinVertexBArray[ offset_skin + 1 ] = sb1.y; + skinVertexBArray[ offset_skin + 2 ] = sb1.z; + skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader + + skinVertexBArray[ offset_skin + 4 ] = sb2.x; + skinVertexBArray[ offset_skin + 5 ] = sb2.y; + skinVertexBArray[ offset_skin + 6 ] = sb2.z; + skinVertexBArray[ offset_skin + 7 ] = 1; + + skinVertexBArray[ offset_skin + 8 ] = sb3.x; + skinVertexBArray[ offset_skin + 9 ] = sb3.y; + skinVertexBArray[ offset_skin + 10 ] = sb3.z; + skinVertexBArray[ offset_skin + 11 ] = 1; + + skinVertexBArray[ offset_skin + 12 ] = sb4.x; + skinVertexBArray[ offset_skin + 13 ] = sb4.y; + skinVertexBArray[ offset_skin + 14 ] = sb4.z; + skinVertexBArray[ offset_skin + 15 ] = 1; + + offset_skin += 16; + + } + + if ( dirtyColors && obj_colors.length ) { + + c1 = obj_colors[ face.a ]; + c2 = obj_colors[ face.b ]; + c3 = obj_colors[ face.c ]; + c4 = obj_colors[ face.d ]; + + colorArray[ offset_color ] = c1.r; + colorArray[ offset_color + 1 ] = c1.g; + colorArray[ offset_color + 2 ] = c1.b; + + colorArray[ offset_color + 3 ] = c2.r; + colorArray[ offset_color + 4 ] = c2.g; + colorArray[ offset_color + 5 ] = c2.b; + + colorArray[ offset_color + 6 ] = c3.r; + colorArray[ offset_color + 7 ] = c3.g; + colorArray[ offset_color + 8 ] = c3.b; + + colorArray[ offset_color + 9 ] = c4.r; + colorArray[ offset_color + 10 ] = c4.g; + colorArray[ offset_color + 11 ] = c4.b; + + offset_color += 12; + + } + + if ( dirtyTangents && geometry.hasTangents ) { + + t1 = vertices[ face.a ].tangent; + t2 = vertices[ face.b ].tangent; + t3 = vertices[ face.c ].tangent; + t4 = vertices[ face.d ].tangent; + + tangentArray[ offset_tangent ] = t1.x; + tangentArray[ offset_tangent + 1 ] = t1.y; + tangentArray[ offset_tangent + 2 ] = t1.z; + tangentArray[ offset_tangent + 3 ] = t1.w; + + tangentArray[ offset_tangent + 4 ] = t2.x; + tangentArray[ offset_tangent + 5 ] = t2.y; + tangentArray[ offset_tangent + 6 ] = t2.z; + tangentArray[ offset_tangent + 7 ] = t2.w; + + tangentArray[ offset_tangent + 8 ] = t3.x; + tangentArray[ offset_tangent + 9 ] = t3.y; + tangentArray[ offset_tangent + 10 ] = t3.z; + tangentArray[ offset_tangent + 11 ] = t3.w; + + tangentArray[ offset_tangent + 12 ] = t4.x; + tangentArray[ offset_tangent + 13 ] = t4.y; + tangentArray[ offset_tangent + 14 ] = t4.z; + tangentArray[ offset_tangent + 15 ] = t4.w; + + offset_tangent += 16; + + } + + if( dirtyNormals ) { + + if ( vertexNormals.length == 4 && needsSmoothNormals ) { + + for ( i = 0; i < 4; i ++ ) { + + vn = vertexNormals[ i ]; + + normalArray[ offset_normal ] = vn.x; + normalArray[ offset_normal + 1 ] = vn.y; + normalArray[ offset_normal + 2 ] = vn.z; + + offset_normal += 3; + + } + + } else { + + for ( i = 0; i < 4; i ++ ) { + + normalArray[ offset_normal ] = faceNormal.x; + normalArray[ offset_normal + 1 ] = faceNormal.y; + normalArray[ offset_normal + 2 ] = faceNormal.z; + + offset_normal += 3; + + } + + } + + } + + if ( dirtyUvs && uv ) { + + for ( i = 0; i < 4; i ++ ) { + + uvi = uv[ i ]; + + uvArray[ offset_uv ] = uvi.u; + uvArray[ offset_uv + 1 ] = uvi.v; + + offset_uv += 2; + + } + + } + + if ( dirtyUvs && uv2 ) { + + for ( i = 0; i < 4; i ++ ) { + + uv2i = uv2[ i ]; + + uv2Array[ offset_uv2 ] = uv2i.u; + uv2Array[ offset_uv2 + 1 ] = uv2i.v; + + offset_uv2 += 2; + + } + + } + + if ( dirtyElements ) { + + faceArray[ offset_face ] = vertexIndex; + faceArray[ offset_face + 1 ] = vertexIndex + 1; + faceArray[ offset_face + 2 ] = vertexIndex + 2; + + faceArray[ offset_face + 3 ] = vertexIndex; + faceArray[ offset_face + 4 ] = vertexIndex + 2; + faceArray[ offset_face + 5 ] = vertexIndex + 3; + + offset_face += 6; + + lineArray[ offset_line ] = vertexIndex; + lineArray[ offset_line + 1 ] = vertexIndex + 1; + + lineArray[ offset_line + 2 ] = vertexIndex; + lineArray[ offset_line + 3 ] = vertexIndex + 3; + + lineArray[ offset_line + 4 ] = vertexIndex + 1; + lineArray[ offset_line + 5 ] = vertexIndex + 2; + + lineArray[ offset_line + 6 ] = vertexIndex + 2; + lineArray[ offset_line + 7 ] = vertexIndex + 3; + + offset_line += 8; + + vertexIndex += 4; + + } + + } + + } + + if ( dirtyVertices ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors && obj_colors.length ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + if ( dirtyNormals ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint ); + + } + + if ( dirtyTangents && geometry.hasTangents ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint ); + + } + + if ( dirtyUvs && offset_uv > 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint ); + + } + + if ( dirtyUvs && offset_uv2 > 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint ); + + } + + if ( dirtyElements ) { + + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer ); + _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint ); + + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer ); + _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint ); + + } + + if ( offset_skin > 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint ); + + } + + }; + + function setLineBuffers ( geometry, hint ) { + + var v, c, vertex, offset, + vertices = geometry.vertices, + colors = geometry.colors, + vl = vertices.length, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyColors = geometry.__dirtyColors; + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + }; + + function setRibbonBuffers ( geometry, hint ) { + + var v, c, vertex, offset, + vertices = geometry.vertices, + colors = geometry.colors, + vl = vertices.length, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyColors = geometry.__dirtyColors; + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + }; + + function setParticleBuffers ( geometry, hint, object ) { + + var v, c, vertex, offset, + vertices = geometry.vertices, + vl = vertices.length, + + colors = geometry.colors, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + sortArray = geometry.__sortArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyElements = geometry.__dirtyElements, + dirtyColors = geometry.__dirtyColors; + + if ( object.sortParticles ) { + + _projScreenMatrix.multiplySelf( object.matrixWorld ); + + for ( v = 0; v < vl; v++ ) { + + vertex = vertices[ v ].position; + + _vector3.copy( vertex ); + _projScreenMatrix.multiplyVector3( _vector3 ); + + sortArray[ v ] = [ _vector3.z, v ]; + + } + + sortArray.sort( function(a,b) { return b[0] - a[0]; } ); + + for ( v = 0; v < vl; v++ ) { + + vertex = vertices[ sortArray[v][1] ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + for ( c = 0; c < cl; c++ ) { + + offset = c * 3; + + color = colors[ sortArray[c][1] ]; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + + } else { + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + } + + } + + if ( dirtyVertices || object.sortParticles ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors || object.sortParticles ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webGLColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + }; + + function setMaterialShaders ( material, shaders ) { + + material.fragmentShader = shaders.fragmentShader; + material.vertexShader = shaders.vertexShader; + material.uniforms = Uniforms.clone( shaders.uniforms ); + + }; + + function refreshUniformsCommon ( uniforms, material ) { + + // premultiply alpha + uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity ); + + // pure color + //uniforms.color.value.setHex( material.color.hex ); + + uniforms.opacity.value = material.opacity; + uniforms.map.texture = material.map; + + uniforms.lightMap.texture = material.lightMap; + + uniforms.envMap.texture = material.envMap; + uniforms.reflectivity.value = material.reflectivity; + uniforms.refractionRatio.value = material.refractionRatio; + uniforms.combine.value = material.combine; + uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping; + + }; + + function refreshUniformsLine ( uniforms, material ) { + + uniforms.diffuse.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity ); + uniforms.opacity.value = material.opacity; + + }; + + function refreshUniformsParticle ( uniforms, material ) { + + uniforms.psColor.value.setRGB( material.color.r * material.opacity, material.color.g * material.opacity, material.color.b * material.opacity ); + uniforms.opacity.value = material.opacity; + uniforms.size.value = material.size; + uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this. + uniforms.map.texture = material.map; + + }; + + function refreshUniformsFog ( uniforms, fog ) { + + uniforms.fogColor.value.setHex( fog.color.hex ); + + if ( fog instanceof THREE.Fog ) { + + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; + + } else if ( fog instanceof THREE.FogExp2 ) { + + uniforms.fogDensity.value = fog.density; + + } + + }; + + function refreshUniformsPhong ( uniforms, material ) { + + //uniforms.ambient.value.setHex( material.ambient.hex ); + //uniforms.specular.value.setHex( material.specular.hex ); + uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b ); + uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b ); + uniforms.shininess.value = material.shininess; + + }; + + + function refreshUniformsLights ( uniforms, lights ) { + + uniforms.enableLighting.value = lights.directional.length + lights.point.length; + uniforms.ambientLightColor.value = lights.ambient; + uniforms.directionalLightColor.value = lights.directional.colors; + uniforms.directionalLightDirection.value = lights.directional.positions; + uniforms.pointLightColor.value = lights.point.colors; + uniforms.pointLightPosition.value = lights.point.positions; + + }; + + this.initMaterial = function ( material, lights, fog, object ) { + + var u, identifiers, parameters, maxLightCount, maxBones; + + if ( material instanceof THREE.MeshDepthMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'depth' ] ); + + } else if ( material instanceof THREE.MeshNormalMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'normal' ] ); + + } else if ( material instanceof THREE.MeshBasicMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] ); + + } else if ( material instanceof THREE.MeshLambertMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'lambert' ] ); + + } else if ( material instanceof THREE.MeshPhongMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'phong' ] ); + + } else if ( material instanceof THREE.LineBasicMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'basic' ] ); + + } else if ( material instanceof THREE.ParticleBasicMaterial ) { + + setMaterialShaders( material, THREE.ShaderLib[ 'particle_basic' ] ); + + } + + // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) + + maxLightCount = allocateLights( lights, 4 ); + + maxBones = allocateBones( object ); + + parameters = { + fog: fog, map: material.map, envMap: material.envMap, + lightMap: material.lightMap, vertexColors: material.vertexColors, + sizeAttenuation: material.sizeAttenuation, skinning: material.skinning, + maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point, + maxBones: maxBones + }; + + material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters ); + + identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition', + 'cameraInverseMatrix', 'boneGlobalMatrices' + ]; + + for( u in material.uniforms ) { + + identifiers.push(u); + + } + + cacheUniformLocations( material.program, identifiers ); + cacheAttributeLocations( material.program, [ "position", "normal", "uv", "uv2", "tangent", "color", + "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] ); + + var attributes = material.program.attributes; + + _gl.enableVertexAttribArray( attributes.position ); + + if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color ); + if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal ); + if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent ); + + if ( material.skinning && + attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 && + attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { + + _gl.enableVertexAttribArray( attributes.skinVertexA ); + _gl.enableVertexAttribArray( attributes.skinVertexB ); + _gl.enableVertexAttribArray( attributes.skinIndex ); + _gl.enableVertexAttribArray( attributes.skinWeight ); + + } + + }; + + function setProgram ( camera, lights, fog, material, object ) { + + if ( !material.program ) _this.initMaterial( material, lights, fog, object ); + + var program = material.program, + p_uniforms = program.uniforms, + m_uniforms = material.uniforms; + + if( program != _oldProgram ) { + + _gl.useProgram( program ); + _oldProgram = program; + + } + + _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray ); + + // refresh uniforms common to several materials + + if ( fog && ( + material instanceof THREE.MeshBasicMaterial || + material instanceof THREE.MeshLambertMaterial || + material instanceof THREE.MeshPhongMaterial || + material instanceof THREE.LineBasicMaterial || + material instanceof THREE.ParticleBasicMaterial ) + ) { + + refreshUniformsFog( m_uniforms, fog ); + + } + + if ( material instanceof THREE.MeshPhongMaterial || + material instanceof THREE.MeshLambertMaterial ) { + + setupLights( program, lights ); + refreshUniformsLights( m_uniforms, _lights ); + + } + + if ( material instanceof THREE.MeshBasicMaterial || + material instanceof THREE.MeshLambertMaterial || + material instanceof THREE.MeshPhongMaterial ) { + + refreshUniformsCommon( m_uniforms, material ); + + } + + // refresh single material specific uniforms + + if ( material instanceof THREE.LineBasicMaterial ) { + + refreshUniformsLine( m_uniforms, material ); + + } else if ( material instanceof THREE.ParticleBasicMaterial ) { + + refreshUniformsParticle( m_uniforms, material ); + + } else if ( material instanceof THREE.MeshPhongMaterial ) { + + refreshUniformsPhong( m_uniforms, material ); + + } else if ( material instanceof THREE.MeshDepthMaterial ) { + + m_uniforms.mNear.value = camera.near; + m_uniforms.mFar.value = camera.far; + m_uniforms.opacity.value = material.opacity; + + } else if ( material instanceof THREE.MeshNormalMaterial ) { + + m_uniforms.opacity.value = material.opacity; + + } + + // load common uniforms + + loadUniformsGeneric( program, m_uniforms ); + loadUniformsMatrices( p_uniforms, object ); + + // load material specific uniforms + // (shader material also gets them for the sake of genericity) + + if ( material instanceof THREE.MeshShaderMaterial || + material instanceof THREE.MeshPhongMaterial || + material.envMap ) { + + _gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z ); + + } + + if ( material instanceof THREE.MeshShaderMaterial || + material.envMap || + material.skinning ) { + + _gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray ); + + } + + if ( material instanceof THREE.MeshPhongMaterial || + material instanceof THREE.MeshLambertMaterial || + material instanceof THREE.MeshShaderMaterial || + material.skinning ) { + + _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray ); + + } + + if ( material.skinning ) { + + loadUniformsSkinning( p_uniforms, object ); + + } + + return program; + + }; + + function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) { + + var program, attributes, linewidth, primitives; + + program = setProgram( camera, lights, fog, material, object ); + + attributes = program.attributes; + + // vertices + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer ); + _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 ); + + // colors + + if ( attributes.color >= 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer ); + _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 ); + + } + + // normals + + if ( attributes.normal >= 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer ); + _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); + + } + + // tangents + + if ( attributes.tangent >= 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLTangentBuffer ); + _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 ); + + } + + // uvs + + if ( attributes.uv >= 0 ) { + + if ( geometryGroup.__webGLUVBuffer ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUVBuffer ); + _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 ); + + _gl.enableVertexAttribArray( attributes.uv ); + + } else { + + _gl.disableVertexAttribArray( attributes.uv ); + + } + + } + + if ( attributes.uv2 >= 0 ) { + + if ( geometryGroup.__webGLUV2Buffer ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLUV2Buffer ); + _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 ); + + _gl.enableVertexAttribArray( attributes.uv2 ); + + } else { + + _gl.disableVertexAttribArray( attributes.uv2 ); + + } + + } + + if ( material.skinning && + attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 && + attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexABuffer ); + _gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinVertexBBuffer ); + _gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinIndicesBuffer ); + _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 ); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLSkinWeightsBuffer ); + _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 ); + + } + + // render mesh + + if ( object instanceof THREE.Mesh ) { + + // wireframe + + if ( material.wireframe ) { + + _gl.lineWidth( material.wireframeLinewidth ); + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLLineBuffer ); + _gl.drawElements( _gl.LINES, geometryGroup.__webGLLineCount, _gl.UNSIGNED_SHORT, 0 ); + + // triangles + + } else { + + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer ); + _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 ); + + } + + // render lines + + } else if ( object instanceof THREE.Line ) { + + primitives = ( object.type == THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES; + + _gl.lineWidth( material.linewidth ); + _gl.drawArrays( primitives, 0, geometryGroup.__webGLLineCount ); + + // render particles + + } else if ( object instanceof THREE.ParticleSystem ) { + + _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webGLParticleCount ); + + // render ribbon + + } else if ( object instanceof THREE.Ribbon ) { + + _gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webGLVertexCount ); + + } + + }; + + function renderBufferImmediate ( object, program ) { + + if ( ! object.__webGLVertexBuffer ) object.__webGLVertexBuffer = _gl.createBuffer(); + if ( ! object.__webGLNormalBuffer ) object.__webGLNormalBuffer = _gl.createBuffer(); + + if ( object.hasPos ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); + _gl.enableVertexAttribArray( program.attributes.position ); + _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); + + } + + if ( object.hasNormal ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webGLNormalBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); + _gl.enableVertexAttribArray( program.attributes.normal ); + _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); + + } + + _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); + + object.count = 0; + + }; + + function setObjectFaces ( object ) { + + if ( _oldDoubleSided != object.doubleSided ) { + + if( object.doubleSided ) { + + _gl.disable( _gl.CULL_FACE ); + + } else { + + _gl.enable( _gl.CULL_FACE ); + + } + + _oldDoubleSided = object.doubleSided; + + } + + if ( _oldFlipSided != object.flipSided ) { + + if( object.flipSided ) { + + _gl.frontFace( _gl.CW ); + + } else { + + _gl.frontFace( _gl.CCW ); + + } + + _oldFlipSided = object.flipSided; + + } + + }; + + function setDepthTest ( test ) { + + if ( _oldDepth != test ) { + + if( test ) { + + _gl.enable( _gl.DEPTH_TEST ); + + } else { + + _gl.disable( _gl.DEPTH_TEST ); + + } + + _oldDepth = test; + + } + + }; + + function computeFrustum ( m ) { + + _frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 ); + _frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 ); + _frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 ); + _frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 ); + _frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 ); + _frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 ); + + var i, plane; + + for ( i = 0; i < 6; i ++ ) { + + plane = _frustum[ i ]; + plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) ); + + } + + }; + + function isInFrustum ( object ) { + + var distance, matrix = object.matrixWorld, + radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) ); + + for ( var i = 0; i < 6; i ++ ) { + + distance = _frustum[ i ].x * matrix.n14 + _frustum[ i ].y * matrix.n24 + _frustum[ i ].z * matrix.n34 + _frustum[ i ].w; + if ( distance <= radius ) return false; + + } + + return true; + + }; + + function addToFixedArray ( where, what ) { + + where.list[ where.count ] = what; + where.count += 1; + + }; + + function unrollImmediateBufferMaterials ( globject ) { + + var i, l, m, ml, material, + object = globject.object, + opaque = globject.opaque, + transparent = globject.transparent; + + transparent.count = 0; + opaque.count = 0; + + for ( m = 0, ml = object.materials.length; m < ml; m++ ) { + + material = object.materials[ m ]; + + if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending ) + addToFixedArray( transparent, material ); + else + addToFixedArray( opaque, material ); + + } + + }; + + function unrollBufferMaterials ( globject ) { + + var i, l, m, ml, material, meshMaterial, + object = globject.object, + buffer = globject.buffer, + opaque = globject.opaque, + transparent = globject.transparent; + + transparent.count = 0; + opaque.count = 0; + + for ( m = 0, ml = object.materials.length; m < ml; m++ ) { + + meshMaterial = object.materials[ m ]; + + if ( meshMaterial instanceof THREE.MeshFaceMaterial ) { + + for ( i = 0, l = buffer.materials.length; i < l; i++ ) { + + material = buffer.materials[ i ]; + + if ( material ) { + + if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending ) + addToFixedArray( transparent, material ); + else + addToFixedArray( opaque, material ); + + } + + } + + } else { + + material = meshMaterial; + + if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending ) { + + addToFixedArray( transparent, material ); + + } else { + + addToFixedArray( opaque, material ); + + } + + } + + } + + }; + + + function painterSort ( a, b ) { + + return b.z - a.z; + + }; + + this.render = function ( scene, camera, renderTarget, forceClear ) { + + var i, program, opaque, transparent, material, + o, ol, oil, webglObject, object, buffer, + lights = scene.lights, + fog = scene.fog, + ol; + + camera.matrixAutoUpdate && camera.update(); + + camera.matrixWorldInverse.flattenToArray( _viewMatrixArray ); + camera.projectionMatrix.flattenToArray( _projectionMatrixArray ); + + _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse ); + computeFrustum( _projScreenMatrix ); + + scene.update( undefined, false, camera ); + + this.initWebGLObjects( scene ); + + setRenderTarget( renderTarget ); + + if ( this.autoClear || forceClear ) { + + this.clear(); + + } + + // set matrices + + ol = scene.__webglObjects.length; + + for ( o = 0; o < ol; o++ ) { + + webglObject = scene.__webglObjects[ o ]; + object = webglObject.object; + + if ( object.visible ) { + + if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) { + + object.matrixWorld.flattenToArray( object._objectMatrixArray ); + + setupMatrices( object, camera ); + + unrollBufferMaterials( webglObject ); + + webglObject.render = true; + + if ( this.sortObjects ) { + + _vector3.copy( object.position ); + _projScreenMatrix.multiplyVector3( _vector3 ); + + webglObject.z = _vector3.z; + + } + + } else { + + webglObject.render = false; + + } + + } else { + + webglObject.render = false; + + } + + } + + if ( this.sortObjects ) { + + scene.__webglObjects.sort( painterSort ); + + } + + oil = scene.__webglObjectsImmediate.length; + + for ( o = 0; o < oil; o++ ) { + + webglObject = scene.__webglObjectsImmediate[ o ]; + object = webglObject.object; + + if ( object.visible ) { + + if( object.matrixAutoUpdate ) { + + object.matrixWorld.flattenToArray( object._objectMatrixArray ); + + } + + setupMatrices( object, camera ); + + unrollImmediateBufferMaterials( webglObject ); + + } + + } + + // opaque pass + + setBlending( THREE.NormalBlending ); + + for ( o = 0; o < ol; o++ ) { + + webglObject = scene.__webglObjects[ o ]; + + if ( webglObject.render ) { + + object = webglObject.object; + buffer = webglObject.buffer; + opaque = webglObject.opaque; + + setObjectFaces( object ); + + for( i = 0; i < opaque.count; i++ ) { + + material = opaque.list[ i ]; + + setDepthTest( material.depthTest ); + renderBuffer( camera, lights, fog, material, buffer, object ); + + } + + } + + } + + // opaque pass (immediate simulator) + + for ( o = 0; o < oil; o++ ) { + + webglObject = scene.__webglObjectsImmediate[ o ]; + object = webglObject.object; + + if ( object.visible ) { + + opaque = webglObject.opaque; + + setObjectFaces( object ); + + for( i = 0; i < opaque.count; i++ ) { + + material = opaque.list[ i ]; + + setDepthTest( material.depthTest ); + + program = setProgram( camera, lights, fog, material, object ); + object.render( function( object ) { renderBufferImmediate( object, program ); } ); + + } + + } + + } + + // transparent pass + + for ( o = 0; o < ol; o++ ) { + + webglObject = scene.__webglObjects[ o ]; + + if ( webglObject.render ) { + + object = webglObject.object; + buffer = webglObject.buffer; + transparent = webglObject.transparent; + + setObjectFaces( object ); + + for( i = 0; i < transparent.count; i++ ) { + + material = transparent.list[ i ]; + + setBlending( material.blending ); + setDepthTest( material.depthTest ); + + renderBuffer( camera, lights, fog, material, buffer, object ); + + } + + } + + } + + // transparent pass (immediate simulator) + + for ( o = 0; o < oil; o++ ) { + + webglObject = scene.__webglObjectsImmediate[ o ]; + object = webglObject.object; + + if ( object.visible ) { + + transparent = webglObject.transparent; + + setObjectFaces( object ); + + for( i = 0; i < transparent.count; i++ ) { + + material = transparent.list[ i ]; + + setBlending( material.blending ); + setDepthTest( material.depthTest ); + + program = setProgram( camera, lights, fog, material, object ); + object.render( function( object ) { renderBufferImmediate( object, program ); } ); + + } + + } + + } + + // Generate mipmap if we're using any kind of mipmap filtering + + if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) { + + updateRenderTargetMipmap( renderTarget ); + + } + + }; + + function setupMatrices ( object, camera ) { + + object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray ); + THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray ); + + }; + + this.initWebGLObjects = function ( scene ) { + + if ( !scene.__webglObjects ) { + + scene.__webglObjects = []; + scene.__webglObjectsImmediate = []; + + } + + while ( scene.__objectsAdded.length ) { + + addObject( scene.__objectsAdded[ 0 ], scene ); + scene.__objectsAdded.splice( 0, 1 ); + + } + + while ( scene.__objectsRemoved.length ) { + + removeObject( scene.__objectsRemoved[ 0 ], scene ); + scene.__objectsRemoved.splice( 0, 1 ); + + } + + // update must be called after objects adding / removal + + for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) { + + updateObject( scene.__webglObjects[ o ].object, scene ); + + } + + }; + + function addObject ( object, scene ) { + + var g, geometry, geometryGroup; + + if ( object._modelViewMatrix == undefined ) { + + object._modelViewMatrix = new THREE.Matrix4(); + + object._normalMatrixArray = new Float32Array( 9 ); + object._modelViewMatrixArray = new Float32Array( 16 ); + object._objectMatrixArray = new Float32Array( 16 ); + + object.matrixWorld.flattenToArray( object._objectMatrixArray ); + + } + + if ( object instanceof THREE.Mesh ) { + + geometry = object.geometry; + + if ( geometry.geometryGroups == undefined ) { + + sortFacesByMaterial( geometry ); + + } + + // create separate VBOs per geometry chunk + + for ( g in geometry.geometryGroups ) { + + geometryGroup = geometry.geometryGroups[ g ]; + + // initialise VBO on the first access + + if ( ! geometryGroup.__webGLVertexBuffer ) { + + createMeshBuffers( geometryGroup ); + initMeshBuffers( geometryGroup, object ); + + geometry.__dirtyVertices = true; + geometry.__dirtyElements = true; + geometry.__dirtyUvs = true; + geometry.__dirtyNormals = true; + geometry.__dirtyTangents = true; + geometry.__dirtyColors = true; + + } + + // create separate wrapper per each use of VBO + + addBuffer( scene.__webglObjects, geometryGroup, object ); + + } + + } else if ( object instanceof THREE.Ribbon ) { + + geometry = object.geometry; + + if( ! geometry.__webGLVertexBuffer ) { + + createRibbonBuffers( geometry ); + initRibbonBuffers( geometry ); + + geometry.__dirtyVertices = true; + geometry.__dirtyColors = true; + + } + + addBuffer( scene.__webglObjects, geometry, object ); + + } else if ( object instanceof THREE.Line ) { + + geometry = object.geometry; + + if( ! geometry.__webGLVertexBuffer ) { + + createLineBuffers( geometry ); + initLineBuffers( geometry ); + + geometry.__dirtyVertices = true; + geometry.__dirtyColors = true; + + } + + addBuffer( scene.__webglObjects, geometry, object ); + + } else if ( object instanceof THREE.ParticleSystem ) { + + geometry = object.geometry; + + if ( ! geometry.__webGLVertexBuffer ) { + + createParticleBuffers( geometry ); + initParticleBuffers( geometry ); + + geometry.__dirtyVertices = true; + geometry.__dirtyColors = true; + + } + + addBuffer( scene.__webglObjects, geometry, object ); + + } else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) { + + addBufferImmediate( scene.__webglObjectsImmediate, object ); + + }/*else if ( object instanceof THREE.Particle ) { + + }*/ + + }; + + function updateObject ( object, scene ) { + + var g, geometry, geometryGroup; + + if ( object instanceof THREE.Mesh ) { + + geometry = object.geometry; + + // check all geometry groups + + for ( g in geometry.geometryGroups ) { + + geometryGroup = geometry.geometryGroups[ g ]; + + if ( geometry.__dirtyVertices || geometry.__dirtyElements || + geometry.__dirtyUvs || geometry.__dirtyNormals || + geometry.__dirtyColors || geometry.__dirtyTangents ) { + + setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW ); + + } + + } + + geometry.__dirtyVertices = false; + geometry.__dirtyElements = false; + geometry.__dirtyUvs = false; + geometry.__dirtyNormals = false; + geometry.__dirtyTangents = false; + geometry.__dirtyColors = false; + + } else if ( object instanceof THREE.Ribbon ) { + + geometry = object.geometry; + + if( geometry.__dirtyVertices || geometry.__dirtyColors ) { + + setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW ); + + } + + geometry.__dirtyVertices = false; + geometry.__dirtyColors = false; + + } else if ( object instanceof THREE.Line ) { + + geometry = object.geometry; + + if( geometry.__dirtyVertices || geometry.__dirtyColors ) { + + setLineBuffers( geometry, _gl.DYNAMIC_DRAW ); + + } + + geometry.__dirtyVertices = false; + geometry.__dirtyColors = false; + + } else if ( object instanceof THREE.ParticleSystem ) { + + geometry = object.geometry; + + if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles ) { + + setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object ); + + } + + geometry.__dirtyVertices = false; + geometry.__dirtyColors = false; + + }/* else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) { + + // it updates itself in render callback + + } else if ( object instanceof THREE.Particle ) { + + }*/ + + }; + + function removeObject ( object, scene ) { + + var o, ol, zobject; + + for ( o = scene.__webglObjects.length - 1; o >= 0; o-- ) { + + zobject = scene.__webglObjects[ o ].object; + + if ( object == zobject ) { + + scene.__webglObjects.splice( o, 1 ); + + } + + } + + }; + + function sortFacesByMaterial ( geometry ) { + + // TODO + // Should optimize by grouping faces with ColorFill / ColorStroke materials + // which could then use vertex color attributes instead of each being + // in its separate VBO + + var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {}; + + geometry.geometryGroups = {}; + + function materialHash( material ) { + + var hash_array = []; + + for ( i = 0, l = material.length; i < l; i++ ) { + + if ( material[ i ] == undefined ) { + + hash_array.push( "undefined" ); + + } else { + + hash_array.push( material[ i ].id ); + + } + + } + + return hash_array.join( '_' ); + + } + + for ( f = 0, fl = geometry.faces.length; f < fl; f++ ) { + + face = geometry.faces[ f ]; + materials = face.materials; + + mhash = materialHash( materials ); + + if ( hash_map[ mhash ] == undefined ) { + + hash_map[ mhash ] = { 'hash': mhash, 'counter': 0 }; + + } + + ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter; + + if ( geometry.geometryGroups[ ghash ] == undefined ) { + + geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 }; + + } + + vertices = face instanceof THREE.Face3 ? 3 : 4; + + if ( geometry.geometryGroups[ ghash ].vertices + vertices > 65535 ) { + + hash_map[ mhash ].counter += 1; + ghash = hash_map[ mhash ].hash + '_' + hash_map[ mhash ].counter; + + if ( geometry.geometryGroups[ ghash ] == undefined ) { + + geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 }; + + } + + } + + geometry.geometryGroups[ ghash ].faces.push( f ); + geometry.geometryGroups[ ghash ].vertices += vertices; + + } + + }; + + function addBuffer ( objlist, buffer, object ) { + + objlist.push( { buffer: buffer, object: object, + opaque: { list: [], count: 0 }, + transparent: { list: [], count: 0 } + } ); + + }; + + function addBufferImmediate ( objlist, object ) { + + objlist.push( { object: object, + opaque: { list: [], count: 0 }, + transparent: { list: [], count: 0 } + } ); + + }; + + this.setFaceCulling = function ( cullFace, frontFace ) { + + if ( cullFace ) { + + if ( !frontFace || frontFace == "ccw" ) { + + _gl.frontFace( _gl.CCW ); + + } else { + + _gl.frontFace( _gl.CW ); + + } + + if( cullFace == "back" ) { + + _gl.cullFace( _gl.BACK ); + + } else if( cullFace == "front" ) { + + _gl.cullFace( _gl.FRONT ); + + } else { + + _gl.cullFace( _gl.FRONT_AND_BACK ); + + } + + _gl.enable( _gl.CULL_FACE ); + + } else { + + _gl.disable( _gl.CULL_FACE ); + + } + + }; + + this.supportsVertexTextures = function () { + + return maxVertexTextures() > 0; + + }; + + function maxVertexTextures () { + + return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + + }; + + function initGL ( antialias, clearColor, clearAlpha ) { + + try { + + if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias } ) ) ) { + + throw 'Error creating WebGL context.'; + + } + + } catch ( e ) { + + console.error( e ); + + } + + _gl.clearColor( 0, 0, 0, 1 ); + _gl.clearDepth( 1 ); + + _gl.enable( _gl.DEPTH_TEST ); + _gl.depthFunc( _gl.LEQUAL ); + + _gl.frontFace( _gl.CCW ); + _gl.cullFace( _gl.BACK ); + _gl.enable( _gl.CULL_FACE ); + + _gl.enable( _gl.BLEND ); + _gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); + _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha ); + + _cullEnabled = true; + + }; + + function buildProgram ( fragmentShader, vertexShader, parameters ) { + + var program = _gl.createProgram(), + + prefix_fragment = [ + "#ifdef GL_ES", + "precision highp float;", + "#endif", + + "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, + "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, + + parameters.fog ? "#define USE_FOG" : "", + parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "", + + parameters.map ? "#define USE_MAP" : "", + parameters.envMap ? "#define USE_ENVMAP" : "", + parameters.lightMap ? "#define USE_LIGHTMAP" : "", + parameters.vertexColors ? "#define USE_COLOR" : "", + + "uniform mat4 viewMatrix;", + "uniform vec3 cameraPosition;", + "" + ].join("\n"), + + prefix_vertex = [ + maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "", + + "#define MAX_DIR_LIGHTS " + parameters.maxDirLights, + "#define MAX_POINT_LIGHTS " + parameters.maxPointLights, + + "#define MAX_BONES " + parameters.maxBones, + + parameters.map ? "#define USE_MAP" : "", + parameters.envMap ? "#define USE_ENVMAP" : "", + parameters.lightMap ? "#define USE_LIGHTMAP" : "", + parameters.vertexColors ? "#define USE_COLOR" : "", + parameters.skinning ? "#define USE_SKINNING" : "", + + parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "", + + "uniform mat4 objectMatrix;", + "uniform mat4 modelViewMatrix;", + "uniform mat4 projectionMatrix;", + "uniform mat4 viewMatrix;", + "uniform mat3 normalMatrix;", + "uniform vec3 cameraPosition;", + + "uniform mat4 cameraInverseMatrix;", + + "attribute vec3 position;", + "attribute vec3 normal;", + "attribute vec3 color;", + "attribute vec2 uv;", + "attribute vec2 uv2;", + + "attribute vec4 skinVertexA;", + "attribute vec4 skinVertexB;", + "attribute vec4 skinIndex;", + "attribute vec4 skinWeight;", + "" + ].join("\n"); + + _gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) ); + _gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) ); + + _gl.linkProgram( program ); + + if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) { + + alert( "Could not initialise shaders\n"+ + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" ); + + //console.log( prefix_fragment + fragmentShader ); + //console.log( prefix_vertex + vertexShader ); + + } + + //console.log( prefix_fragment + fragmentShader ); + //console.log( prefix_vertex + vertexShader ); + + program.uniforms = {}; + program.attributes = {}; + + return program; + + }; + + function loadUniformsSkinning ( uniforms, object ) { + + _gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray ); + _gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices ); + + }; + + function loadUniformsMatrices ( uniforms, object ) { + + _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray ); + _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray ); + + }; + + function loadUniformsGeneric ( program, uniforms ) { + + var u, uniform, value, type, location, texture; + + for( u in uniforms ) { + + location = program.uniforms[u]; + if ( !location ) continue; + + uniform = uniforms[u]; + + type = uniform.type; + value = uniform.value; + + if( type == "i" ) { + + _gl.uniform1i( location, value ); + + } else if( type == "f" ) { + + _gl.uniform1f( location, value ); + + } else if( type == "fv1" ) { + + _gl.uniform1fv( location, value ); + + } else if( type == "fv" ) { + + _gl.uniform3fv( location, value ); + + } else if( type == "v2" ) { + + _gl.uniform2f( location, value.x, value.y ); + + } else if( type == "v3" ) { + + _gl.uniform3f( location, value.x, value.y, value.z ); + + } else if( type == "c" ) { + + _gl.uniform3f( location, value.r, value.g, value.b ); + + } else if( type == "t" ) { + + _gl.uniform1i( location, value ); + + texture = uniform.texture; + + if ( !texture ) continue; + + if ( texture.image instanceof Array && texture.image.length == 6 ) { + + setCubeTexture( texture, value ); + + } else { + + setTexture( texture, value ); + + } + + } + + } + + }; + + function setBlending ( blending ) { + + if ( blending != _oldBlending ) { + + switch ( blending ) { + + case THREE.AdditiveBlending: + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.ONE, _gl.ONE ); + + break; + + case THREE.SubtractiveBlending: + + //_gl.blendEquation( _gl.FUNC_SUBTRACT ); + _gl.blendFunc( _gl.DST_COLOR, _gl.ZERO ); + + break; + + case THREE.BillboardBlending: + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA); + + break; + + case THREE.ReverseSubtractiveBlending: + + _gl.blendEquation( _gl.FUNC_REVERSE_SUBTRACT ); + _gl.blendFunc( _gl.ONE, _gl.ONE ); + + break; + default: + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); + + break; + + } + + _oldBlending = blending; + + } + + }; + + function setTextureParameters ( textureType, texture, image ) { + + if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) { + + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) ); + + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) ); + + _gl.generateMipmap( textureType ); + + } else { + + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); + _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); + + _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) ); + _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) ); + + } + + }; + + function setTexture ( texture, slot ) { + + if ( texture.needsUpdate ) { + + if ( !texture.__wasSetOnce ) { + + texture.__webGLTexture = _gl.createTexture(); + + _gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture ); + _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image ); + + texture.__wasSetOnce = true; + + } else { + + _gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture ); + _gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image ); + + } + + setTextureParameters( _gl.TEXTURE_2D, texture, texture.image ); + _gl.bindTexture( _gl.TEXTURE_2D, null ); + + texture.needsUpdate = false; + + } + + _gl.activeTexture( _gl.TEXTURE0 + slot ); + _gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture ); + + }; + + function setCubeTexture ( texture, slot ) { + + if ( texture.image.length == 6 ) { + + if ( texture.needsUpdate ) { + + if ( !texture.__wasSetOnce ) { + + texture.image.__webGLTextureCube = _gl.createTexture(); + + _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube ); + + for ( var i = 0; i < 6; ++i ) { + + _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] ); + + } + + texture.__wasSetOnce = true; + + } else { + + _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube ); + + for ( var i = 0; i < 6; ++i ) { + + _gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] ); + + } + + } + + setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] ); + _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null ); + + texture.needsUpdate = false; + + } + + _gl.activeTexture( _gl.TEXTURE0 + slot ); + _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube ); + + } + + }; + + function setRenderTarget ( renderTexture ) { + + if ( renderTexture && !renderTexture.__webGLFramebuffer ) { + + renderTexture.__webGLFramebuffer = _gl.createFramebuffer(); + renderTexture.__webGLRenderbuffer = _gl.createRenderbuffer(); + renderTexture.__webGLTexture = _gl.createTexture(); + + // Setup renderbuffer + + _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer ); + _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height ); + + // Setup texture + + _gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webGLTexture ); + _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrapS ) ); + _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrapT ) ); + _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.magFilter ) ); + _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.minFilter ) ); + _gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null ); + + // Setup framebuffer + + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webGLFramebuffer ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webGLTexture, 0 ); + _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webGLRenderbuffer ); + + // Release everything + + _gl.bindTexture( _gl.TEXTURE_2D, null ); + _gl.bindRenderbuffer( _gl.RENDERBUFFER, null ); + _gl.bindFramebuffer( _gl.FRAMEBUFFER, null); + + } + + var framebuffer, width, height; + + if ( renderTexture ) { + + framebuffer = renderTexture.__webGLFramebuffer; + width = renderTexture.width; + height = renderTexture.height; + + } else { + + framebuffer = null; + width = _viewportWidth; + height = _viewportHeight; + + } + + if( framebuffer != _oldFramebuffer ) { + + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + _gl.viewport( _viewportX, _viewportY, width, height ); + + _oldFramebuffer = framebuffer; + + } + + }; + + function updateRenderTargetMipmap ( renderTarget ) { + + _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webGLTexture ); + _gl.generateMipmap( _gl.TEXTURE_2D ); + _gl.bindTexture( _gl.TEXTURE_2D, null ); + + }; + + function cacheUniformLocations ( program, identifiers ) { + + var i, l, id; + + for( i = 0, l = identifiers.length; i < l; i++ ) { + + id = identifiers[ i ]; + program.uniforms[ id ] = _gl.getUniformLocation( program, id ); + + } + + }; + + function cacheAttributeLocations ( program, identifiers ) { + + var i, l, id; + + for( i = 0, l = identifiers.length; i < l; i++ ) { + + id = identifiers[ i ]; + program.attributes[ id ] = _gl.getAttribLocation( program, id ); + + } + + }; + + function getShader ( type, string ) { + + var shader; + + if ( type == "fragment" ) { + + shader = _gl.createShader( _gl.FRAGMENT_SHADER ); + + } else if ( type == "vertex" ) { + + shader = _gl.createShader( _gl.VERTEX_SHADER ); + + } + + _gl.shaderSource( shader, string ); + _gl.compileShader( shader ); + + if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) { + + alert( _gl.getShaderInfoLog( shader ) ); + return null; + + } + + return shader; + + }; + + // fallback filters for non-power-of-2 textures + + function filterFallback ( f ) { + + switch ( f ) { + + case THREE.NearestFilter: + case THREE.NearestMipMapNearestFilter: + case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break; + + case THREE.LinearFilter: + case THREE.LinearMipMapNearestFilter: + case THREE.LinearMipMapLinearFilter: return _gl.LINEAR; break; + + } + + }; + + function paramThreeToGL ( p ) { + + switch ( p ) { + + case THREE.RepeatWrapping: return _gl.REPEAT; break; + case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break; + case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break; + + case THREE.NearestFilter: return _gl.NEAREST; break; + case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break; + case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break; + + case THREE.LinearFilter: return _gl.LINEAR; break; + case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break; + case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break; + + case THREE.ByteType: return _gl.BYTE; break; + case THREE.UnsignedByteType: return _gl.UNSIGNED_BYTE; break; + case THREE.ShortType: return _gl.SHORT; break; + case THREE.UnsignedShortType: return _gl.UNSIGNED_SHORT; break; + case THREE.IntType: return _gl.INT; break; + case THREE.UnsignedShortType: return _gl.UNSIGNED_INT; break; + case THREE.FloatType: return _gl.FLOAT; break; + + case THREE.AlphaFormat: return _gl.ALPHA; break; + case THREE.RGBFormat: return _gl.RGB; break; + case THREE.RGBAFormat: return _gl.RGBA; break; + case THREE.LuminanceFormat: return _gl.LUMINANCE; break; + case THREE.LuminanceAlphaFormat: return _gl.LUMINANCE_ALPHA; break; + + } + + return 0; + + }; + + function isPowerOfTwo ( value ) { + + return ( value & ( value - 1 ) ) == 0; + + }; + + function materialNeedsSmoothNormals ( material ) { + + return material && material.shading != undefined && material.shading == THREE.SmoothShading; + + }; + + function bufferNeedsSmoothNormals ( geometryGroup, object ) { + + var m, ml, i, l, meshMaterial, needsSmoothNormals = false; + + for ( m = 0, ml = object.materials.length; m < ml; m++ ) { + + meshMaterial = object.materials[ m ]; + + if ( meshMaterial instanceof THREE.MeshFaceMaterial ) { + + for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) { + + if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) { + + needsSmoothNormals = true; + break; + + } + + } + + } else { + + if ( materialNeedsSmoothNormals( meshMaterial ) ) { + + needsSmoothNormals = true; + break; + + } + + } + + if ( needsSmoothNormals ) break; + + } + + return needsSmoothNormals; + + }; + + function allocateBones ( object ) { + + // default for when object is not specified + // ( for example when prebuilding shader + // to be used with multiple objects ) + // + // - leave some extra space for other uniforms + // - limit here is ANGLE's 254 max uniform vectors + // (up to 54 should be safe) + + var maxBones = 50; + + if ( object !== undefined && object instanceof THREE.SkinnedMesh ) { + + maxBones = object.bones.length; + + } + + return maxBones; + + }; + + function allocateLights ( lights, maxLights ) { + + var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights; + dirLights = pointLights = maxDirLights = maxPointLights = 0; + + for ( l = 0, ll = lights.length; l < ll; l++ ) { + + light = lights[ l ]; + + if ( light instanceof THREE.DirectionalLight ) dirLights++; + if ( light instanceof THREE.PointLight ) pointLights++; + + } + + if ( ( pointLights + dirLights ) <= maxLights ) { + + maxDirLights = dirLights; + maxPointLights = pointLights; + + } else { + + maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) ); + maxPointLights = maxLights - maxDirLights; + + } + + return { 'directional' : maxDirLights, 'point' : maxPointLights }; + + }; + + /* DEBUG + function getGLParams() { + + var params = { + + 'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ), + 'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ), + + 'MAX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ), + 'MAX_VERTEX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ), + 'MAX_COMBINED_TEXTURE_IMAGE_UNITS' : _gl.getParameter( _gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ), + + 'MAX_VERTEX_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ), + 'MAX_FRAGMENT_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_FRAGMENT_UNIFORM_VECTORS ) + } + + return params; + }; + + function dumpObject( obj ) { + + var p, str = ""; + for ( p in obj ) { + + str += p + ": " + obj[p] + "\n"; + + } + + return str; + } + */ + +}; + +THREE.Snippets = { + + // FOG + + fog_pars_fragment: [ + + "#ifdef USE_FOG", + + "uniform vec3 fogColor;", + + "#ifdef FOG_EXP2", + "uniform float fogDensity;", + "#else", + "uniform float fogNear;", + "uniform float fogFar;", + "#endif", + + "#endif" + + ].join("\n"), + + fog_fragment: [ + + "#ifdef USE_FOG", + + "float depth = gl_FragCoord.z / gl_FragCoord.w;", + + "#ifdef FOG_EXP2", + "const float LOG2 = 1.442695;", + "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );", + "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );", + "#else", + "float fogFactor = smoothstep( fogNear, fogFar, depth );", + "#endif", + + "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );", + + "#endif" + + ].join("\n"), + + // ENVIRONMENT MAP + + envmap_pars_fragment: [ + + "#ifdef USE_ENVMAP", + + "varying vec3 vReflect;", + "uniform float reflectivity;", + "uniform samplerCube envMap;", + "uniform int combine;", + + "#endif" + + ].join("\n"), + + envmap_fragment: [ + + "#ifdef USE_ENVMAP", + + "vec4 cubeColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );", + + "if ( combine == 1 ) {", + + //"gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );", + "gl_FragColor = vec4( mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity ), opacity );", + + "} else {", + + "gl_FragColor = gl_FragColor * cubeColor;", + + "}", + + "#endif" + + ].join("\n"), + + envmap_pars_vertex: [ + + "#ifdef USE_ENVMAP", + + "varying vec3 vReflect;", + "uniform float refractionRatio;", + "uniform bool useRefract;", + + "#endif" + + ].join("\n"), + + envmap_vertex : [ + + "#ifdef USE_ENVMAP", + + "vec4 mPosition = objectMatrix * vec4( position, 1.0 );", + "vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;", + + "if ( useRefract ) {", + + "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );", + + "} else {", + + "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );", + + "}", + + "#endif" + + ].join("\n"), + + // COLOR MAP (particles) + + map_particle_pars_fragment: [ + + "#ifdef USE_MAP", + + "uniform sampler2D map;", + + "#endif" + + ].join("\n"), + + + map_particle_fragment: [ + + "#ifdef USE_MAP", + + "gl_FragColor = gl_FragColor * texture2D( map, gl_PointCoord );", + + "#endif" + + ].join("\n"), + + // COLOR MAP (triangles) + + map_pars_fragment: [ + + "#ifdef USE_MAP", + + "varying vec2 vUv;", + "uniform sampler2D map;", + + "#endif" + + ].join("\n"), + + map_pars_vertex: [ + + "#ifdef USE_MAP", + + "varying vec2 vUv;", + + "#endif" + + ].join("\n"), + + map_fragment: [ + + "#ifdef USE_MAP", + + "gl_FragColor = gl_FragColor * texture2D( map, vUv );", + + "#endif" + + ].join("\n"), + + map_vertex: [ + + "#ifdef USE_MAP", + + "vUv = uv;", + + "#endif" + + ].join("\n"), + + // LIGHT MAP + + lightmap_pars_fragment: [ + + "#ifdef USE_LIGHTMAP", + + "varying vec2 vUv2;", + "uniform sampler2D lightMap;", + + "#endif" + + ].join("\n"), + + lightmap_pars_vertex: [ + + "#ifdef USE_LIGHTMAP", + + "varying vec2 vUv2;", + + "#endif" + + ].join("\n"), + + lightmap_fragment: [ + + "#ifdef USE_LIGHTMAP", + + "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );", + + "#endif" + + ].join("\n"), + + lightmap_vertex: [ + + "#ifdef USE_LIGHTMAP", + + "vUv2 = uv2;", + + "#endif" + + ].join("\n"), + + lights_pars_vertex: [ + + "uniform bool enableLighting;", + "uniform vec3 ambientLightColor;", + + "#if MAX_DIR_LIGHTS > 0", + + "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", + "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", + + "#endif", + + "#if MAX_POINT_LIGHTS > 0", + + "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", + "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", + + "#ifdef PHONG", + "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];", + "#endif", + + "#endif" + + ].join("\n"), + + // LIGHTS + + lights_vertex: [ + + "if ( !enableLighting ) {", + + "vLightWeighting = vec3( 1.0 );", + + "} else {", + + "vLightWeighting = ambientLightColor;", + + "#if MAX_DIR_LIGHTS > 0", + + "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", + + "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", + "float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );", + "vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;", + + "}", + + "#endif", + + "#if MAX_POINT_LIGHTS > 0", + + "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", + + "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", + "vec3 pointLightVector = normalize( lPosition.xyz - mvPosition.xyz );", + "float pointLightWeighting = max( dot( transformedNormal, pointLightVector ), 0.0 );", + "vLightWeighting += pointLightColor[ i ] * pointLightWeighting;", + + "#ifdef PHONG", + "vPointLightVector[ i ] = pointLightVector;", + "#endif", + + "}", + + "#endif", + + "}" + + ].join("\n"), + + lights_pars_fragment: [ + + "#if MAX_DIR_LIGHTS > 0", + "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", + "#endif", + + "#if MAX_POINT_LIGHTS > 0", + "varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];", + "#endif", + + "varying vec3 vViewPosition;", + "varying vec3 vNormal;" + + ].join("\n"), + + lights_fragment: [ + + "vec3 normal = normalize( vNormal );", + "vec3 viewPosition = normalize( vViewPosition );", + + "vec4 mColor = vec4( diffuse, opacity );", + "vec4 mSpecular = vec4( specular, opacity );", + + "#if MAX_POINT_LIGHTS > 0", + + "vec4 pointDiffuse = vec4( 0.0 );", + "vec4 pointSpecular = vec4( 0.0 );", + + "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {", + + "vec3 pointVector = normalize( vPointLightVector[ i ] );", + "vec3 pointHalfVector = normalize( vPointLightVector[ i ] + vViewPosition );", + + "float pointDotNormalHalf = dot( normal, pointHalfVector );", + "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", + + "float pointSpecularWeight = 0.0;", + "if ( pointDotNormalHalf >= 0.0 )", + "pointSpecularWeight = pow( pointDotNormalHalf, shininess );", + + "pointDiffuse += mColor * pointDiffuseWeight;", + "pointSpecular += mSpecular * pointSpecularWeight;", + + "}", + + "#endif", + + "#if MAX_DIR_LIGHTS > 0", + + "vec4 dirDiffuse = vec4( 0.0 );", + "vec4 dirSpecular = vec4( 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( lDirection.xyz + vViewPosition );", + + "float dirDotNormalHalf = dot( normal, dirHalfVector );", + + "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", + + "float dirSpecularWeight = 0.0;", + "if ( dirDotNormalHalf >= 0.0 )", + "dirSpecularWeight = pow( dirDotNormalHalf, shininess );", + + "dirDiffuse += mColor * dirDiffuseWeight;", + "dirSpecular += mSpecular * dirSpecularWeight;", + + "}", + + "#endif", + + "vec4 totalLight = vec4( ambient, opacity );", + + "#if MAX_DIR_LIGHTS > 0", + "totalLight += dirDiffuse + dirSpecular;", + "#endif", + + "#if MAX_POINT_LIGHTS > 0", + "totalLight += pointDiffuse + pointSpecular;", + "#endif", + + "gl_FragColor = gl_FragColor * totalLight;" + + ].join("\n"), + + // VERTEX COLORS + + color_pars_fragment: [ + + "#ifdef USE_COLOR", + + "varying vec3 vColor;", + + "#endif" + + ].join("\n"), + + + color_fragment: [ + + "#ifdef USE_COLOR", + + "gl_FragColor = gl_FragColor * vec4( vColor, opacity );", + + "#endif" + + ].join("\n"), + + color_pars_vertex: [ + + "#ifdef USE_COLOR", + + "varying vec3 vColor;", + + "#endif" + + ].join("\n"), + + + color_vertex: [ + + "#ifdef USE_COLOR", + + "vColor = color;", + + "#endif" + + ].join("\n"), + + // skinning + + skinning_pars_vertex: [ + + "#ifdef USE_SKINNING", + + "uniform mat4 boneGlobalMatrices[ MAX_BONES ];", + + "#endif" + + ].join("\n"), + + skinning_vertex: [ + + "#ifdef USE_SKINNING", + + "gl_Position = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;", + "gl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;", + + // this doesn't work, no idea why + //"gl_Position = projectionMatrix * cameraInverseMatrix * objectMatrix * gl_Position;", + + "gl_Position = projectionMatrix * viewMatrix * objectMatrix * gl_Position;", + + "#else", + + "gl_Position = projectionMatrix * mvPosition;", + + "#endif" + + ].join("\n") + +}; + +THREE.UniformsLib = { + + common: { + + "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, + "opacity" : { type: "f", value: 1.0 }, + "map" : { type: "t", value: 0, texture: null }, + + "lightMap" : { type: "t", value: 2, texture: null }, + + "envMap" : { type: "t", value: 1, texture: null }, + "useRefract" : { type: "i", value: 0 }, + "reflectivity" : { type: "f", value: 1.0 }, + "refractionRatio": { type: "f", value: 0.98 }, + "combine" : { type: "i", value: 0 }, + + "fogDensity": { type: "f", value: 0.00025 }, + "fogNear" : { type: "f", value: 1 }, + "fogFar" : { type: "f", value: 2000 }, + "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } + + }, + + lights: { + + "enableLighting" : { type: "i", value: 1 }, + "ambientLightColor" : { type: "fv", value: [] }, + "directionalLightDirection" : { type: "fv", value: [] }, + "directionalLightColor" : { type: "fv", value: [] }, + "pointLightPosition" : { type: "fv", value: [] }, + "pointLightColor" : { type: "fv", value: [] } + + }, + + particle: { + + "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) }, + "opacity" : { type: "f", value: 1.0 }, + "size" : { type: "f", value: 1.0 }, + "scale" : { type: "f", value: 1.0 }, + "map" : { type: "t", value: 0, texture: null }, + + "fogDensity": { type: "f", value: 0.00025 }, + "fogNear" : { type: "f", value: 1 }, + "fogFar" : { type: "f", value: 2000 }, + "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) } + + } + +}; + +THREE.ShaderLib = { + + 'depth': { + + uniforms: { "mNear": { type: "f", value: 1.0 }, + "mFar" : { type: "f", value: 2000.0 }, + "opacity" : { type: "f", value: 1.0 } + }, + + fragmentShader: [ + + "uniform float mNear;", + "uniform float mFar;", + "uniform float opacity;", + + "void main() {", + + "float depth = gl_FragCoord.z / gl_FragCoord.w;", + "float color = 1.0 - smoothstep( mNear, mFar, depth );", + "gl_FragColor = vec4( vec3( color ), opacity );", + + "}" + + ].join("\n"), + + vertexShader: [ + + "void main() {", + + "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + + "}" + + ].join("\n") + + }, + + 'normal': { + + uniforms: { "opacity" : { type: "f", value: 1.0 } }, + + fragmentShader: [ + + "uniform float opacity;", + "varying vec3 vNormal;", + + "void main() {", + + "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );", + + "}" + + ].join("\n"), + + vertexShader: [ + + "varying vec3 vNormal;", + + "void main() {", + + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + "vNormal = normalize( normalMatrix * normal );", + + "gl_Position = projectionMatrix * mvPosition;", + + "}" + + ].join("\n") + + }, + + 'basic': { + + uniforms: THREE.UniformsLib[ "common" ], + + fragmentShader: [ + + "uniform vec3 diffuse;", + "uniform float opacity;", + + THREE.Snippets[ "color_pars_fragment" ], + THREE.Snippets[ "map_pars_fragment" ], + THREE.Snippets[ "lightmap_pars_fragment" ], + THREE.Snippets[ "envmap_pars_fragment" ], + THREE.Snippets[ "fog_pars_fragment" ], + + "void main() {", + + "gl_FragColor = vec4( diffuse, opacity );", + + THREE.Snippets[ "map_fragment" ], + THREE.Snippets[ "lightmap_fragment" ], + THREE.Snippets[ "color_fragment" ], + THREE.Snippets[ "envmap_fragment" ], + THREE.Snippets[ "fog_fragment" ], + + "}" + + ].join("\n"), + + vertexShader: [ + + THREE.Snippets[ "map_pars_vertex" ], + THREE.Snippets[ "lightmap_pars_vertex" ], + THREE.Snippets[ "envmap_pars_vertex" ], + THREE.Snippets[ "color_pars_vertex" ], + THREE.Snippets[ "skinning_pars_vertex" ], + + "void main() {", + + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + + THREE.Snippets[ "map_vertex" ], + THREE.Snippets[ "lightmap_vertex" ], + THREE.Snippets[ "envmap_vertex" ], + THREE.Snippets[ "color_vertex" ], + THREE.Snippets[ "skinning_vertex" ], + + "}" + + ].join("\n") + + }, + + 'lambert': { + + uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ], + THREE.UniformsLib[ "lights" ] ] ), + + fragmentShader: [ + + "uniform vec3 diffuse;", + "uniform float opacity;", + + "varying vec3 vLightWeighting;", + + THREE.Snippets[ "color_pars_fragment" ], + THREE.Snippets[ "map_pars_fragment" ], + THREE.Snippets[ "lightmap_pars_fragment" ], + THREE.Snippets[ "envmap_pars_fragment" ], + THREE.Snippets[ "fog_pars_fragment" ], + + "void main() {", + + "gl_FragColor = vec4( diffuse, opacity );", + "gl_FragColor = gl_FragColor * vec4( vLightWeighting, 1.0 );", + + THREE.Snippets[ "map_fragment" ], + THREE.Snippets[ "lightmap_fragment" ], + THREE.Snippets[ "color_fragment" ], + THREE.Snippets[ "envmap_fragment" ], + THREE.Snippets[ "fog_fragment" ], + + "}" + + ].join("\n"), + + vertexShader: [ + + "varying vec3 vLightWeighting;", + + THREE.Snippets[ "map_pars_vertex" ], + THREE.Snippets[ "lightmap_pars_vertex" ], + THREE.Snippets[ "envmap_pars_vertex" ], + THREE.Snippets[ "lights_pars_vertex" ], + THREE.Snippets[ "color_pars_vertex" ], + THREE.Snippets[ "skinning_pars_vertex" ], + + "void main() {", + + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + + THREE.Snippets[ "map_vertex" ], + THREE.Snippets[ "lightmap_vertex" ], + THREE.Snippets[ "envmap_vertex" ], + THREE.Snippets[ "color_vertex" ], + + "vec3 transformedNormal = normalize( normalMatrix * normal );", + + THREE.Snippets[ "lights_vertex" ], + THREE.Snippets[ "skinning_vertex" ], + + "}" + + ].join("\n") + + }, + + 'phong': { + + uniforms: Uniforms.merge( [ THREE.UniformsLib[ "common" ], + THREE.UniformsLib[ "lights" ], + + { "ambient" : { type: "c", value: new THREE.Color( 0x050505 ) }, + "specular" : { type: "c", value: new THREE.Color( 0x111111 ) }, + "shininess": { type: "f", value: 30 } + } + + ] ), + + fragmentShader: [ + + "uniform vec3 diffuse;", + "uniform float opacity;", + + "uniform vec3 ambient;", + "uniform vec3 specular;", + "uniform float shininess;", + + "varying vec3 vLightWeighting;", + + THREE.Snippets[ "color_pars_fragment" ], + THREE.Snippets[ "map_pars_fragment" ], + THREE.Snippets[ "lightmap_pars_fragment" ], + THREE.Snippets[ "envmap_pars_fragment" ], + THREE.Snippets[ "fog_pars_fragment" ], + THREE.Snippets[ "lights_pars_fragment" ], + + "void main() {", + + "gl_FragColor = vec4( vLightWeighting, 1.0 );", + THREE.Snippets[ "lights_fragment" ], + + THREE.Snippets[ "map_fragment" ], + THREE.Snippets[ "lightmap_fragment" ], + THREE.Snippets[ "color_fragment" ], + THREE.Snippets[ "envmap_fragment" ], + THREE.Snippets[ "fog_fragment" ], + + "}" + + ].join("\n"), + + vertexShader: [ + + "#define PHONG", + + "varying vec3 vLightWeighting;", + "varying vec3 vViewPosition;", + "varying vec3 vNormal;", + + THREE.Snippets[ "map_pars_vertex" ], + THREE.Snippets[ "lightmap_pars_vertex" ], + THREE.Snippets[ "envmap_pars_vertex" ], + THREE.Snippets[ "lights_pars_vertex" ], + THREE.Snippets[ "color_pars_vertex" ], + THREE.Snippets[ "skinning_pars_vertex" ], + + "void main() {", + + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + + THREE.Snippets[ "map_vertex" ], + THREE.Snippets[ "lightmap_vertex" ], + THREE.Snippets[ "envmap_vertex" ], + THREE.Snippets[ "color_vertex" ], + + "#ifndef USE_ENVMAP", + "vec4 mPosition = objectMatrix * vec4( position, 1.0 );", + "#endif", + + "vViewPosition = cameraPosition - mPosition.xyz;", + + "vec3 transformedNormal = normalize( normalMatrix * normal );", + "vNormal = transformedNormal;", + + THREE.Snippets[ "lights_vertex" ], + THREE.Snippets[ "skinning_vertex" ], + + "}" + + ].join("\n") + + }, + + 'particle_basic': { + + uniforms: THREE.UniformsLib[ "particle" ], + + fragmentShader: [ + + "uniform vec3 psColor;", + "uniform float opacity;", + + THREE.Snippets[ "color_pars_fragment" ], + THREE.Snippets[ "map_particle_pars_fragment" ], + THREE.Snippets[ "fog_pars_fragment" ], + + "void main() {", + + "gl_FragColor = vec4( psColor, opacity );", + + THREE.Snippets[ "map_particle_fragment" ], + THREE.Snippets[ "color_fragment" ], + THREE.Snippets[ "fog_fragment" ], + + "}" + + ].join("\n"), + + vertexShader: [ + + "uniform float size;", + "uniform float scale;", + + THREE.Snippets[ "color_pars_vertex" ], + + "void main() {", + + THREE.Snippets[ "color_vertex" ], + + "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + + "#ifdef USE_SIZEATTENUATION", + "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );", + "#else", + "gl_PointSize = size;", + "#endif", + + "gl_Position = projectionMatrix * mvPosition;", + + "}" + + ].join("\n") + + } + +}; \ No newline at end of file diff --git a/backend/rmdir.php b/backend/rmdir.php new file mode 100644 index 0000000..d84d094 --- /dev/null +++ b/backend/rmdir.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/iframe.html b/iframe.html new file mode 100644 index 0000000..7a6428e --- /dev/null +++ b/iframe.html @@ -0,0 +1,20 @@ + + + + +Untitled Document + + + +200x200
+ + +
+
+ + +same page, but with 600x600 and webgl
+ + + + \ No newline at end of file diff --git a/images/bg_line.png b/images/bg_line.png new file mode 100644 index 0000000000000000000000000000000000000000..7a82a56026a1b63b3b135659eef907bae9c7d17d GIT binary patch literal 1341 zcmd5+PiWIn7|%9@vQgYY2JWyuv(wm`e`{A7S7+O_u3*M!3+usyS@O1qEqO6{ZL=Lj z$95Rv!ON~*yp4$RO6A3o)32GrAe2_cx!=K-Z%5WJu;@D*+4o z*n$nS3*$L;VOEW3^yoP-;)=w;fLH;pF=slW8>OqhBH4Q|OM@x}&qnE^r1J6vNFW=6 z5W@vjZkPkZJi`wK!{P8C5ICM=If3Pc03Q~I1d-!F?V(9DTbmX$QmPhYf?+jm zO{Z2SQZUw4ES6_D?@D!|EdQBm7!9_AGw?Xy-x@o)c?+@`=%AvllEzKt*J)`TI7>k8diBv=ghC>|B zC%ITSKAaMQsf3UU#idZ9u9c8lG@yy=TJ2a%delVg4T52j$P%>m64X*QGC=jhqTW0g zuBl&5t2NJsZ>nWUGOX9uU)o%U$n1FA#?X>OW9*?xX5A)3y}G!)OHnQN(^4$wzWKDv zw=YuEvU0O@%UaL+{5_jl+*U01b1R^~`{A=28~bnfz8>y;`;fcSvorAS%gN%S$Lj~~ z=GvNj_R{Uj#*ex8pMx(e-(Nqdl&&6BO4+Bqz7FNg;L?e$c;45sw0y6#s|s{>5daJl z;5@;V>jd9w{fET=DVJ&)I#)aXx+aIuC$F_o$ycZR`QCw#-VZIE9GC9KFE9QC#v7|S literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_back.png b/images/skins/earthiverse/arm_left_back.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_bottom.png b/images/skins/earthiverse/arm_left_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d7b9ecf6f69bc095cb57ab473167db4966c530e4 GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zIH2=Slt)s=SLDm9xZ-q1&*$X~ANm;`W{jfI5EywOaD!RvD@*F8?0}2F9K+!0>gTe~ HDWM4ftEBN* literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_front.png b/images/skins/earthiverse/arm_left_front.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_inner.png b/images/skins/earthiverse/arm_left_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_outer.png b/images/skins/earthiverse/arm_left_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_left_top.png b/images/skins/earthiverse/arm_left_top.png new file mode 100644 index 0000000000000000000000000000000000000000..276ffc3c3ae1338cf6aabfaa4dcfe3616640b863 GIT binary patch literal 855 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{IZqeIkcv5PuNX2iDDWIG za4`6{U$J>{XH(qW^0PV$FaPi{{4-?WFdjvtAu#enpxQW*B}evLi4-uyFnGH9xvXnPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_right_bottom.png b/images/skins/earthiverse/arm_right_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d7b9ecf6f69bc095cb57ab473167db4966c530e4 GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zIH2=Slt)s=SLDm9xZ-q1&*$X~ANm;`W{jfI5EywOaD!RvD@*F8?0}2F9K+!0>gTe~ HDWM4ftEBN* literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_right_front.png b/images/skins/earthiverse/arm_right_front.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_right_inner.png b/images/skins/earthiverse/arm_right_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_right_outer.png b/images/skins/earthiverse/arm_right_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/arm_right_top.png b/images/skins/earthiverse/arm_right_top.png new file mode 100644 index 0000000000000000000000000000000000000000..276ffc3c3ae1338cf6aabfaa4dcfe3616640b863 GIT binary patch literal 855 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{IZqeIkcv5PuNX2iDDWIG za4`6{U$J>{XH(qW^0PV$FaPi{{4-?WFdjvtAu#enpxQW*B}evLi4-uyFnGH9xvXaF-&>#kaV{Ej5r3Nt&>|>(^Of-mrU=A$>EaktG3V{=jb29rL|88D z{Io&j&6_R4ky|ziY~1u!I7f8Nx8!Y;-~MH>PY`qo(V2SGshWGEkl?)DsR>GVS`^RC zNlUyr-KS7;(sW;il}x6a|LJU(Y47lmb-2T1-B4J`aD+(Y`mOTc1y+T>^-SgsJD74d z7*DvnnK@u5;}Ow>^_Q91mN7JRJ+`ks|D4Srk@d#=9}_OWKR^HY-?!Ds)n!^oG0po4gY)-k(eKy9Sc~ExDM&%349zYepnI3F*dt)8^U?MPf89ZJ6T-G@yGywqq C65iSX literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_back.png b/images/skins/earthiverse/body_back.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_bottom.png b/images/skins/earthiverse/body_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d7b9ecf6f69bc095cb57ab473167db4966c530e4 GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zIH2=Slt)s=SLDm9xZ-q1&*$X~ANm;`W{jfI5EywOaD!RvD@*F8?0}2F9K+!0>gTe~ HDWM4ftEBN* literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_front.png b/images/skins/earthiverse/body_front.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_left.png b/images/skins/earthiverse/body_left.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_right.png b/images/skins/earthiverse/body_right.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea1f24883818ff33136bad730184a4a8763ff08 GIT binary patch literal 950 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdT2B|pkcv5P?`+JR>nPxM zu`=v4l=x`*?frD)B?RP~#;-|t+Z z%AQ^S#*%P)=JL0k2gKAFS~$ral{6PaNG49pG2pUbP6H#|9W zXS+Fr_Z+h0I_+O>KEt#*GyC829uOisvVlpYmO1>a$P%5S+-1Q0$l&Sf=d#Wzp$Py7 C)$4@- literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/body_top.png b/images/skins/earthiverse/body_top.png new file mode 100644 index 0000000000000000000000000000000000000000..276ffc3c3ae1338cf6aabfaa4dcfe3616640b863 GIT binary patch literal 855 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{IZqeIkcv5PuNX2iDDWIG za4`6{U$J>{XH(qW^0PV$FaPi{{4-?WFdjvtAu#enpxQW*B}evLi4-uyFnGH9xvXfl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/hat_bottom.png b/images/skins/earthiverse/hat_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..4fe9ab37631ae5bb0fad9069c0d8ec0abca560fe GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$2RR)5S5QV$R!xh9J2^3%>fl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/hat_front.png b/images/skins/earthiverse/hat_front.png new file mode 100644 index 0000000000000000000000000000000000000000..4fe9ab37631ae5bb0fad9069c0d8ec0abca560fe GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$2RR)5S5QV$R!xh9J2^3%>fl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/hat_left.png b/images/skins/earthiverse/hat_left.png new file mode 100644 index 0000000000000000000000000000000000000000..4fe9ab37631ae5bb0fad9069c0d8ec0abca560fe GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$2RR)5S5QV$R!xh9J2^3%>fl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/hat_right.png b/images/skins/earthiverse/hat_right.png new file mode 100644 index 0000000000000000000000000000000000000000..4fe9ab37631ae5bb0fad9069c0d8ec0abca560fe GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$2RR)5S5QV$R!xh9J2^3%>fl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/hat_top.png b/images/skins/earthiverse/hat_top.png new file mode 100644 index 0000000000000000000000000000000000000000..4fe9ab37631ae5bb0fad9069c0d8ec0abca560fe GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$2RR)5S5QV$R!xh9J2^3%>fl g&E{ADWR74^!OUpGz-aR}m=hETp00i_>zopr00S-(%m4rY literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_back.png b/images/skins/earthiverse/head_back.png new file mode 100644 index 0000000000000000000000000000000000000000..a50ddb8377277655da4778355ee75753051d8b4b GIT binary patch literal 895 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{H%}MGkcv5PuNmgLI10EN z{CRDXC12l}cq=Bpp2w3+dpP4noBHPc+G$+guw?yP#shMU4FlI+eV(@hJb6Mw<&;$TPEv+{I literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_bottom.png b/images/skins/earthiverse/head_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..b15d20cec52e10bf7ae8ea2452be1763b22e8ed4 GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zIIy3$gilh&SLDm9ec5S@p3ln}KJ+s>%os(ZAu#en;0AL!AIoB~mVe&B9K+!0>gTe~ HDWM4fwmk6r literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_front.png b/images/skins/earthiverse/head_front.png new file mode 100644 index 0000000000000000000000000000000000000000..4b959d32b0506544edc9f3ebd7bc30d8694dff4e GIT binary patch literal 919 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFdI8PVHkcv5P?-~ZOItsX6 zjLSOnppipAUUZRxLj&I=M>qEGGR(iTnxf~vElz*O;F*7$xxto+A(2KX{aI}_^M)g= zG_wHc?(}EL)rVK5?+e>s|9tDOzq$A7r*ktLVxbv2cjo!Gw$$DKmw*3vuYNL3t(s@O zzr31d!(p0+-}(D@cH1)Dc*xXXz(^~!;q&Ib3=xlMYsFrgTT$P?Pw+*kSK?P-hGXz_ L^>bP0l+XkKVz1)6 literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_left.png b/images/skins/earthiverse/head_left.png new file mode 100644 index 0000000000000000000000000000000000000000..a50ddb8377277655da4778355ee75753051d8b4b GIT binary patch literal 895 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{H%}MGkcv5PuNmgLI10EN z{CRDXC12l}cq=Bpp2w3+dpP4noBHPc+G$+guw?yP#shMU4FlI+eV(@hJb6Mw<&;$TPEv+{I literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_right.png b/images/skins/earthiverse/head_right.png new file mode 100644 index 0000000000000000000000000000000000000000..a50ddb8377277655da4778355ee75753051d8b4b GIT binary patch literal 895 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{H%}MGkcv5PuNmgLI10EN z{CRDXC12l}cq=Bpp2w3+dpP4noBHPc+G$+guw?yP#shMU4FlI+eV(@hJb6Mw<&;$TPEv+{I literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/head_top.png b/images/skins/earthiverse/head_top.png new file mode 100644 index 0000000000000000000000000000000000000000..761a55fce440457f0aa57b3e7358b6d64484a7d0 GIT binary patch literal 854 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{Sx*kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_left_bottom.png b/images/skins/earthiverse/leg_left_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..06ebb17dbfb6b141ea171fbe0bbbac5290e7953e GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zaNzkT%O@%0EAr*lyxnPxp3ln}KJ+s>%os(ZAu#en;0E)ZNh~Ud_Bqc2<`@P~S3j3^ HP6kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_left_inner.png b/images/skins/earthiverse/leg_left_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7db668565d1bec271ecd9a15415ff124a342b1 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFda!(h>kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_left_outer.png b/images/skins/earthiverse/leg_left_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7db668565d1bec271ecd9a15415ff124a342b1 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFda!(h>kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_left_top.png b/images/skins/earthiverse/leg_left_top.png new file mode 100644 index 0000000000000000000000000000000000000000..408dd48b20bcf029f1e1c52d732899608ce371fb GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG za1j2tmRC~7SLDm9xZ-q1&*$X~ANm;`W{jfI5EywOaD(|xH;d8y(*6U$9K+!0>gTe~ HDWM4fuha3O literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_right_back.png b/images/skins/earthiverse/leg_right_back.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7db668565d1bec271ecd9a15415ff124a342b1 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFda!(h>kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_right_bottom.png b/images/skins/earthiverse/leg_right_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..06ebb17dbfb6b141ea171fbe0bbbac5290e7953e GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG zaNzkT%O@%0EAr*lyxnPxp3ln}KJ+s>%os(ZAu#en;0E)ZNh~Ud_Bqc2<`@P~S3j3^ HP6kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_right_inner.png b/images/skins/earthiverse/leg_right_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7db668565d1bec271ecd9a15415ff124a342b1 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFda!(h>kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_right_outer.png b/images/skins/earthiverse/leg_right_outer.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7db668565d1bec271ecd9a15415ff124a342b1 GIT binary patch literal 944 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJFda!(h>kcv5P?=19nbrf;E zSec^HumFe(zU04TX#L5?%GUJzN#HTj>a|>bw`OKPi+Fx|XTy@&FBuQWFg6&Fg*GJ5 z<+o#PU9tDt`7dk<9l{KUSja-(-tO|tXK0ftfBs3^z{QeL!H0oNlwUHyHXca0ruyKC3IVyj}j1^?-yrLklOlNOpSh+{?-hl5q?IYUHA_ zKmUG;h^*@Sti=%Ul!e@Q-n(zPIz#ZcUo+-0_!Kgc8M44Axe>SivT%bYB_7&#{q`4@ zgi~?zK?ac>LAPILS1}o+uK)g$^MD8?arBp&Q&sZY@kcVQz?{h7>FVdQ&MBb@0G?>w APXGV_ literal 0 HcmV?d00001 diff --git a/images/skins/earthiverse/leg_right_top.png b/images/skins/earthiverse/leg_right_top.png new file mode 100644 index 0000000000000000000000000000000000000000..408dd48b20bcf029f1e1c52d732899608ce371fb GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|GzJD{c~2L|kcv5PuNX2iDDWIG za1j2tmRC~7SLDm9xZ-q1&*$X~ANm;`W{jfI5EywOaD(|xH;d8y(*6U$9K+!0>gTe~ HDWM4fuha3O literal 0 HcmV?d00001 diff --git a/index.php b/index.php new file mode 100644 index 0000000..46774ba --- /dev/null +++ b/index.php @@ -0,0 +1,126 @@ + + + + + + + + + + +3d minecraft body test v1.0 + + + + + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..5c276c8 --- /dev/null +++ b/style.css @@ -0,0 +1,14 @@ +/* + earthiverse.ath.cx + Kent Rasmussen + hyprkookeez@gmail.com +*/ + +/* Elements */ +body { + background-image:url(images/bg_line.png); + background-position:top center; + background-repeat:repeat; + margin:0; + padding:0; +} \ No newline at end of file