/* (c) 2010 FIELD.IO */
Pre3d=(function(){function crossProduct(a,b){return{x:a.y*b.z-a.z*b.y,y:a.z*b.x-a.x*b.z,z:a.x*b.y-a.y*b.x};}
function dotProduct2d(a,b){return a.x*b.x+a.y*b.y;}
function dotProduct3d(a,b){return a.x*b.x+a.y*b.y+a.z*b.z;}
function subPoints2d(a,b){return{x:a.x-b.x,y:a.y-b.y};}
function subPoints3d(a,b){return{x:a.x-b.x,y:a.y-b.y,z:a.z-b.z};}
function subPoints2dIP(c,a,b){c.x=a.x-b.x;c.y=a.y-b.y;return c;}
function subPoints3dIP(c,a,b){c.x=a.x-b.x;c.y=a.y-b.y;c.z=a.z-b.z;return c;}
function addPoints2d(a,b){return{x:a.x+b.x,y:a.y+b.y};}
function addPoints3d(a,b){return{x:a.x+b.x,y:a.y+b.y,z:a.z+b.z};}
function addPoints2dIP(c,a,b){c.x=a.x+b.x;c.y=a.y+b.y;return c;}
function addPoints3dIP(c,a,b){c.x=a.x+b.x;c.y=a.y+b.y;c.z=a.z+b.z;return c;}
function mulPoint2d(a,s){return{x:a.x*s,y:a.y*s};}
function mulPoint3d(a,s){return{x:a.x*s,y:a.y*s,z:a.z*s};}
function vecMag2d(a){var ax=a.x,ay=a.y;return Math.sqrt(ax*ax+ay*ay);}
function vecMag3d(a){var ax=a.x,ay=a.y,az=a.z;return Math.sqrt(ax*ax+ay*ay+az*az);}
function unitVector2d(a){return mulPoint2d(a,1/vecMag2d(a));}
function unitVector3d(a){return mulPoint3d(a,1/vecMag3d(a));}
function linearInterpolate(a,b,d){return(b-a)*d+a;}
function linearInterpolatePoints3d(a,b,d){return{x:(b.x-a.x)*d+a.x,y:(b.y-a.y)*d+a.y,z:(b.z-a.z)*d+a.z}}
function AffineMatrix(e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11){this.e0=e0;this.e1=e1;this.e2=e2;this.e3=e3;this.e4=e4;this.e5=e5;this.e6=e6;this.e7=e7;this.e8=e8;this.e9=e9;this.e10=e10;this.e11=e11;};function multiplyAffine(a,b){var a0=a.e0,a1=a.e1,a2=a.e2,a3=a.e3,a4=a.e4,a5=a.e5;var a6=a.e6,a7=a.e7,a8=a.e8,a9=a.e9,a10=a.e10,a11=a.e11;var b0=b.e0,b1=b.e1,b2=b.e2,b3=b.e3,b4=b.e4,b5=b.e5;var b6=b.e6,b7=b.e7,b8=b.e8,b9=b.e9,b10=b.e10,b11=b.e11;return new AffineMatrix(a0*b0+a1*b4+a2*b8,a0*b1+a1*b5+a2*b9,a0*b2+a1*b6+a2*b10,a0*b3+a1*b7+a2*b11+a3,a4*b0+a5*b4+a6*b8,a4*b1+a5*b5+a6*b9,a4*b2+a5*b6+a6*b10,a4*b3+a5*b7+a6*b11+a7,a8*b0+a9*b4+a10*b8,a8*b1+a9*b5+a10*b9,a8*b2+a9*b6+a10*b10,a8*b3+a9*b7+a10*b11+a11);}
function makeIdentityAffine(){return new AffineMatrix(1,0,0,0,0,1,0,0,0,0,1,0);}
function makeRotateAffineX(theta){var s=Math.sin(theta);var c=Math.cos(theta);return new AffineMatrix(1,0,0,0,0,c,-s,0,0,s,c,0);}
function makeRotateAffineY(theta){var s=Math.sin(theta);var c=Math.cos(theta);return new AffineMatrix(c,0,s,0,0,1,0,0,-s,0,c,0);}
function makeRotateAffineZ(theta){var s=Math.sin(theta);var c=Math.cos(theta);return new AffineMatrix(c,-s,0,0,s,c,0,0,0,0,1,0);}
function makeTranslateAffine(dx,dy,dz){return new AffineMatrix(1,0,0,dx,0,1,0,dy,0,0,1,dz);}
function makeScaleAffine(sx,sy,sz){return new AffineMatrix(sx,0,0,0,0,sy,0,0,0,0,sz,0);}
function dupAffine(m){return new AffineMatrix(m.e0,m.e1,m.e2,m.e3,m.e4,m.e5,m.e6,m.e7,m.e8,m.e9,m.e10,m.e11);}
function transAdjoint(a){var a0=a.e0,a1=a.e1,a2=a.e2,a4=a.e4,a5=a.e5;var a6=a.e6,a8=a.e8,a9=a.e9,a10=a.e10;return new AffineMatrix(a10*a5-a6*a9,a6*a8-a4*a10,a4*a9-a8*a5,0,a2*a9-a10*a1,a10*a0-a2*a8,a8*a1-a0*a9,0,a6*a1-a2*a5,a4*a2-a6*a0,a0*a5-a4*a1,0);}
function transformPoint(t,p){return{x:t.e0*p.x+t.e1*p.y+t.e2*p.z+t.e3,y:t.e4*p.x+t.e5*p.y+t.e6*p.z+t.e7,z:t.e8*p.x+t.e9*p.y+t.e10*p.z+t.e11};}
function Transform(){this.reset();}
Transform.prototype.reset=function(){this.m=makeIdentityAffine();};Transform.prototype.rotateX=function(theta){this.m=multiplyAffine(makeRotateAffineX(theta),this.m);};Transform.prototype.rotateXPre=function(theta){this.m=multiplyAffine(this.m,makeRotateAffineX(theta));};Transform.prototype.rotateY=function(theta){this.m=multiplyAffine(makeRotateAffineY(theta),this.m);};Transform.prototype.rotateYPre=function(theta){this.m=multiplyAffine(this.m,makeRotateAffineY(theta));};Transform.prototype.rotateZ=function(theta){this.m=multiplyAffine(makeRotateAffineZ(theta),this.m);};Transform.prototype.rotateZPre=function(theta){this.m=multiplyAffine(this.m,makeRotateAffineZ(theta));};Transform.prototype.translate=function(dx,dy,dz){this.m=multiplyAffine(makeTranslateAffine(dx,dy,dz),this.m);};Transform.prototype.translatePre=function(dx,dy,dz){this.m=multiplyAffine(this.m,makeTranslateAffine(dx,dy,dz));};Transform.prototype.scale=function(sx,sy,sz){this.m=multiplyAffine(makeScaleAffine(sx,sy,sz),this.m);};Transform.prototype.scalePre=function(sx,sy,sz){this.m=multiplyAffine(this.m,makeScaleAffine(sx,sy,sz));};Transform.prototype.transformPoint=function(p){return transformPoint(this.m,p);};Transform.prototype.multTransform=function(t){this.m=multiplyAffine(this.m,t.m);};Transform.prototype.setDCM=function(u,v,w){var m=this.m;m.e0=u.x;m.e4=u.y;m.e8=u.z;m.e1=v.x;m.e5=v.y;m.e9=v.z;m.e2=w.x;m.e6=w.y;m.e10=w.z;};Transform.prototype.dup=function(){var tm=new Transform();tm.m=dupAffine(this.m);return tm;};function transformPoints(t,ps){var il=ps.length;var out=Array(il);for(var i=0;i<il;++i){out[i]=transformPoint(t,ps[i]);}
return out;}
function averagePoints(ps){var avg={x:0,y:0,z:0};for(var i=0,il=ps.length;i<il;++i){var p=ps[i];avg.x+=p.x;avg.y+=p.y;avg.z+=p.z;}
var f=1/il;avg.x*=f;avg.y*=f;avg.z*=f;return avg;}
function pushPoints2dIP(a,b){var vec=unitVector2d(subPoints2d(b,a));addPoints2dIP(b,b,vec);subPoints2dIP(a,a,vec);}
function RGBA(r,g,b,a){this.setRGBA(r,g,b,a);};RGBA.prototype.setRGBA=function(r,g,b,a){this.r=r;this.g=g;this.b=b;this.a=a;};RGBA.prototype.setRGB=function(r,g,b){this.setRGBA(r,g,b,1);};RGBA.prototype.invert=function(){this.r=1-this.r;this.g=1-this.g;this.b=1-this.b;};RGBA.prototype.dup=function(){return new RGBA(this.r,this.g,this.b,this.a);};function QuadFace(i0,i1,i2,i3){this.i0=i0;this.i1=i1;this.i2=i2;this.i3=i3;this.centroid=null;this.normal1=null;this.normal2=null;}
QuadFace.prototype.isTriangle=function(){return(this.i3===null);};QuadFace.prototype.setQuad=function(i0,i1,i2,i3){this.i0=i0;this.i1=i1;this.i2=i2;this.i3=i3;};QuadFace.prototype.setTriangle=function(i0,i1,i2){this.i0=i0;this.i1=i1;this.i2=i2;this.i3=null;};function Shape(){this.vertices=[];this.quads=[];}
function Curve(ep,c0,c1){this.ep=ep;this.c0=c0;this.c1=c1;}
Curve.prototype.isQuadratic=function(){return(this.c1===null);};Curve.prototype.setQuadratic=function(ep,c0){this.ep=ep;this.c0=c0;this.c1=null;};Curve.prototype.setCubic=function(ep,c0,c1){this.ep=ep;this.c0=c0;this.c1=c1;};function Path(){this.points=[];this.curves=[];this.starting_point=null;}
function Camera(){this.transform=new Transform();this.focal_length=1;}
function TextureInfo(){this.image=null;this.u0=null;this.v0=null;this.u1=null;this.v1=null;this.u2=null;this.v2=null;this.u3=null;this.v3=null;};function Renderer(canvas_element){this.perform_z_sorting=true;this.draw_overdraw=true;this.draw_backfaces=false;this.lights_enabled=true;this.light_ambient=0;this.light_diffuse=1;this.texture=null;this.fill_rgba=new RGBA(1,0,0,1);this.stroke_rgba=null;this.normal1_rgba=null;this.normal2_rgba=null;this.canvas=canvas_element;this.ctx=canvas_element.getContext('2d');this.camera=new Camera();this.transform=new Transform();this.transform_stack_=[];this.quad_callback=null;this.width_=canvas_element.width;this.height_=canvas_element.height;this.scale_=this.height_/2;this.xoff_=this.width_/2;this.buffered_quads_=null;this.emptyBuffer();if(this.ctx.setStrokeColor==null){this.ctx.setStrokeColor=function setStrokeColor(r,g,b,a){var rgba=[Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a];this.strokeStyle='rgba('+rgba.join(',')+')';}}
if(this.ctx.setFillColor==null){this.ctx.setFillColor=function setFillColor(r,g,b,a){var rgba=[Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a];this.fillStyle='rgba('+rgba.join(',')+')';}}}
Renderer.prototype.pushTransform=function(){this.transform_stack_.push(this.transform.dup());};Renderer.prototype.popTransform=function(){this.transform=this.transform_stack_.pop();};Renderer.prototype.emptyBuffer=function(){this.buffered_quads_=[];};Renderer.prototype.projectPointToCanvas=function projectPointToCanvas(p){var v=this.camera.focal_length/-p.z;var scale=this.scale_;return{x:p.x*v*scale+this.xoff_,y:p.y*v*-scale+scale};};Renderer.prototype.projectPointsToCanvas=function projectPointsToCanvas(ps){var il=ps.length;var out=Array(il);for(var i=0;i<il;++i){out[i]=this.projectPointToCanvas(ps[i]);}
return out;};Renderer.prototype.projectQuadFaceToCanvasIP=function(qf){qf.i0=this.projectPointToCanvas(qf.i0);qf.i1=this.projectPointToCanvas(qf.i1);qf.i2=this.projectPointToCanvas(qf.i2);if(!qf.isTriangle())
qf.i3=this.projectPointToCanvas(qf.i3);return qf;};function drawCanvasTexturedTriangle(ctx,im,x0,y0,x1,y1,x2,y2,sx0,sy0,sx1,sy1,sx2,sy2){ctx.save();ctx.beginPath();ctx.moveTo(x0,y0);ctx.lineTo(x1,y1);ctx.lineTo(x2,y2);ctx.closePath();ctx.clip();var denom=sx0*(sy2-sy1)-
sx1*sy2+
sx2*sy1+
(sx1-sx2)*sy0;var m11=-(sy0*(x2-x1)-
sy1*x2+
sy2*x1+
(sy1-sy2)*x0)/denom;var m12=(sy1*y2+
sy0*(y1-y2)-
sy2*y1+
(sy2-sy1)*y0)/denom;var m21=(sx0*(x2-x1)-
sx1*x2+
sx2*x1+
(sx1-sx2)*x0)/denom;var m22=-(sx1*y2+
sx0*(y1-y2)-
sx2*y1+
(sx2-sx1)*y0)/denom;var dx=(sx0*(sy2*x1-sy1*x2)+
sy0*(sx1*x2-sx2*x1)+
(sx2*sy1-sx1*sy2)*x0)/denom;var dy=(sx0*(sy2*y1-sy1*y2)+
sy0*(sx1*y2-sx2*y1)+
(sx2*sy1-sx1*sy2)*y0)/denom;ctx.transform(m11,m12,m21,m22,dx,dy);ctx.drawImage(im,0,0);ctx.restore();}
var g_z_axis_vector={x:0,y:0,z:1};Renderer.prototype.bufferShape=function bufferShape(shape){var draw_backfaces=this.draw_backfaces;var quad_callback=this.quad_callback;var t=multiplyAffine(this.camera.transform.m,this.transform.m);var tn=transAdjoint(t);var world_vertices=transformPoints(t,shape.vertices);var quads=shape.quads;for(var j=0,jl=shape.quads.length;j<jl;++j){var qf=quads[j];if(quad_callback!==null&&quad_callback(qf,j,shape)===true)
continue;var centroid=transformPoint(t,qf.centroid);if(centroid.z>=-1)
continue;var n1=unitVector3d(transformPoint(tn,qf.normal1));var n2=transformPoint(tn,qf.normal2);if(draw_backfaces!==true&&dotProduct3d(centroid,n1)>0&&dotProduct3d(centroid,n2)>0){continue;}
var intensity=this.lights_enabled?dotProduct3d(g_z_axis_vector,n1):1;intensity=intensity*this.light_diffuse+this.light_ambient;if(intensity>1)intensity=1;if(intensity<0)intensity=0;var world_qf;if(qf.isTriangle()===true){world_qf=new QuadFace(world_vertices[qf.i0],world_vertices[qf.i1],world_vertices[qf.i2],null);}else{world_qf=new QuadFace(world_vertices[qf.i0],world_vertices[qf.i1],world_vertices[qf.i2],world_vertices[qf.i3]);}
world_qf.centroid=centroid;world_qf.normal1=n1;world_qf.normal2=n2;var obj={qf:world_qf,intensity:intensity,draw_overdraw:this.draw_overdraw,texture:this.texture,fill_rgba:this.fill_rgba,stroke_rgba:this.stroke_rgba,normal1_rgba:this.normal1_rgba,normal2_rgba:this.normal2_rgba,};this.buffered_quads_.push(obj);}};function zSorter(x,y){return x.qf.centroid.z-y.qf.centroid.z;}
Renderer.prototype.drawBackground=function(){this.ctx.fillRect(0,0,this.width_,this.height_);};Renderer.prototype.clearBackground=function(){this.ctx.clearRect(0,0,this.width_,this.height_);};Renderer.prototype.drawBuffer=function drawBuffer(){var ctx=this.ctx;var all_quads=this.buffered_quads_;var num_quads=all_quads.length;if(this.perform_z_sorting===true)
all_quads.sort(zSorter);for(var j=0;j<num_quads;++j){var obj=all_quads[j];var qf=obj.qf;this.projectQuadFaceToCanvasIP(qf);var is_triangle=qf.isTriangle();if(obj.draw_overdraw===true){pushPoints2dIP(qf.i0,qf.i1);pushPoints2dIP(qf.i1,qf.i2);if(is_triangle===true){pushPoints2dIP(qf.i2,qf.i0);}else{pushPoints2dIP(qf.i2,qf.i3);pushPoints2dIP(qf.i3,qf.i0);}}
ctx.beginPath();ctx.moveTo(qf.i0.x,qf.i0.y);ctx.lineTo(qf.i1.x,qf.i1.y);ctx.lineTo(qf.i2.x,qf.i2.y);if(is_triangle!==true)
ctx.lineTo(qf.i3.x,qf.i3.y);var frgba=obj.fill_rgba;if(frgba!==null){var iy=obj.intensity;ctx.setFillColor(frgba.r*iy,frgba.g*iy,frgba.b*iy,frgba.a);ctx.fill();}
var texture=obj.texture;if(texture!==null){drawCanvasTexturedTriangle(ctx,texture.image,qf.i0.x,qf.i0.y,qf.i1.x,qf.i1.y,qf.i2.x,qf.i2.y,texture.u0,texture.v0,texture.u1,texture.v1,texture.u2,texture.v2);if(!is_triangle){drawCanvasTexturedTriangle(ctx,texture.image,qf.i0.x,qf.i0.y,qf.i2.x,qf.i2.y,qf.i3.x,qf.i3.y,texture.u0,texture.v0,texture.u2,texture.v2,texture.u3,texture.v3);}}
var srgba=obj.stroke_rgba;if(srgba!==null){ctx.closePath();ctx.setStrokeColor(srgba.r,srgba.g,srgba.b,srgba.a);ctx.stroke();}
var n1r=obj.normal1_rgba;var n2r=obj.normal2_rgba;if(n1r!==null){ctx.setStrokeColor(n1r.r,n1r.g,n1r.b,n1r.a);var screen_centroid=this.projectPointToCanvas(qf.centroid);var screen_point=this.projectPointToCanvas(addPoints3d(qf.centroid,unitVector3d(qf.normal1)));ctx.beginPath();ctx.moveTo(screen_centroid.x,screen_centroid.y);ctx.lineTo(screen_point.x,screen_point.y);ctx.stroke();}
if(n2r!==null){ctx.setStrokeColor(n2r.r,n2r.g,n2r.b,n2r.a);var screen_centroid=this.projectPointToCanvas(qf.centroid);var screen_point=this.projectPointToCanvas(addPoints3d(qf.centroid,unitVector3d(qf.normal2)));ctx.beginPath();ctx.moveTo(screen_centroid.x,screen_centroid.y);ctx.lineTo(screen_point.x,screen_point.y);ctx.stroke();}}
return num_quads;}
Renderer.prototype.drawPath=function drawPath(path,opts){var ctx=this.ctx;var opts=opts||{};var t=multiplyAffine(this.camera.transform.m,this.transform.m);var screen_points=this.projectPointsToCanvas(transformPoints(t,path.points));var start_point=(path.starting_point===null?this.projectPointToCanvas(transformPoint(t,{x:0,y:0,z:0})):screen_points[path.starting_point]);ctx.beginPath();ctx.moveTo(start_point.x,start_point.y);var curves=path.curves;for(var j=0,jl=curves.length;j<jl;++j){var curve=curves[j];if(curve.isQuadratic()===true){var c0=screen_points[curve.c0];var ep=screen_points[curve.ep];ctx.quadraticCurveTo(c0.x,c0.y,ep.x,ep.y);}else{var c0=screen_points[curve.c0];var c1=screen_points[curve.c1];var ep=screen_points[curve.ep];ctx.bezierCurveTo(c0.x,c0.y,c1.x,c1.y,ep.x,ep.y);}}
if(opts.fill===true){ctx.fill();}else{ctx.stroke();}};return{RGBA:RGBA,AffineMatrix:AffineMatrix,Transform:Transform,QuadFace:QuadFace,Shape:Shape,Curve:Curve,Path:Path,Camera:Camera,TextureInfo:TextureInfo,Renderer:Renderer,Math:{crossProduct:crossProduct,dotProduct2d:dotProduct2d,dotProduct3d:dotProduct3d,subPoints2d:subPoints2d,subPoints3d:subPoints3d,addPoints2d:addPoints2d,addPoints3d:addPoints3d,mulPoint2d:mulPoint2d,mulPoint3d:mulPoint3d,vecMag2d:vecMag2d,vecMag3d:vecMag3d,unitVector2d:unitVector2d,unitVector3d:unitVector3d,linearInterpolate:linearInterpolate,linearInterpolatePoints3d:linearInterpolatePoints3d,averagePoints:averagePoints,},};})();Pre3d.PathUtils=(function(){function makeCircle(){var kKappa=0.66666666666;var path=new Pre3d.Path();path.points=[{x:0,y:kKappa,z:0},{x:1,y:kKappa,z:0},{x:1,y:0,z:0},{x:1,y:-kKappa,z:0},{x:0,y:-kKappa,z:0},{x:0,y:0,z:0}];path.curves=[new Pre3d.Curve(2,0,1),new Pre3d.Curve(5,3,4)];return path;}
function makeSpiral(count){var kKappa=0.66666666666;var points=[];var curves=[];var z=0;var p=0;for(var i=0;i<count;++i){points.push({x:0,y:kKappa,z:z});z-=0.05;points.push({x:1,y:kKappa,z:z});points.push({x:1,y:0,z:z});points.push({x:1,y:-kKappa,z:z});z-=0.05;points.push({x:0,y:-kKappa,z:z});points.push({x:0,y:0,z:z});curves.push(new Pre3d.Curve(p+2,p+0,p+1));curves.push(new Pre3d.Curve(p+5,p+3,p+4));p+=6;}
var path=new Pre3d.Path();path.points=points;path.curves=curves;return path;}
function fitQuadraticToPoints(p0,p1,p2){return{x:p1.x+p1.x-0.5*(p0.x+p2.x),y:p1.y+p1.y-0.5*(p0.y+p2.y),z:p1.z+p1.z-0.5*(p0.z+p2.z)};}
return{makeCircle:makeCircle,makeSpiral:makeSpiral,fitQuadraticToPoints:fitQuadraticToPoints};})();Pre3d.ShapeUtils=(function(){var crossProduct=Pre3d.Math.crossProduct;var dotProduct2d=Pre3d.Math.dotProduct2d;var dotProduct3d=Pre3d.Math.dotProduct3d;var subPoints2d=Pre3d.Math.subPoints2d;var subPoints3d=Pre3d.Math.subPoints3d;var addPoints2d=Pre3d.Math.addPoints2d;var addPoints3d=Pre3d.Math.addPoints3d;var mulPoint2d=Pre3d.Math.mulPoint2d;var mulPoint3d=Pre3d.Math.mulPoint3d;var vecMag2d=Pre3d.Math.vecMag2d;var vecMag3d=Pre3d.Math.vecMag3d;var unitVector2d=Pre3d.Math.unitVector2d;var unitVector3d=Pre3d.Math.unitVector3d;var linearInterpolate=Pre3d.Math.linearInterpolate;var linearInterpolatePoints3d=Pre3d.Math.linearInterpolatePoints3d;var averagePoints=Pre3d.Math.averagePoints;var k2PI=Math.PI*2;function averagePoints2(a,b){return{x:(a.x+b.x)*0.5,y:(a.y+b.y)*0.5,z:(a.z+b.z)*0.5};}
function rebuildMeta(shape){var quads=shape.quads;var num_quads=quads.length;var vertices=shape.vertices;for(var i=0;i<num_quads;++i){var qf=quads[i];var centroid;var n1,n2,na;var vert0=vertices[qf.i0];var vert1=vertices[qf.i1];var vert2=vertices[qf.i2];var vec01=subPoints3d(vert1,vert0);var vec02=subPoints3d(vert2,vert0);var n1=crossProduct(vec01,vec02);if(qf.isTriangle()){n2=na=n1;centroid=averagePoints([vert0,vert1,vert2]);}else{var vert3=vertices[qf.i3];var vec03=subPoints3d(vert3,vert0);n2=crossProduct(vec02,vec03);na=averagePoints2(n1,n2);centroid=averagePoints([vert0,vert1,vert2,vert3]);}
qf.centroid=centroid;qf.normal1=n1;qf.normal2=n2;}}
function triangulate(shape){var quads=shape.quads;var num_quads=quads.length;for(var i=0;i<num_quads;++i){var qf=quads[i];if(qf.isTriangle())
continue;var newtri=new Pre3d.QuadFace(qf.i0,qf.i2,qf.i3,null);qf.i3=null;quads.push(newtri);}
rebuildMeta(shape);}
function forEachFace(shape,func){var quads=this.quads;for(var i=0,il=quads.length;i<il;++i){if(func(quads[i],i,this)===true)
break;}};function makePlane(p1,p2,p3,p4){var s=new Pre3d.Shape();s.vertices=[p1,p2,p3,p4];s.quads=[new Pre3d.QuadFace(0,1,2,3)];rebuildMeta(s);return s;}
function makeBox(w,h,d){var s=new Pre3d.Shape();s.vertices=[{x:w,y:h,z:-d},{x:w,y:h,z:d},{x:w,y:-h,z:d},{x:w,y:-h,z:-d},{x:-w,y:h,z:-d},{x:-w,y:h,z:d},{x:-w,y:-h,z:d},{x:-w,y:-h,z:-d}];s.quads=[new Pre3d.QuadFace(0,1,2,3),new Pre3d.QuadFace(1,5,6,2),new Pre3d.QuadFace(5,4,7,6),new Pre3d.QuadFace(4,0,3,7),new Pre3d.QuadFace(0,4,5,1),new Pre3d.QuadFace(2,6,7,3)];rebuildMeta(s);return s;}
function makeCube(whd){return makeBox(whd,whd,whd);}
function makeBoxWithHole(w,h,d,hw,hh){var s=new Pre3d.Shape();s.vertices=[{x:w,y:h,z:-d},{x:w,y:h,z:d},{x:w,y:-h,z:d},{x:w,y:-h,z:-d},{x:-w,y:h,z:-d},{x:-w,y:h,z:d},{x:-w,y:-h,z:d},{x:-w,y:-h,z:-d},{x:hw,y:h,z:d},{x:w,y:hh,z:d},{x:hw,y:hh,z:d},{x:hw,y:-h,z:d},{x:w,y:-hh,z:d},{x:hw,y:-hh,z:d},{x:-hw,y:h,z:d},{x:-w,y:hh,z:d},{x:-hw,y:hh,z:d},{x:-hw,y:-h,z:d},{x:-w,y:-hh,z:d},{x:-hw,y:-hh,z:d},{x:hw,y:h,z:-d},{x:w,y:hh,z:-d},{x:hw,y:hh,z:-d},{x:hw,y:-h,z:-d},{x:w,y:-hh,z:-d},{x:hw,y:-hh,z:-d},{x:-hw,y:h,z:-d},{x:-w,y:hh,z:-d},{x:-hw,y:hh,z:-d},{x:-hw,y:-h,z:-d},{x:-w,y:-hh,z:-d},{x:-hw,y:-hh,z:-d}];s.quads=[new Pre3d.QuadFace(1,8,10,9),new Pre3d.QuadFace(8,14,16,10),new Pre3d.QuadFace(14,5,15,16),new Pre3d.QuadFace(16,15,18,19),new Pre3d.QuadFace(19,18,6,17),new Pre3d.QuadFace(13,19,17,11),new Pre3d.QuadFace(12,13,11,2),new Pre3d.QuadFace(9,10,13,12),new Pre3d.QuadFace(4,26,28,27),new Pre3d.QuadFace(26,20,22,28),new Pre3d.QuadFace(20,0,21,22),new Pre3d.QuadFace(22,21,24,25),new Pre3d.QuadFace(25,24,3,23),new Pre3d.QuadFace(31,25,23,29),new Pre3d.QuadFace(30,31,29,7),new Pre3d.QuadFace(27,28,31,30),new Pre3d.QuadFace(10,16,28,22),new Pre3d.QuadFace(19,31,28,16),new Pre3d.QuadFace(13,25,31,19),new Pre3d.QuadFace(10,22,25,13),new Pre3d.QuadFace(6,7,29,17),new Pre3d.QuadFace(17,29,23,11),new Pre3d.QuadFace(11,23,3,2),new Pre3d.QuadFace(1,9,21,0),new Pre3d.QuadFace(9,12,24,21),new Pre3d.QuadFace(12,2,3,24),new Pre3d.QuadFace(5,4,27,15),new Pre3d.QuadFace(15,27,30,18),new Pre3d.QuadFace(18,30,7,6),new Pre3d.QuadFace(14,26,4,5),new Pre3d.QuadFace(8,20,26,14),new Pre3d.QuadFace(1,0,20,8)];rebuildMeta(s);return s;}
function makeSphere(r,tess_x,tess_y){var vertices=[];var quads=[];var theta_step=Math.PI/(tess_y+1);var phi_step=(k2PI)/tess_x;for(var i=0,theta=theta_step;i<tess_y;++i,theta+=theta_step){var sin_theta=Math.sin(theta);var cos_theta=Math.cos(theta);for(var j=0;j<tess_x;++j){var phi=phi_step*j;vertices.push({x:r*sin_theta*Math.sin(phi),y:r*cos_theta,z:r*sin_theta*Math.cos(phi)});}}
for(var i=0;i<tess_y-1;++i){var stride=i*tess_x;for(var j=0;j<tess_x;++j){var n=(j+1)%tess_x;quads.push(new Pre3d.QuadFace(stride+j,stride+tess_x+j,stride+tess_x+n,stride+n));}}
var last_row=vertices.length-tess_x;var top_p_i=vertices.length;var bot_p_i=top_p_i+1;vertices.push({x:0,y:r,z:0});vertices.push({x:0,y:-r,z:0});for(var i=0;i<tess_x;++i){quads.push(new Pre3d.QuadFace(top_p_i,i,((i+1)%tess_x),null));quads.push(new Pre3d.QuadFace(bot_p_i,last_row+((i+2)%tess_x),last_row+((i+1)%tess_x),null));}
var s=new Pre3d.Shape();s.vertices=vertices;s.quads=quads;rebuildMeta(s);return s;}
function averageSmooth(shape,m){if(m===void(0))
m=1;var vertices=shape.vertices;var psl=vertices.length;var new_ps=Array(psl);var connections=Array(psl);for(var i=0;i<psl;++i)
connections[i]=[];for(var i=0,il=shape.quads.length;i<il;++i){var qf=shape.quads[i];connections[qf.i0].push(i);connections[qf.i1].push(i);connections[qf.i2].push(i);if(!qf.isTriangle())
connections[qf.i3].push(i);}
for(var i=0,il=vertices.length;i<il;++i){var cs=connections[i];var avg={x:0,y:0,z:0};for(var j=0,jl=cs.length;j<jl;++j){var quad=shape.quads[cs[j]];var p1=vertices[quad.i0];var p2=vertices[quad.i1];var p3=vertices[quad.i2];var p4=vertices[quad.i3];avg.x+=(p1.x+p2.x+p3.x+p4.x)/4;avg.y+=(p1.y+p2.y+p3.y+p4.y)/4;avg.z+=(p1.z+p2.z+p3.z+p4.z)/4;}
var f=1/jl;avg.x*=f;avg.y*=f;avg.z*=f;new_ps[i]=linearInterpolatePoints3d(vertices[i],avg,m);}
shape.vertices=new_ps;rebuildMeta(shape);}
function linearSubdivide(shape){var num_quads=shape.quads.length;var share_points={};for(var i=0;i<num_quads;++i){var quad=shape.quads[i];var i0=quad.i0;var i1=quad.i1;var i2=quad.i2;var i3=quad.i3;var p0=shape.vertices[i0];var p1=shape.vertices[i1];var p2=shape.vertices[i2];var p3=shape.vertices[i3];var ni=[[i0,i1].sort(),[i1,i2].sort(),[i2,i3].sort(),[i3,i0].sort(),[i0,i1,i2,i3].sort(),];for(var j=0,jl=ni.length;j<jl;++j){var ps=ni[j];var key=ps.join('-');var centroid_index=share_points[key];if(centroid_index==null){centroid_index=shape.vertices.length;var s=shape;shape.vertices.push(averagePoints(ps.map(function(x){return s.vertices[x];})));share_points[key]=centroid_index;}
ni[j]=centroid_index;}
var q0=new Pre3d.QuadFace(i0,ni[0],ni[4],ni[3]);var q1=new Pre3d.QuadFace(ni[0],i1,ni[1],ni[4]);var q2=new Pre3d.QuadFace(ni[4],ni[1],i2,ni[2]);var q3=new Pre3d.QuadFace(ni[3],ni[4],ni[2],i3);shape.quads[i]=q0;shape.quads.push(q1);shape.quads.push(q2);shape.quads.push(q3);}
rebuildMeta(shape);}
function Extruder(){this.distance_=1.0;this.count_=1;this.selector_=null;this.selectAll();this.scale={x:1,y:1,z:1};this.rotate={x:0,y:0,z:0};};Extruder.prototype.selectAll=function(){this.selector_=function(shape,vertex_index){return true;};};Extruder.prototype.selectCustom=function(select_func){this.selector_=select_func;};Extruder.prototype.distance=function(){return this.distance_;};Extruder.prototype.set_distance=function(d){this.distance_=d;};Extruder.prototype.count=function(){return this.count_;};Extruder.prototype.set_count=function(c){this.count_=c;};Extruder.prototype.extrude=function extrude(shape){var distance=this.distance();var count=this.count();var rx=this.rotate.x;var ry=this.rotate.y;var rz=this.rotate.z;var sx=this.scale.x;var sy=this.scale.y;var sz=this.scale.z;var vertices=shape.vertices;var quads=shape.quads;var faces=[];for(var i=0,il=quads.length;i<il;++i){if(this.selector_(shape,i))
faces.push(i);}
for(var i=0,il=faces.length;i<il;++i){var face_index=faces[i];var qf=quads[face_index];var original_cent=qf.centroid;var surface_normal=unitVector3d(addPoints3d(qf.normal1,qf.normal2));var is_triangle=qf.isTriangle();var inner_normal0=subPoints3d(vertices[qf.i0],original_cent);var inner_normal1=subPoints3d(vertices[qf.i1],original_cent);var inner_normal2=subPoints3d(vertices[qf.i2],original_cent);if(is_triangle!==true){var inner_normal3=subPoints3d(vertices[qf.i3],original_cent);}
for(var z=0;z<count;++z){var m=(z+1)/count;var t=new Pre3d.Transform();t.rotateX(rx*m);t.rotateY(ry*m);t.rotateZ(rz*m);var new_cent=addPoints3d(original_cent,mulPoint3d(t.transformPoint(surface_normal),m*distance));t.scalePre(linearInterpolate(1,sx,m),linearInterpolate(1,sy,m),linearInterpolate(1,sz,m));var index_before=vertices.length;vertices.push(addPoints3d(new_cent,t.transformPoint(inner_normal0)));vertices.push(addPoints3d(new_cent,t.transformPoint(inner_normal1)));vertices.push(addPoints3d(new_cent,t.transformPoint(inner_normal2)));if(is_triangle!==true){vertices.push(addPoints3d(new_cent,t.transformPoint(inner_normal3)));}
quads.push(new Pre3d.QuadFace(qf.i1,index_before+1,index_before,qf.i0));quads.push(new Pre3d.QuadFace(qf.i2,index_before+2,index_before+1,qf.i1));if(is_triangle===true){quads.push(new Pre3d.QuadFace(qf.i0,index_before,index_before+2,qf.i2));}else{quads.push(new Pre3d.QuadFace(qf.i3,index_before+3,index_before+2,qf.i2));quads.push(new Pre3d.QuadFace(qf.i0,index_before,index_before+3,qf.i3));}
qf.i0=index_before;qf.i1=index_before+1;qf.i2=index_before+2;if(is_triangle!==true)
qf.i3=index_before+3;}}
rebuildMeta(shape);};return{rebuildMeta:rebuildMeta,triangulate:triangulate,forEachFace:forEachFace,makePlane:makePlane,makeCube:makeCube,makeBox:makeBox,makeBoxWithHole:makeBoxWithHole,makeSphere:makeSphere,averageSmooth:averageSmooth,linearSubdivide:linearSubdivide,Extruder:Extruder,};})();fk={_baseURL:null,_templateURL:null,init:function(){var initializing=false,fnTest=/xyz/.test(function(){xyz;})?/\b_super\b/:/.*/;this.Class=function(){};fk.Class.extend=function(prop){var _super=this.prototype;initializing=true;var prototype=new this();initializing=false;for(var name in prop){prototype[name]=typeof prop[name]=="function"&&typeof _super[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,prop[name]):prop[name];}
function Class(){if(!initializing&&this.init)
this.init.apply(this,arguments);}
Class.prototype=prototype;Class.constructor=Class;Class.extend=arguments.callee;return Class;};},info:function(){if(window.console){var s=""
for(var i=0;i<arguments.length;i++)
s+=arguments[i]+' '
window.console.info(s)}},warn:function(){if(window.console){var s="WARNING: "
for(var i=0;i<arguments.length;i++)
s+=arguments[i]+' '
window.console.warn(s)}},error:function(){if(window.console){var s="WARNING: "
for(var i=0;i<arguments.length;i++)
s+=arguments[i]+' '
window.console.error(s)}},dec2hex:function(d){return d.toString(16);},hex2dec:function(h){return parseInt(h,16);},}
fk.particle={}
fk.particle3d={}
fk.init()
fk.Colour=fk.Class.extend({r:0,g:0,b:0,init:function(){if(arguments.length==3){this.set(arguments[0],arguments[1],arguments[2])}else if(arguments.length==1){this.set(arguments[0])}},set:function(){if(arguments.length==1){var arg=arguments[0]
if(typeof(arg)=='string'){if(arg.length==6){this.fromHex(arg);}
else{var parts=arg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/)
this.red(parts[1]);this.green(parts[2]);this.blue(parts[3]);}}else if(typeof(arg)=='object'){this.red(arg.r);this.green(arg.g);this.blue(arg.b)}else{fk.warn("fk.Colour.set: Invalid argument ("+arg+" <"+typeof(arg)+">)");}}else if(arguments.length==3){this.red(arguments[0]);this.green(arguments[1]);this.blue(arguments[2]);}
return this;},red:function(r){if(arguments.length==1)this.r=this.parseComponent(arguments[0]);return this.r;},green:function(g){if(arguments.length==1)this.g=this.parseComponent(arguments[0]);return this.g;},blue:function(b){if(arguments.length==1)this.b=this.parseComponent(arguments[0]);return this.b;},hue:function(){var hsv=this.toHSV();if(arguments.length==1){hsv[0]=arguments[0];this.fromHSV(hsv[0],hsv[1],hsv[2]);}
return hsv[0];},saturation:function(){var hsv=this.toHSV()
if(arguments.length==1){hsv[1]=arguments[0]
this.fromHSV(hsv[0],hsv[1],hsv[2])}
return hsv[1]},value:function(){var hsv=this.toHSV()
if(arguments.length==1){hsv[2]=arguments[0]
this.fromHSV(hsv[0],hsv[1],hsv[2])}
return hsv[2]},toHSL:function(){var _r=this.r/255
var _g=this.g/255
var _b=this.b/255
var max=Math.max(_r,_g,_b),min=Math.min(_r,_g,_b)
var h,s,l=(max+min)/2
if(max==min){h=s=0}else{var d=max-min
s=l>0.5?d/(2-max-min):d/(max+min)
switch(max){case _r:h=(_g-_b)/d+(_g<_b?6:0);break
case _g:h=(_b-_r)/d+2;break
case _b:h=(_r-_g)/d+4;break}
h/=6;}
return[h,s,l];},toHSV:function(){var _r=this.r/255
var _g=this.g/255
var _b=this.b/255
var max=Math.max(_r,_g,_b),min=Math.min(_r,_g,_b)
var h,s,v=max
var d=max-min
s=max==0?0:d/max
if(max==min){h=0;}else{switch(max){case _r:h=(_g-_b)/d+(_g<_b?6:0);break
case _g:h=(_b-_r)/d+2;break
case _b:h=(_r-_g)/d+4;break}
h/=6;}
return[h,s,v]},toHex:function(){return fk.dec2hex(this.toInt());},toInt:function(){return(this.r<<16)+(this.g<<8)+this.b;},fromHSL:function(h,s,l){if(s==0){r=g=b=l}else{function hue2rgb(p,q,t){if(t<0)t+=1
if(t>1)t-=1
if(t<1/6)return p+(q-p)*6*t
if(t<1/2)return q
if(t<2/3)return p+(q-p)*(2/3-t)*6
return p;}
var q=l<0.5?l*(1+s):l+s-l*s
var p=2*l-q
r=hue2rgb(p,q,h+1/3)
g=hue2rgb(p,q,h)
b=hue2rgb(p,q,h-1/3)}
return this},fromHSV:function(h,s,v){var i=Math.floor(h*6);var f=h*6-i;var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);switch(i%6){case 0:this.r=v,this.g=t,this.b=p;break
case 1:this.r=q,this.g=v,this.b=p;break
case 2:this.r=p,this.g=v,this.b=t;break
case 3:this.r=p,this.g=q,this.b=v;break
case 4:this.r=t,this.g=p,this.b=v;break
case 5:this.r=v,this.g=p,this.b=q;break};this.r*=255;this.g*=255;this.b*=255;return this;},fromHex:function(hex){return this.fromInt(fk.hex2dec(hex));},fromInt:function(i){this.r=(i>>16)&0xFF;this.g=(i>>8)&0xFF;this.b=i&0xFF;return this;},randomise:function(){this.red(Math.random());this.green(Math.random());this.blue(Math.random());return this;},slerp:function(target,delta){this.r=this.r*(1-delta)+target.r*delta;this.g=this.g*(1-delta)+target.g*delta;this.b=this.b*(1-delta)+target.b*delta;return this;},interpolate:function(target,delta){this.r+=(target.r-this.r)*delta;this.g+=(target.g-this.g)*delta;this.b+=(target.b-this.b)*delta;return this;},clone:function(){return new fk.Colour(this);},toString:function(){return'Colour['+this.r+', '+this.g+', '+this.b+']';},parseComponent:function(arg){if(typeof(arg)=='number'){var n=arg
if(n<0)n*=-1
if(n<1.0)n*=255
if(n>255)n=255
return n}else if(typeof(arg)=='string'){return this.parseComponent(parseFloat(arg))}else{fk.info("fk.Colour.parseComponent: unhandled type "+typeof(arg)+" "+arg)
return arg}},});fk.math={PI:Math.PI,HALF_PI:Math.PI*0.5,TWO_PI:Math.PI*2,DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,Rect:function(){this.x1=0
this.y1=0
this.x2=0
this.y2=0
if(arguments.length==4){this.x1=arguments[0]
this.y1=arguments[1]
this.x2=arguments[2]
this.y2=arguments[3]}
this.intersects=function(r){return r.x2>this.x1&&r.y2>this.y1&&r.x1<this.x2&&r.y1<this.y2}
this.contains=function(r){return r.x1>=this.x1&&r.y1>=this.y1&&r.x2<=this.x2&&r.y2<=this.y2}},random:function(min,max){return Math.random()*(max-min)+min},randomInt:function(min,max){return parseInt(Math.random()*(max-min)+min)},randomNormal:function(){return Math.random()>0.5?1:-1;},flipCoin:function(){return Math.random()>0.5?true:false;},slerp:function(cur,to,delta){return cur*(1-delta)+to*delta},slerpAngle:function(cur,to,delta){if(cur<0&&to>0){if(Math.abs(cur)>this.HALF_PI&&Math.abs(to)>this.HALF_PI)
cur+=this.TWO_PI}else if(cur>0&&to<0){if(Math.abs(cur)>this.HALF_PI&&Math.abs(to)>this.HALF_PI)
cur-=this.TWO_PI}
return cur*(1-delta)+to*delta},}
fk.math.Vec2=fk.Class.extend({x:0,y:0,init:function(){switch(arguments.length){case 1:this.setS(arguments[0]);break;case 2:this.set(arguments[0],arguments[1]);break;};},set:function(x,y){this.x=x;this.y=y;return this;},setV:function(v){this.x=v.x;this.y=v.y;return this;},setS:function(s){this.x=s;this.y=s;return this;},add:function(x,y){this.x+=x;this.y+=y;return this;},sub:function(x,y){this.x-=x;this.y-=y;return this;},mul:function(x,y){this.x*=x;this.y*=y;return this;},div:function(x,y){this.x/=x;this.y/=y;return this;},addV:function(v){this.x+=v.x;this.y+=v.y;return this;},subV:function(v){this.x-=v.x;this.y-=v.y;return this;},mulV:function(v){this.x*=v.x;this.y*=v.y;return this;},divV:function(v){this.x/=v.x;this.y/=v.y;return this;},addS:function(s){this.x+=s;this.y+=s;return this;},subS:function(s){this.x-=s;this.y-=s;return this;},mulS:function(s){this.x*=s;this.y*=s;return this;},divS:function(s){this.x/=s;this.y/=s;return this;},zero:function(){this.x=0;this.y=0;return this;},normalize:function(){var l=this.length();return(l!=0)?this.divS(l):this;},lengthSquared:function(){return this.x*this.x+this.y*this.y;},length:function(){return Math.sqrt(this.lengthSquared());},clamp:function(max){var l=this.length();if(l>max){this.divS(l);this.mulS(max);}
return this;},distance:function(x,y){return Math.sqrt(this.distanceSquared(x,y));},distanceV:function(v){return Math.sqrt(this.distanceSquared(v.x,v.y));},distanceSquared:function(x,y){var dx=this.x-x;var dy=this.y-y;return dx*dx+dy*dy;},toString:function(){return"Vec2("+this.x+","+this.y+")";},});fk.math.Vec3=fk.Class.extend({x:0,y:0,z:0,init:function(){switch(arguments.length){case 1:this.setV(arguments[0]);break;case 3:this.set(arguments[0],arguments[1],arguments[2]);break;};},set:function(x,y,z){this.x=x;this.y=y;this.z=z;return this;},setV:function(v){this.x=v.x;this.y=v.y;this.z=v.z;return this;},setS:function(s){this.x=s;this.y=s;this.z=s;return this;},add:function(x,y,z){this.x+=x;this.y+=y;this.z+=z;return this;},sub:function(x,y,z){this.x-=x;this.y-=y;this.z-=z;return this;},mul:function(x,y,z){this.x*=x;this.y*=y;this.z*=z;return this;},div:function(x,y,z){this.x/=x;this.y/=y;this.z/=z;return this;},addV:function(v){this.x+=v.x;this.y+=v.y;this.z+=v.z;return this;},subV:function(v){this.x-=v.x;this.y-=v.y;this.z-=v.z;return this;},mulV:function(v){this.x*=v.x;this.y*=v.y;this.z*=v.z;return this},divV:function(v){this.x/=v.x;this.y/=v.y;this.z/=v.z;return this;},addS:function(s){this.x+=s;this.y+=s;this.z+=s;return this;},subS:function(s){this.x-=s;this.y-=s;this.z-=s;return this;},mulS:function(s){this.x*=s;this.y*=s;this.z*=s;return this;},divS:function(s){this.x/=s;this.y/=s;this.z/=s;return this;},zero:function(){this.x=0;this.y=0;this.z=0;return this;},normalize:function(){var l=this.length();return(l!=0)?this.divS(l):this;},length:function(){return Math.sqrt(this.lengthSquared());},lengthSquared:function(){return this.x*this.x+this.y*this.y+this.z*this.z;},clamp:function(max){var l=this.length();if(l>max){this.divS(l);this.mulS(max);}
return this;},dot:function(v){return this.x*v.x+this.y*v.y+this.z*v.z;},cross:function(v,result){var rx=(this.y*v.z)-(this.z*v.y);var ry=(this.z*v.x)-(this.x*v.z);var rz=(this.x*v.y)-(this.y*v.x);var r=(result==undefined)?new fk.math.Vec3():result;r.set(rx,ry,rz);return r;},distance:function(x,y,z){return Math.sqrt(this.distanceSquared(x,y,z));},distanceV:function(v){return Math.sqrt(this.distanceSquared(v.x,v.y,v.z));},distanceSquared:function(x,y,z){var dx=this.x-x;var dy=this.y-y;var dz=this.z-z;return dx*dx+dy*dy+dz*dz;},equals:function(x,y,z){this.x==x&&this.y==y&&this.z==z;},toString:function(){return"Vec3("+this.x+","+this.y+","+this.z+")";},});fk.math.Vec3.ZERO=new fk.math.Vec3(0,0,0);fk.math.Vec3.UNIT_X=new fk.math.Vec3(1,0,0);fk.math.Vec3.UNIT_Y=new fk.math.Vec3(0,1,0);fk.math.Vec3.UNIT_Z=new fk.math.Vec3(0,0,1);fk.math.Mat4=fk.Class.extend({m00:0,m01:0,m02:0,m03:3,m10:0,m11:0,m12:0,m13:3,m20:0,m21:0,m22:0,m23:3,m30:0,m31:0,m32:0,m33:3,});fk.math.Simplex=function(){var SQRT3=Math.sqrt(3.0)
var SQRT5=Math.sqrt(3.0)
var F2=0.5*(SQRT3-1.0)
var G2=(3.0-SQRT3)/6.0
var G22=(3.0-SQRT3)/6.0
var F3=1.0/3.0
var G3=1.0/6.0
var F4=(SQRT5-1.0)/4.0
var G4=(5.0-SQRT5)/20.0
var G42=G4*2.0
var G43=G4*3.0
var G44=G4*4.0-1.0
var p=[151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]
var perm=new Array(p.length*2)
for(var i=0;i<perm.length;i++)
perm[i]=p[i&0xff]
var grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]]
var grad4=[[0,1,1,1],[0,1,1,-1],[0,1,-1,1],[0,1,-1,-1],[0,-1,1,1],[0,-1,1,-1],[0,-1,-1,1],[0,-1,-1,-1],[1,0,1,1],[1,0,1,-1],[1,0,-1,1],[1,0,-1,-1],[-1,0,1,1],[-1,0,1,-1],[-1,0,-1,1],[-1,0,-1,-1],[1,1,0,1],[1,1,0,-1],[1,-1,0,1],[1,-1,0,-1],[-1,1,0,1],[-1,1,0,-1],[-1,-1,0,1],[-1,-1,0,-1],[1,1,1,0],[1,1,-1,0],[1,-1,1,0],[1,-1,-1,0],[-1,1,1,0],[-1,1,-1,0],[-1,-1,1,0],[-1,-1,-1,0]]
var simplex=[[0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0],[0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0],[1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0],[2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]]
var fastfloor=function(x){return x>0?x:x-1}
var dot2d=function(g,x,y){return g[0]*x+g[1]*y}
var dot3d=function(g,x,y,z){return g[0]*x+g[1]*y+g[2]*z}
var dot4d=function(g,x,y,z,w){return g[0]*x+g[1]*y+g[2]*z+g[3]*w}
this.sample2d=function(x,y){var n0=0,n1=0,n2=0
var s=(x+y)*F2
var i=Math.floor(x+s)
var j=Math.floor(y+s)
var t=(i+j)*G2
var x0=x-(i-t)
var y0=y-(j-t)
var i1,j1
if(x0>y0){i1=1
j1=0}
else{i1=0
j1=1}
var x1=x0-i1+G2
var y1=y0-j1+G2
var x2=x0+G22
var y2=y0+G22
var ii=i&0xff
var jj=j&0xff
var t0=0.5-x0*x0-y0*y0
if(t0>0){t0*=t0
var gi0=perm[ii+perm[jj]]%12
n0=t0*t0*dot2d(grad3[gi0],x0,y0)}
var t1=0.5-x1*x1-y1*y1
if(t1>0){t1*=t1
var gi1=perm[ii+i1+perm[jj+j1]]%12
n1=t1*t1*dot2d(grad3[gi1],x1,y1)}
var t2=0.5-x2*x2-y2*y2
if(t2>0){t2*=t2
var gi2=perm[ii+1+perm[jj+1]]%12
n2=t2*t2*dot2d(grad3[gi2],x2,y2)}
return 70.0*(n0+n1+n2)}
this.sample3d=function(x,y,z){var n0=0,n1=0,n2=0,n3=0
var s=(x+y+z)*F3
var i=fastfloor(x+s)
var j=fastfloor(y+s)
var k=fastfloor(z+s)
var t=(i+j+k)*G3
var x0=x-(i-t)
var y0=y-(j-t)
var z0=z-(k-t)
var i1,j1,k1
var i2,j2,k2
if(x0>=y0){if(y0>=z0){i1=1
j1=0
k1=0
i2=1
j2=1
k2=0}
else if(x0>=z0){i1=1
j1=0
k1=0
i2=1
j2=0
k2=1}
else{i1=0
j1=0
k1=1
i2=1
j2=0
k2=1}}else{if(y0<z0){i1=0
j1=0
k1=1
i2=0
j2=1
k2=1}
else if(x0<z0){i1=0
j1=1
k1=0
i2=0
j2=1
k2=1}
else{i1=0
j1=1
k1=0
i2=1
j2=1
k2=0}}
var x1=x0-i1+G3
var y1=y0-j1+G3
var z1=z0-k1+G3
var x2=x0-i2+F3
var y2=y0-j2+F3
var z2=z0-k2+F3
var x3=x0-0.5
var y3=y0-0.5
var z3=z0-0.5
var ii=i&0xff
var jj=j&0xff
var kk=k&0xff
var t0=0.6-x0*x0-y0*y0-z0*z0
if(t0>0){t0*=t0
var gi0=perm[ii+perm[jj+perm[kk]]]%12
n0=t0*t0*dot3d(grad3[gi0],x0,y0,z0)}
var t1=0.6-x1*x1-y1*y1-z1*z1
if(t1>0){t1*=t1
var gi1=perm[ii+i1+perm[jj+j1+perm[kk+k1]]]%12
n1=t1*t1*dot3d(grad3[gi1],x1,y1,z1)}
var t2=0.6-x2*x2-y2*y2-z2*z2
if(t2>0){t2*=t2
var gi2=perm[ii+i2+perm[jj+j2+perm[kk+k2]]]%12
n2=t2*t2*dot3d(grad3[gi2],x2,y2,z2)}
var t3=0.6-x3*x3-y3*y3-z3*z3
if(t3>0){t3*=t3
var gi3=perm[ii+1+perm[jj+1+perm[kk+1]]]%12
n3=t3*t3*dot3d(grad3[gi3],x3,y3,z3)}
return 32.0*(n0+n1+n2+n3)}
this.sample4d=function(x,y,z,w){var n0=0,n1=0,n2=0,n3=0,n4=0
var s=(x+y+z+w)*F4
var i=fastfloor(x+s)
var j=fastfloor(y+s)
var k=fastfloor(z+s)
var l=fastfloor(w+s)
var t=(i+j+k+l)*G4
var x0=x-(i-t)
var y0=y-(j-t)
var z0=z-(k-t)
var w0=w-(l-t)
var c=0
if(x0>y0){c=0x20}
if(x0>z0){c|=0x10}
if(y0>z0){c|=0x08}
if(x0>w0){c|=0x04}
if(y0>w0){c|=0x02}
if(z0>w0){c|=0x01}
var i1,j1,k1,l1
var i2,j2,k2,l2
var i3,j3,k3,l3
var sc=simplex[c]
i1=sc[0]>=3?1:0
j1=sc[1]>=3?1:0
k1=sc[2]>=3?1:0
l1=sc[3]>=3?1:0
i2=sc[0]>=2?1:0
j2=sc[1]>=2?1:0
k2=sc[2]>=2?1:0
l2=sc[3]>=2?1:0
i3=sc[0]>=1?1:0
j3=sc[1]>=1?1:0
k3=sc[2]>=1?1:0
l3=sc[3]>=1?1:0
var x1=x0-i1+G4
var y1=y0-j1+G4
var z1=z0-k1+G4
var w1=w0-l1+G4
var x2=x0-i2+G42
var y2=y0-j2+G42
var z2=z0-k2+G42
var w2=w0-l2+G42
var x3=x0-i3+G43
var y3=y0-j3+G43
var z3=z0-k3+G43
var w3=w0-l3+G43
var x4=x0+G44
var y4=y0+G44
var z4=z0+G44
var w4=w0+G44
var ii=i&0xff
var jj=j&0xff
var kk=k&0xff
var ll=l&0xff
var t0=0.6-x0*x0-y0*y0-z0*z0-w0*w0
if(t0>0){t0*=t0
var gi0=perm[ii+perm[jj+perm[kk+perm[ll]]]]%32
n0=t0*t0*dot4d(grad4[gi0],x0,y0,z0,w0)}
var t1=0.6-x1*x1-y1*y1-z1*z1-w1*w1
if(t1>0){t1*=t1
var gi1=perm[ii+i1
+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]]%32
n1=t1*t1*dot4d(grad4[gi1],x1,y1,z1,w1)}
var t2=0.6-x2*x2-y2*y2-z2*z2-w2*w2
if(t2>0){t2*=t2
var gi2=perm[ii+i2
+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]]%32
n2=t2*t2*dot4d(grad4[gi2],x2,y2,z2,w2)}
var t3=0.6-x3*x3-y3*y3-z3*z3-w3*w3
if(t3>0){t3*=t3
var gi3=perm[ii+i3
+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]]%32
n3=t3*t3*dot4d(grad4[gi3],x3,y3,z3,w3)}
var t4=0.6-x4*x4-y4*y4-z4*z4-w4*w4
if(t4>0){t4*=t4
var gi4=perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]]%32
n4=t4*t4*dot4d(grad4[gi4],x4,y4,z4,w4)}
return 27.0*(n0+n1+n2+n3+n4)}}
fk.math.noise=function(){if(!this.simplex)this.simplex=new fk.math.Simplex()
var n=this.simplex
if(arguments.length==2)
return n.sample2d(arguments[0],arguments[1])
else if(arguments.length==3)
return n.sample3d(arguments[0],arguments[1],arguments[2])
else if(arguments.length==4)
return n.sample4d(arguments[0],arguments[1],arguments[2],arguments[3])}
fk.particle.System=fk.Class.extend({init:function(updateTicks,logicTicks){this.updateTicks=updateTicks;this.logicTicks=logicTicks;this.flocks=new Array();this.friction=0.97;this.width=640;this.height=480;this.depth=480;this.timerSim=new Date();this.timerLogic=new Date();},update:function(){var now=new Date();var dtSim=now-this.timerSim;this.timerSim=now;var dtLogic=now-this.timerLogic;if(dtLogic>1000/this.logicTicks){this.timerLogic=now;for(var i=0;i<this.flocks.length;i++)
this.flocks[i].updateLogic(dtLogic);}
for(var i=0;i<this.flocks.length;i++)
this.flocks[i].updateSimulation(dtSim);},add:function(flock){flock.ps=this;this.flocks.push(flock);},toAbsolute:function(normalized,result){result.setV(normalized).mul(this.width,this.height,this.depth);return result;}});fk.particle.Flock=fk.Class.extend({init:function(){this.particles=new Array();this.behaviours=new Array();this.emitter=new fk.particle.Emitter(this);},updateLogic:function(dt){this.emitter.updateLogic(dt);for(var i=0;i<this.behaviours.length;i++)
this.behaviours[i].prepare(dt);for(var i=0;i<this.particles.length;i++){var p=this.particles[i];for(var j=0;j<this.behaviours.length;j++)
this.behaviours[j].apply(p,dt);p.updateLogic(dt);}},updateSimulation:function(dt){for(var i=0;i<this.particles.length;i++)
this.particles[i].updateSimulation(dt);},add:function(behaviour){this.behaviours.push(behaviour);},toString:function(){return'Flock';},});fk.particle.Emitter=fk.Class.extend({init:function(flock){this.flock=flock
this.position=new fk.math.Vec2();this.behaviours=new Array();this.rate=1;this.interval=1000.0;this.particleMax=100;this.time=0;},updateLogic:function(dt){this.time+=dt;if(this.time>=this.interval){this.time=0;if(this.emissionCount()>0){for(var i=0;i<this.behaviours.length;i++)
this.behaviours[i].prepare(dt);for(var i=0;i<this.rate;i++)
if(this.emissionCount()>0)
this.emit();}}},emissionCount:function(){return this.particleMax-this.flock.particles.length;},emit:function(){var p=this.createParticle();p.position.setV(this.position);for(var i=0;i<this.behaviours.length;i++)
this.behaviours[i].apply(p,0);this.flock.particles.push(p);},createParticle:function(){return new fk.particle.Particle(this.flock);},add:function(behaviour){this.behaviours.push(behaviour)},});fk.particle.Particle=fk.Class.extend({init:function(flock){this.flock=flock;this.position=new fk.math.Vec2();this.velocity=new fk.math.Vec2();this.steer=new fk.math.Vec2();this.age=0;this.steerMax=1.0;this.velocityMax=10;this.rotation=0;this.turningSpeed=0.1;this.size=10;this.theta=0;this.absVelocity=new fk.math.Vec2();this.reset();},reset:function(){this.velocity.zero();this.steer.zero();this.age=0;this.rotation=0;this.size=10;this.theta=0;this.absVelocity.zero();},updateLogic:function(dt){this.age+=dt;this.steer.clamp(this.steerMax);this.velocity.addV(this.steer).clamp(this.velocityMax);this.steer.zero();this.theta=-Math.atan2(this.velocity.x,this.velocity.y);},updateSimulation:function(dt){this.absVelocity.setV(this.velocity).mulS(dt/this.flock.ps.updateTicks);this.position.addV(this.absVelocity);this.velocity.mulS(this.flock.ps.friction);this.rotation=fk.math.slerpAngle(this.rotation,this.theta,this.turningSpeed);},});fk.particle.Behaviour=fk.Class.extend({prepare:function(dt){},apply:function(particle,dt){}});fk.particle.RandomEmit=fk.particle.Behaviour.extend({ps:null,min:null,max:null,init:function(ps){this.ps=ps;this.min=new fk.math.Vec2(0,0);this.max=new fk.math.Vec2(1,1);this.minAbs=new fk.math.Vec2();this.rangeAbs=new fk.math.Vec2();},prepare:function(dt){this.minAbs.setV(this.min).mul(this.ps.width,this.ps.height,this.ps.depth)
this.rangeAbs.setV(this.max).subV(this.min).mul(this.ps.width,this.ps.height,this.ps.depth)},apply:function(p,dt){p.position.setV(this.rangeAbs).mul(Math.random(),Math.random(),Math.random()).addV(this.minAbs)},});fk.particle.Gravity=fk.particle.Behaviour.extend({force:null,init:function(){this.force=new fk.math.Vec2(0,0.01);},apply:function(p,dt){p.steer.addV(this.force);},});fk.particle.RandomSteer=fk.particle.Behaviour.extend({apply:function(p,dt){p.steer.x+=(Math.random()*2.0-1.0)*0.2;p.steer.y+=(Math.random()*2.0-1.0)*0.2;}});fk.particle.Wrap=fk.particle.Behaviour.extend({min:new fk.math.Vec2(),max:new fk.math.Vec2(),init:function(ps){this.ps=ps;},prepare:function(dt){this.min.set(0,0);this.max.set(this.ps.width,this.ps.height);},apply:function(p,dt){var pos=p.position;if(pos.x<this.min.x)pos.x=this.max.x;if(pos.y<this.min.y)pos.y=this.max.y;if(pos.x>this.max.x)pos.x=this.min.x;if(pos.y>this.max.y)pos.y=this.min.y;}});fk.particle3d.Flock=fk.particle.Flock.extend({init:function(){this._super();this.emitter=new fk.particle3d.Emitter(this);},toString:function(){return'Flock3D';},});fk.particle3d.Emitter=fk.particle.Emitter.extend({init:function(flock){this._super(flock);this.position=new fk.math.Vec3();},})
fk.particle3d.Particle=fk.particle.Particle.extend({init:function(flock){this._super(flock);this.position=new fk.math.Vec3();this.velocity=new fk.math.Vec3();this.steer=new fk.math.Vec3();this.absVelocity=new fk.math.Vec3();},});fk.particle3d.RandomEmit=fk.particle.Behaviour.extend({ps:null,min:null,max:null,init:function(ps){this.ps=ps;this.min=new fk.math.Vec3(0,0,0);this.max=new fk.math.Vec3(1,1,1);this.minAbs=new fk.math.Vec3();this.range=new fk.math.Vec3();this.rangeAbs=new fk.math.Vec3();},prepare:function(dt){this.ps.toAbsolute(this.min,this.minAbs);this.range.setV(this.max).subV(this.min);this.ps.toAbsolute(this.range,this.rangeAbs);},apply:function(p,dt){p.position.setV(this.rangeAbs).mul(Math.random(),Math.random(),Math.random()).addV(this.minAbs)},});fk.particle3d.Gravity=fk.particle.Behaviour.extend({force:null,init:function(){this.force=new fk.math.Vec3(0,0.01,0);},apply:function(p,dt){p.steer.addV(this.force);},});fk.particle3d.Wrap=fk.particle.Behaviour.extend({min:new fk.math.Vec3(),max:new fk.math.Vec3(),init:function(ps){this.ps=ps;this.minAbs=new fk.math.Vec3();this.maxAbs=new fk.math.Vec3();},prepare:function(dt){this.ps.toAbsolute(this.min,this.minAbs);this.ps.toAbsolute(this.max,this.maxAbs);},apply:function(p,dt){var pos=p.position;var min=this.minAbs;var max=this.maxAbs;if(pos.x<min.x)pos.x=max.x;if(pos.x>max.x)pos.x=min.x;if(pos.y<min.y)pos.y=max.y;if(pos.y>max.y)pos.y=min.y;if(pos.z<min.z)pos.z=max.z;if(pos.z>max.z)pos.z=min.z;}});skeie={}
skeie.colour=function(hex){var c=new fk.Colour();c.fromHex(hex);return new Pre3d.RGBA(c.r/255,c.g/255,c.b/255,1)};skeie.colourBG=new fk.Colour('e6ebf1');skeie.colourA=new fk.Colour('ffffff');skeie.colourB=new fk.Colour('d0dae6');skeie.colourBGpre=skeie.colour('e6ebf1');skeie.colourApre=skeie.colour('ffffff');skeie.colourBpre=skeie.colour('d0dae6');skeie.Particle=fk.particle3d.Particle.extend({colour:null,colourTarget:null,colourSlerp:0.1,isActive:true,init:function(flock){this._super(flock);this.colour=skeie.colourBG.clone();this.colourTarget=new fk.Colour();},updateLogic:function(dt){if(!this.isActive)return;this.age+=dt;this.steer.clamp(this.steerMax);this.velocity.addV(this.steer).clamp(this.velocityMax);this.steer.zero();},updateSimulation:function(dt){if(!this.isActive)return;this.absVelocity.setV(this.velocity).mulS(dt/this.flock.ps.updateTicks);this.position.addV(this.absVelocity);this.velocity.mulS(this.flock.ps.friction);this.colour.slerp(this.colourTarget,this.colourSlerp);var c=this.mesh.colour;c.r=this.colour.r/255;c.g=this.colour.g/255;c.b=this.colour.b/255;var t=this.mesh.transform
t.reset()
t.rotateZ(this.rotation.z)
t.rotateY(this.rotation.y)
t.rotateX(this.rotation.x)
t.translate(this.position.x,this.position.y,this.position.z);},})
skeie.Mesh=fk.Class.extend({geometry:null,transform:null,colour:null,init:function(){this.geometry=(arguments.length==1)?arguments[0]:null;this.transform=new Pre3d.Transform();this.colour=new Pre3d.RGBA(1,1,1,1);this.scale=new Pre3d.Transform();}})
skeie.LMesh=skeie.Mesh.extend({init:function(scale,offsetX,offsetY,offsetZ){this._super();if(typeof(scale)=='undefined')scale=1;if(offsetX===undefined)offsetX=0;if(offsetY===undefined)offsetY=0;if(offsetZ===undefined)offsetZ=0;var w=1*scale;var h=4*scale;var d=1*scale;var e=2*scale;var ox=offsetX*scale;var oy=offsetY*scale;var oz=offsetZ*scale;var s=new Pre3d.Shape();s.vertices=[{x:w,y:h,z:-d},{x:w,y:h,z:d},{x:w,y:-h,z:d},{x:w,y:-h,z:-d},{x:-w,y:h,z:-d},{x:-w,y:h,z:d},{x:-w,y:-h,z:d},{x:-w,y:-h,z:-d},{x:w,y:-h+e,z:d},{x:w,y:-h+e,z:-d},{x:w+e,y:-h+e,z:d},{x:w+e,y:-h+e,z:-d},{x:w+e,y:-h,z:d},{x:w+e,y:-h,z:-d},];for(var i=0;i<s.vertices.length;i++){s.vertices[i].x+=ox;s.vertices[i].y+=oy;s.vertices[i].z+=oz;}
s.quads=[new Pre3d.QuadFace(0,1,8,9),new Pre3d.QuadFace(1,5,6,2),new Pre3d.QuadFace(5,4,7,6),new Pre3d.QuadFace(4,0,3,7),new Pre3d.QuadFace(0,4,5,1),new Pre3d.QuadFace(11,10,12,13),new Pre3d.QuadFace(10,8,2,12),new Pre3d.QuadFace(9,11,13,3),new Pre3d.QuadFace(11,9,8,10),new Pre3d.QuadFace(12,6,7,13),];Pre3d.ShapeUtils.rebuildMeta(s);this.geometry=s;}});skeie.play=function(id){var animations=[skeie.Dance,skeie.Growth,skeie.Tower,skeie.Wheel];var clazz=(id<animations.length)?animations[id]:animations[0];var inst=new clazz();inst.start();};skeie.Animation=fk.Class.extend({width:640,height:480,framerate:30,renderer:null,camera:null,init:function(){this.width=document.documentElement.clientWidth;this.height=document.documentElement.clientHeight;var stage=document.getElementById('stage');var canvas=document.createElement("canvas");canvas.width=this.width;canvas.height=this.height;stage.appendChild(canvas);this.renderer=new Pre3d.Renderer(canvas);this.camera=this.renderer.camera;this.camera.focal_length=143*fk.math.DEG_TO_RAD;this.cameraZ=this.height*this.camera.focal_length*-0.5;var ct=this.camera.transform;ct.reset();ct.translate(0,0,this.cameraZ);this.setup();},setup:function(){},start:function(){var test=this
this.interval=setInterval(function(){test.draw()},1000/this.framerate);},stop:function(){clearInterval(this.interval);},draw:function(){},});skeie.Dance=skeie.Animation.extend({scene:null,rot:null,rotVel:null,setup:function(){this.renderer.draw_backfaces=false;this.renderer.lights_enabled=false;this.scene=[]
var l1=new skeie.LMesh();l1.transform.rotateZ(fk.math.PI/2);l1.transform.translate(0,-3,0);l1.colour=skeie.colourApre;this.scene.push(l1)
var l2=new skeie.LMesh();l2.transform.rotateZ(-fk.math.PI/2);l2.transform.translate(0,3,0);l2.colour=skeie.colourBpre;this.scene.push(l2);this.rot=new fk.math.Vec3();this.rot.x=fk.math.random(-fk.math.PI,fk.math.PI);this.rot.y=fk.math.random(-fk.math.PI,fk.math.PI);this.rotVel=new fk.math.Vec3();this.rotVel.x=fk.math.random(-0.0025,0.0025);this.rotVel.y=fk.math.random(-0.001,0.01);this.rot2Vel=new fk.math.Vec3();this.rot2Vel.x=fk.math.random(-0.0005,0.0015);this.rot2Vel.y=fk.math.random(-0.0015,0.005);this.time=0},draw:function(){this.time+=0.001;this.camera.focal_length=Math.sin(this.time)/fk.math.PI*6+3;this.rot.addV(this.rotVel);var ct=this.camera.transform;ct.reset();ct.rotateX(this.rot.x);ct.rotateY(this.rot.y);ct.rotateZ(0);ct.translate(0,0,-10);var l1=this.scene[0];l1.transform.rotateX(-this.rot2Vel.x);l1.transform.rotateY(this.rot2Vel.y);var r=this.renderer;for(var i=0;i<this.scene.length;i++){var m=this.scene[i];r.fill_rgba=m.colour;r.transform=m.transform;r.bufferShape(m.geometry);}
r.clearBackground();r.drawBuffer();r.emptyBuffer();},})
skeie.Growth=skeie.Animation.extend({setup:function(){this.renderer.lights_enabled=false;this.renderer.draw_backfaces=false;this.renderer.perform_z_sorting=false;fk.info("setup "+this.width+"x"+this.height)
this.camera.focal_length=120*fk.math.DEG_TO_RAD;var LMeshParticle=skeie.Particle.extend({isActive:true,init:function(flock,flip){this._super(flock);this.size=fk.math.random(40,640);this.width=this.size;this.height=this.width/4;this.depth=this.height*2;var normal=(fk.math.flipCoin())?-1:1
this.mesh=new skeie.LMesh(this.size*0.1,0,0)
this.rotation=new fk.math.Vec3()
this.rotation.z=fk.math.PI/2*normal;this.rotation.x=0
this.rotation.y=0
this.colour.set(skeie.colourBG)
if(fk.math.flipCoin()){this.colourTarget.set(skeie.colourA)}else{this.colourTarget.set(skeie.colourB)}},updateSimulation:function(dt){this.absVelocity.setV(this.velocity).mulS(dt/this.flock.ps.updateTicks);this.position.addV(this.absVelocity);this.velocity.mulS(this.flock.ps.friction);this.colour.slerp(this.colourTarget,this.colourSlerp);var c=this.mesh.colour;c.r=this.colour.r/255;c.g=this.colour.g/255;c.b=this.colour.b/255;var t=this.mesh.transform
t.reset()
t.rotateZ(this.rotation.z)
t.rotateY(this.rotation.y)
t.rotateX(this.rotation.x)
t.translate(this.position.x-this.flock.ps.width/2,(this.position.y-this.flock.ps.height/2)*-1,-this.position.z)},collide:function(){this.steer.zero();this.velocity.zero();this.isActive=false;}});var LMeshEmitter=fk.particle3d.Emitter.extend({init:function(flock){this._super(flock);},createParticle:function(){return new LMeshParticle(this.flock)}});var ParticleInitialiser=fk.particle.Behaviour.extend({apply:function(p,dt){p.steerMax=1;p.velocityMax=10;},})
var ps=new fk.particle.System(30,30)
this.ps=ps
ps.width=this.width
ps.height=this.height
ps.depth=this.height
var flock=new fk.particle3d.Flock()
ps.add(flock)
flock.emitter=new LMeshEmitter(flock)
flock.emitter.interval=1000
flock.emitter.time=flock.emitter.interval
flock.emitter.particleMax=15
flock.emitter.add(new ParticleInitialiser())
var randomEmit=new(fk.particle3d.RandomEmit.extend({init:function(){this._super(ps);this.tmp=new fk.math.Vec3()},randomPoint:function(){this.tmp.setV(this.rangeAbs).mul(Math.random(),Math.random(),Math.random()).addV(this.minAbs);return this.tmp;},apply:function(p,dt){var intersects=false;p.position.setV(this.randomPoint());var attempts=0
do{intersects=false
var particles=p.flock.particles
for(var i=0;i<particles.length;i++){var n=particles[i]
if(p==n)
continue;if(n.position.x+n.width>p.position.x&&n.position.y+n.height>p.position.y&&n.position.x<p.position.x+p.width&&n.position.y<p.position.y+p.height){intersects=true}}
if(intersects){p.position.setV(this.randomPoint());attempts++;}}while(intersects&&attempts<10)
if(attempts==10)
p.position.x=10000},}));randomEmit.min.x=-0.5
randomEmit.max.x=-0.15
flock.emitter.add(randomEmit);var wave=new(fk.particle.Behaviour.extend({time:0,freq:0.005,speed:0.0002,amplitude:2.0,prepare:function(dt){this.time+=dt;},apply:function(p,dt){var alpha=Math.sin(p.position.x*this.freq+this.time*this.speed);p.steer.z=alpha*this.amplitude;p.rotation.y=Math.atan(alpha);}}));flock.add(wave);var wind=new(fk.particle.Behaviour.extend({apply:function(p,dt){p.steer.add(0.45,0,0);}}));flock.add(wind);var Cleaner=fk.particle.Behaviour.extend({apply:function(p,dt){if(p.position.x>=ps.width*2){var i=p.flock.particles.indexOf(p);p.flock.particles.splice(i,1);}}})
flock.add(new Cleaner());},draw:function(){this.ps.update();var r=this.renderer;var l=this.ps.flocks[0].particles;for(var i=0;i<l.length;i++){var p=l[i];var m=p.mesh;if(p.position.z>=this.cameraZ+250){r.fill_rgba=m.colour;r.transform=m.transform;r.bufferShape(m.geometry);}}
r.clearBackground();r.drawBuffer();r.emptyBuffer();},})
skeie.Tower=skeie.Animation.extend({cameraRotY:0,setup:function(){this.renderer.draw_backfaces=false;this.renderer.perform_z_sorting=true;this.renderer.lights_enabled=false;fk.info("setup "+this.width+"x"+this.height)
var parent=this
var LMeshParticle=skeie.Particle.extend({init:function(flock,flip,rotation,colour){this._super(flock);this.size=640;this.width=this.size;this.height=this.width/4;this.depth=this.height*2
this.flip=flip
var normal=(flip)?-1:1
this.mesh=new skeie.LMesh(this.size*0.115,-3.5,0)
this.rotation=new fk.math.Vec3()
this.rotation.z=fk.math.PI/2*normal+rotation;this.rotation.x=fk.math.PI/2
this.rotation.y=fk.math.PI
this.colour.set(skeie.colourBG)
this.colourTarget.set(colour)},updateLogic:function(dt){this.age+=dt;this.steer.clamp(this.steerMax);this.velocity.addV(this.steer).clamp(this.velocityMax);this.steer.zero();},updateSimulation:function(dt){this.absVelocity.setV(this.velocity).mulS(dt/this.flock.ps.updateTicks);this.position.addV(this.absVelocity);this.velocity.mulS(this.flock.ps.friction);this.colour.slerp(this.colourTarget,this.colourSlerp);var c=this.mesh.colour;c.r=this.colour.r/255;c.g=this.colour.g/255;c.b=this.colour.b/255;var t=this.mesh.transform
t.reset()
t.rotateZ(this.rotation.z+parent.cameraRotY)
t.rotateY(this.rotation.y)
t.rotateX(this.rotation.x)
t.translate(this.position.x-this.flock.ps.width/2,(this.position.y-this.flock.ps.height/2)*-1,-this.position.z)},collide:function(){this.steer.zero();this.velocity.zero();this.isActive=false;}});var LMeshEmitter=fk.particle3d.Emitter.extend({init:function(flock){this._super(flock);this.pair=0;this.rotation=0;},createParticle:function(){this.pair++;var flip=true;var colour=null;if(this.pair==1){flip=false;this.randomiseRotation();colour=skeie.colourA;}else if(this.pair==2){colour=skeie.colourB;}else if(this.pair==3){flip=false;this.randomiseRotation();colour=skeie.colourB;}else if(this.pair==4){this.pair=0;colour=skeie.colourA;}
return new LMeshParticle(this.flock,flip,this.rotation,colour)},randomiseColour:function(){var delta=fk.math.random(0,1);this.colour.set(skeie.colourA).interpolate(skeie.colourB,delta);},randomiseRotation:function(){var alpha=fk.math.DEG_TO_RAD*93
this.rotation=fk.math.random(-alpha,alpha)}});var LFlock=fk.particle3d.Flock.extend({updateLogic:function(dt){this.emitter.updateLogic(dt);for(var i=0;i<this.behaviours.length;i++)
this.behaviours[i].prepare(dt);for(var i=0;i<this.particles.length;i++){var p=this.particles[i];if(!p.isActive)continue;for(var j=0;j<this.behaviours.length;j++)
this.behaviours[j].apply(p,dt);p.updateLogic(dt);}},})
var ParticleInitialiser=fk.particle.Behaviour.extend({apply:function(p,dt){p.steerMax=10;p.velocityMax=100;},})
var RandomEmit=fk.particle.Behaviour.extend({ps:null,min:null,max:null,init:function(ps){this.ps=ps;this.min=new fk.math.Vec3(0,0,0);this.max=new fk.math.Vec3(1,1,1);this.minAbs=new fk.math.Vec3();this.rangeAbs=new fk.math.Vec3();},prepare:function(dt){this.minAbs.setV(this.min).mul(this.ps.width,this.ps.height,this.ps.depth);this.rangeAbs.setV(this.max).subV(this.min).mul(this.ps.width,this.ps.height,this.ps.depth);},apply:function(p,dt){p.position.setV(this.rangeAbs).mul(Math.random(),Math.random(),Math.random()).addV(this.minAbs);},});var ps=new fk.particle.System(30,30);this.ps=ps;ps.width=this.width;ps.height=this.height;ps.depth=this.height;var flock=new LFlock();ps.add(flock);flock.emitter=new LMeshEmitter(flock);flock.emitter.interval=1500;flock.emitter.time=flock.emitter.interval;flock.emitter.particleMax=16;flock.emitter.add(new ParticleInitialiser())
var re=new RandomEmit(ps)
re.min.x=0.5;re.min.y=-2;re.min.z=0.5
re.max.x=0.5;re.max.y=re.min.y;re.max.z=0.5
flock.emitter.add(re);var gravity=new fk.particle3d.Gravity();gravity.force.y=0.65
flock.add(gravity);var Bounce=fk.particle.Behaviour.extend({apply:function(p,dt){var pos=p.position;var steer=p.steer;if(pos.y>ps.height-p.height&&steer.y>0){p.collide();}}});flock.add(new Bounce());var Repel=fk.particle.Behaviour.extend({apply:function(p,dt){var particles=p.flock.particles
var tmp=0
for(var i=0;i<particles.length;i++){var n=particles[i]
if(p==n)continue;if(p.flip!=n.flip)continue;if(n.position.x+n.width>p.position.x&&n.position.x<p.position.x+p.width&&n.position.y+n.height>p.position.y&&n.position.y<p.position.y+p.height&&n.position.z+n.depth>p.position.z&&n.position.z<p.position.z+p.depth){p.collide();}}}});flock.add(new Repel());this.camera.fmin=140*fk.math.DEG_TO_RAD;this.camera.fmax=220*fk.math.DEG_TO_RAD;var ct=this.camera.transform;ct.reset();ct.rotateZ(-5*fk.math.DEG_TO_RAD);ct.rotateX(-45*fk.math.DEG_TO_RAD);ct.translate(0,0,this.cameraZ);this.time=0;},draw:function(){this.ps.update();this.time+=0.01;var delta=(Math.sin(this.time)+1)/2;var min=this.camera.fmin;var max=this.camera.fmax;var range=max-min;this.camera.focal_length=delta*range+min;this.cameraRotY+=0.004;var r=this.renderer;var l=this.ps.flocks[0].particles;for(var i=0;i<l.length;i++){var p=l[i];var m=p.mesh;r.fill_rgba=m.colour;r.transform=m.transform;r.bufferShape(m.geometry);}
r.clearBackground();r.drawBuffer();r.emptyBuffer();},});skeie.Wheel=skeie.Animation.extend({setup:function(){function fk2preColour(c){return new Pre3D.RGBA(c.r/255,c.g/255,c.b/255,255)}
var Wheel=fk.Class.extend({position:null,rotation:null,elements:null,colour:null,spin:0.05,init:function(radius,count,size,colour){this.colour=colour;this.position=new fk.math.Vec3();this.rotation=new fk.math.Vec3();this.elements=new Array();this.initElements(radius,count,size);},initElements:function(radius,count,size){var alpha=fk.math.TWO_PI/count;for(var i=0;i<count;i++){var m=new skeie.LMesh(size,radius/(2*size),0);m.transform.rotateZ(i*alpha);this.elements.push(m);}},update:function(){for(var i=0;i<this.elements.length;i++){var m=this.elements[i];m.transform.rotateZ(this.spin);}}})
this.renderer.draw_backfaces=false;this.renderer.perform_z_sorting=true;this.renderer.lights_enabled=false;this.scene=new Array()
var Vec3=fk.math.Vec3
var ca=skeie.colourApre
var cb=skeie.colourBpre
var spin=0.02
var ref=Math.min(this.width,this.height)
var size=ref/48
var radius=ref/1.5
var r1=radius/2
var o13=r1*0.9
var o14=r1/2.5
var w1=new Wheel(r1,5,size,ca)
w1.position=new Vec3(r1+o13,o14,0)
w1.spin=spin*2
this.scene.push(w1)
var w2=new Wheel(radius,10,size,cb)
w2.spin=-spin
this.scene.push(w2)
this.camera.focal_length=130*fk.math.DEG_TO_RAD
this.rotation=new Vec3()
this.rotVel=new Vec3()
this.rotVel.x=fk.math.random(-0.001,0.001)
this.rotVel.y=fk.math.random(-0.02,0.02)
this.rotVel.x=fk.math.random(-0.01,0.01)},draw:function(){this.rotation.addV(this.rotVel)
var ct=this.camera.transform;ct.reset()
ct.rotateX(this.rotation.x);ct.rotateY(this.rotation.y);ct.rotateZ(this.rotation.z);ct.translate(0,0,this.cameraZ*0.75);var s=this.scene;var r=this.renderer;for(var i=0;i<s.length;i++)
s[i].update();for(var i=0;i<s.length;i++){var obj=s[i]
var elements=obj.elements;for(var j=0;j<elements.length;j++){var mesh=elements[j]
var tx=mesh.transform.dup();tx.rotateX(obj.rotation.x);tx.rotateY(obj.rotation.y);tx.rotateZ(obj.rotation.z);tx.translate(obj.position.x,obj.position.y,obj.position.z);r.transform=tx;r.fill_rgba=obj.colour;r.bufferShape(mesh.geometry);}}
r.clearBackground();r.drawBuffer();r.emptyBuffer();},})
