Browse Source

Added path.createSpacedPointsGeometry() and extended shapes example to show such equidistantly sampled paths.

Spaced points are magic that will eventually make objects follow paths with constant speed.
alteredq 14 years ago
parent
commit
fc6b13d9ba
4 changed files with 97 additions and 41 deletions
  1. 3 2
      build/Three.js
  2. 15 14
      build/custom/ThreeExtras.js
  3. 50 15
      examples/webgl_geometry_shapes.html
  4. 29 10
      src/extras/geometries/Path.js

+ 3 - 2
build/Three.js

@@ -437,12 +437,13 @@ THREE.Path.prototype.lineTo=function(b,c){var e=Array.prototype.slice.call(argum
 THREE.Path.prototype.quadraticCurveTo=function(b,c,e,f){var g=Array.prototype.slice.call(arguments),j=this.actions[this.actions.length-1].args,j=new THREE.QuadraticBezierCurve(j[j.length-2],j[j.length-1],b,c,e,f);this.curves.push(j);this.actions.push({action:THREE.PathActions.QUADRATIC_CURVE_TO,args:g,curve:j})};
 THREE.Path.prototype.quadraticCurveTo=function(b,c,e,f){var g=Array.prototype.slice.call(arguments),j=this.actions[this.actions.length-1].args,j=new THREE.QuadraticBezierCurve(j[j.length-2],j[j.length-1],b,c,e,f);this.curves.push(j);this.actions.push({action:THREE.PathActions.QUADRATIC_CURVE_TO,args:g,curve:j})};
 THREE.Path.prototype.bezierCurveTo=function(b,c,e,f,g,j){var h=Array.prototype.slice.call(arguments),m=this.actions[this.actions.length-1].args,m=new THREE.CubicBezierCurve(m[m.length-2],m[m.length-1],b,c,e,f,g,j);this.curves.push(m);this.actions.push({action:THREE.PathActions.BEZIER_CURVE_TO,args:h,curve:m})};
 THREE.Path.prototype.bezierCurveTo=function(b,c,e,f,g,j){var h=Array.prototype.slice.call(arguments),m=this.actions[this.actions.length-1].args,m=new THREE.CubicBezierCurve(m[m.length-2],m[m.length-1],b,c,e,f,g,j);this.curves.push(m);this.actions.push({action:THREE.PathActions.BEZIER_CURVE_TO,args:h,curve:m})};
 THREE.Path.prototype.splineThru=function(b){var c=Array.prototype.slice.call(arguments),e=this.actions[this.actions.length-1].args,e=[new THREE.Vector2(e[e.length-2],e[e.length-1])],e=e.concat(b),e=new THREE.SplineCurve(e);this.curves.push(e);this.actions.push({action:THREE.PathActions.CSPLINE_THRU,args:c,curve:e})};
 THREE.Path.prototype.splineThru=function(b){var c=Array.prototype.slice.call(arguments),e=this.actions[this.actions.length-1].args,e=[new THREE.Vector2(e[e.length-2],e[e.length-1])],e=e.concat(b),e=new THREE.SplineCurve(e);this.curves.push(e);this.actions.push({action:THREE.PathActions.CSPLINE_THRU,args:c,curve:e})};
-THREE.Path.prototype.arc=function(b,c,e,f,g,j){var h=Array.prototype.slice.call(arguments);this.curves.push(new THREE.ArcCurve(b,c,e,f,g,j));this.actions.push({action:THREE.PathActions.ARC,args:h})};THREE.Path.prototype.getSpacedPoints=function(b){b||(b=40);for(var c=[],e=0;e<b;e++)c.push(this.getPoint(e/b));return c};
+THREE.Path.prototype.arc=function(b,c,e,f,g,j){var h=Array.prototype.slice.call(arguments);this.curves.push(new THREE.ArcCurve(b,c,e,f,g,j));this.actions.push({action:THREE.PathActions.ARC,args:h})};THREE.Path.prototype.getSpacedPoints=function(b,c){b||(b=40);for(var e=[],f=0;f<b;f++)e.push(this.getPoint(f/b));c&&e.push(e[0]);return e};
 THREE.Path.prototype.getPoints=function(b,c){var b=b||12,e=[],f,g,j,h,m,n,p,o,t,u,v,x,w;f=0;for(g=this.actions.length;f<g;f++)switch(j=this.actions[f],h=j.action,j=j.args,h){case THREE.PathActions.LINE_TO:e.push(new THREE.Vector2(j[0],j[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:m=j[2];n=j[3];t=j[0];u=j[1];e.length>0?(h=e[e.length-1],v=h.x,x=h.y):(h=this.actions[f-1].args,v=h[h.length-2],x=h[h.length-1]);for(h=1;h<=b;h++)w=h/b,j=THREE.FontUtils.b2(w,v,t,m),w=THREE.FontUtils.b2(w,x,u,n),
 THREE.Path.prototype.getPoints=function(b,c){var b=b||12,e=[],f,g,j,h,m,n,p,o,t,u,v,x,w;f=0;for(g=this.actions.length;f<g;f++)switch(j=this.actions[f],h=j.action,j=j.args,h){case THREE.PathActions.LINE_TO:e.push(new THREE.Vector2(j[0],j[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:m=j[2];n=j[3];t=j[0];u=j[1];e.length>0?(h=e[e.length-1],v=h.x,x=h.y):(h=this.actions[f-1].args,v=h[h.length-2],x=h[h.length-1]);for(h=1;h<=b;h++)w=h/b,j=THREE.FontUtils.b2(w,v,t,m),w=THREE.FontUtils.b2(w,x,u,n),
 e.push(new THREE.Vector2(j,w));break;case THREE.PathActions.BEZIER_CURVE_TO:m=j[4];n=j[5];t=j[0];u=j[1];p=j[2];o=j[3];e.length>0?(h=e[e.length-1],v=h.x,x=h.y):(h=this.actions[f-1].args,v=h[h.length-2],x=h[h.length-1]);for(h=1;h<=b;h++)w=h/b,j=THREE.FontUtils.b3(w,v,t,p,m),w=THREE.FontUtils.b3(w,x,u,o,n),e.push(new THREE.Vector2(j,w));break;case THREE.PathActions.CSPLINE_THRU:h=this.actions[f-1].args;h=[new THREE.Vector2(h[h.length-2],h[h.length-1])];w=b*j[0].length;h=h.concat(j[0]);j=new THREE.SplineCurve(h);
 e.push(new THREE.Vector2(j,w));break;case THREE.PathActions.BEZIER_CURVE_TO:m=j[4];n=j[5];t=j[0];u=j[1];p=j[2];o=j[3];e.length>0?(h=e[e.length-1],v=h.x,x=h.y):(h=this.actions[f-1].args,v=h[h.length-2],x=h[h.length-1]);for(h=1;h<=b;h++)w=h/b,j=THREE.FontUtils.b3(w,v,t,p,m),w=THREE.FontUtils.b3(w,x,u,o,n),e.push(new THREE.Vector2(j,w));break;case THREE.PathActions.CSPLINE_THRU:h=this.actions[f-1].args;h=[new THREE.Vector2(h[h.length-2],h[h.length-1])];w=b*j[0].length;h=h.concat(j[0]);j=new THREE.SplineCurve(h);
 for(h=1;h<=w;h++)e.push(j.getPointAt(h/w));break;case THREE.PathActions.ARC:h=this.actions[f-1].args;m=j[0];n=j[1];p=j[2];t=j[3];w=j[4];u=!!j[5];o=h[h.length-2];v=h[h.length-1];h.length==0&&(o=v=0);x=w-t;var B=b*2;for(h=1;h<=B;h++)w=h/B,u||(w=1-w),w=t+w*x,j=o+m+p*Math.cos(w),w=v+n+p*Math.sin(w),e.push(new THREE.Vector2(j,w))}c&&e.push(e[0]);return e};
 for(h=1;h<=w;h++)e.push(j.getPointAt(h/w));break;case THREE.PathActions.ARC:h=this.actions[f-1].args;m=j[0];n=j[1];p=j[2];t=j[3];w=j[4];u=!!j[5];o=h[h.length-2];v=h[h.length-1];h.length==0&&(o=v=0);x=w-t;var B=b*2;for(h=1;h<=B;h++)w=h/B,u||(w=1-w),w=t+w*x,j=o+m+p*Math.cos(w),w=v+n+p*Math.sin(w),e.push(new THREE.Vector2(j,w))}c&&e.push(e[0]);return e};
 THREE.Path.prototype.getMinAndMax=function(){var b=this.getPoints(),c,e,f,g;c=e=Number.NEGATIVE_INFINITY;f=g=Number.POSITIVE_INFINITY;var j,h,m;h=0;for(m=b.length;h<m;h++){j=b[h];if(j.x>c)c=j.x;else if(j.x<f)f=j.x;if(j.y>e)e=j.y;else if(j.y<e)g=j.y}return{minX:f,minY:g,maxX:c,maxY:e}};THREE.Path.prototype.getPoint=function(b){for(var c=b*this.getLength(),e=this.sums,b=0;b<e.length;){if(e[b]>=c)return c=e[b]-c,b=this.curves[b],c=1-c/b.getLength(),b.getPointAt(c);b++}return null};
 THREE.Path.prototype.getMinAndMax=function(){var b=this.getPoints(),c,e,f,g;c=e=Number.NEGATIVE_INFINITY;f=g=Number.POSITIVE_INFINITY;var j,h,m;h=0;for(m=b.length;h<m;h++){j=b[h];if(j.x>c)c=j.x;else if(j.x<f)f=j.x;if(j.y>e)e=j.y;else if(j.y<e)g=j.y}return{minX:f,minY:g,maxX:c,maxY:e}};THREE.Path.prototype.getPoint=function(b){for(var c=b*this.getLength(),e=this.sums,b=0;b<e.length;){if(e[b]>=c)return c=e[b]-c,b=this.curves[b],c=1-c/b.getLength(),b.getPointAt(c);b++}return null};
-THREE.Path.prototype.getLength=function(){var b=[],c=0,e,f=this.curves.length;for(e=0;e<f;e++)c+=this.curves[e].getLength(),b.push(c);this.sums=b;return c};THREE.Path.prototype.createPointsGeometry=function(b){for(var b=this.getPoints(b,!0),c=new THREE.Geometry,e=0;e<b.length;e++)c.vertices.push(new THREE.Vertex(new THREE.Vector3(b[e].x,b[e].y,0)));return c};
+THREE.Path.prototype.getLength=function(){var b=[],c=0,e,f=this.curves.length;for(e=0;e<f;e++)c+=this.curves[e].getLength(),b.push(c);this.sums=b;return c};THREE.Path.prototype.createPointsGeometry=function(b){return this.createGeometry(this.getPoints(b,!0))};THREE.Path.prototype.createSpacedPointsGeometry=function(b){return this.createGeometry(this.getSpacedPoints(b,!0))};
+THREE.Path.prototype.createGeometry=function(b){for(var c=new THREE.Geometry,e=0;e<b.length;e++)c.vertices.push(new THREE.Vertex(new THREE.Vector3(b[e].x,b[e].y,0)));return c};
 THREE.Path.prototype.transform=function(b){b=new THREE.Path;b.moveTo(0,0);b.quadraticCurveTo(100,20,140,80);console.log(b.cacheArcLengths());var c=this.getMinAndMax(),e=this.getPoints(),f,g,j,h,m,n;f=0;for(g=e.length;f<g;f++)j=e[f],h=j.x,m=j.y,n=h/c.maxX,h=b.getPoint(n),m=b.getNormalVector(n).multiplyScalar(m),j.x=h.x+m.x,j.y=h.y+m.y;return e};
 THREE.Path.prototype.transform=function(b){b=new THREE.Path;b.moveTo(0,0);b.quadraticCurveTo(100,20,140,80);console.log(b.cacheArcLengths());var c=this.getMinAndMax(),e=this.getPoints(),f,g,j,h,m,n;f=0;for(g=e.length;f<g;f++)j=e[f],h=j.x,m=j.y,n=h/c.maxX,h=b.getPoint(n),m=b.getNormalVector(n).multiplyScalar(m),j.x=h.x+m.x,j.y=h.y+m.y;return e};
 THREE.Path.prototype.nltransform=function(b,c,e,f,g,j){var h=this.getPoints(),m,n,p,o,t;m=0;for(n=h.length;m<n;m++)p=h[m],o=p.x,t=p.y,p.x=b*o+c*t+e,p.y=f*t+g*o+j;return h};
 THREE.Path.prototype.nltransform=function(b,c,e,f,g,j){var h=this.getPoints(),m,n,p,o,t;m=0;for(n=h.length;m<n;m++)p=h[m],o=p.x,t=p.y,p.x=b*o+c*t+e,p.y=f*t+g*o+j;return h};
 THREE.Path.prototype.debug=function(b){var c=this.getMinAndMax();b||(b=document.createElement("canvas"),b.setAttribute("width",c.maxX+100),b.setAttribute("height",c.maxY+100),document.body.appendChild(b));c=b.getContext("2d");c.fillStyle="white";c.fillRect(0,0,b.width,b.height);c.strokeStyle="black";c.beginPath();var e,f,g,b=0;for(e=this.actions.length;b<e;b++)f=this.actions[b],g=f.args,f=f.action,f!=THREE.PathActions.CSPLINE_THRU&&c[f].apply(c,g);c.stroke();c.closePath();c.strokeStyle="red";f=this.transform(0.866,
 THREE.Path.prototype.debug=function(b){var c=this.getMinAndMax();b||(b=document.createElement("canvas"),b.setAttribute("width",c.maxX+100),b.setAttribute("height",c.maxY+100),document.body.appendChild(b));c=b.getContext("2d");c.fillStyle="white";c.fillRect(0,0,b.width,b.height);c.strokeStyle="black";c.beginPath();var e,f,g,b=0;for(e=this.actions.length;b<e;b++)f=this.actions[b],g=f.args,f=f.action,f!=THREE.PathActions.CSPLINE_THRU&&c[f].apply(c,g);c.stroke();c.closePath();c.strokeStyle="red";f=this.transform(0.866,

+ 15 - 14
build/custom/ThreeExtras.js

@@ -95,12 +95,13 @@ THREE.Path.prototype.lineTo=function(a,c){var b=Array.prototype.slice.call(argum
 THREE.Path.prototype.quadraticCurveTo=function(a,c,b,g){var f=Array.prototype.slice.call(arguments),h=this.actions[this.actions.length-1].args,h=new THREE.QuadraticBezierCurve(h[h.length-2],h[h.length-1],a,c,b,g);this.curves.push(h);this.actions.push({action:THREE.PathActions.QUADRATIC_CURVE_TO,args:f,curve:h})};
 THREE.Path.prototype.quadraticCurveTo=function(a,c,b,g){var f=Array.prototype.slice.call(arguments),h=this.actions[this.actions.length-1].args,h=new THREE.QuadraticBezierCurve(h[h.length-2],h[h.length-1],a,c,b,g);this.curves.push(h);this.actions.push({action:THREE.PathActions.QUADRATIC_CURVE_TO,args:f,curve:h})};
 THREE.Path.prototype.bezierCurveTo=function(a,c,b,g,f,h){var e=Array.prototype.slice.call(arguments),j=this.actions[this.actions.length-1].args,j=new THREE.CubicBezierCurve(j[j.length-2],j[j.length-1],a,c,b,g,f,h);this.curves.push(j);this.actions.push({action:THREE.PathActions.BEZIER_CURVE_TO,args:e,curve:j})};
 THREE.Path.prototype.bezierCurveTo=function(a,c,b,g,f,h){var e=Array.prototype.slice.call(arguments),j=this.actions[this.actions.length-1].args,j=new THREE.CubicBezierCurve(j[j.length-2],j[j.length-1],a,c,b,g,f,h);this.curves.push(j);this.actions.push({action:THREE.PathActions.BEZIER_CURVE_TO,args:e,curve:j})};
 THREE.Path.prototype.splineThru=function(a){var c=Array.prototype.slice.call(arguments),b=this.actions[this.actions.length-1].args,b=[new THREE.Vector2(b[b.length-2],b[b.length-1])],b=b.concat(a),b=new THREE.SplineCurve(b);this.curves.push(b);this.actions.push({action:THREE.PathActions.CSPLINE_THRU,args:c,curve:b})};
 THREE.Path.prototype.splineThru=function(a){var c=Array.prototype.slice.call(arguments),b=this.actions[this.actions.length-1].args,b=[new THREE.Vector2(b[b.length-2],b[b.length-1])],b=b.concat(a),b=new THREE.SplineCurve(b);this.curves.push(b);this.actions.push({action:THREE.PathActions.CSPLINE_THRU,args:c,curve:b})};
-THREE.Path.prototype.arc=function(a,c,b,g,f,h){var e=Array.prototype.slice.call(arguments);this.curves.push(new THREE.ArcCurve(a,c,b,g,f,h));this.actions.push({action:THREE.PathActions.ARC,args:e})};THREE.Path.prototype.getSpacedPoints=function(a){a||(a=40);for(var c=[],b=0;b<a;b++)c.push(this.getPoint(b/a));return c};
+THREE.Path.prototype.arc=function(a,c,b,g,f,h){var e=Array.prototype.slice.call(arguments);this.curves.push(new THREE.ArcCurve(a,c,b,g,f,h));this.actions.push({action:THREE.PathActions.ARC,args:e})};THREE.Path.prototype.getSpacedPoints=function(a,c){a||(a=40);for(var b=[],g=0;g<a;g++)b.push(this.getPoint(g/a));c&&b.push(b[0]);return b};
 THREE.Path.prototype.getPoints=function(a,c){var a=a||12,b=[],g,f,h,e,j,k,l,m,n,o,p,w,t;g=0;for(f=this.actions.length;g<f;g++)switch(h=this.actions[g],e=h.action,h=h.args,e){case THREE.PathActions.LINE_TO:b.push(new THREE.Vector2(h[0],h[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:j=h[2];k=h[3];n=h[0];o=h[1];b.length>0?(e=b[b.length-1],p=e.x,w=e.y):(e=this.actions[g-1].args,p=e[e.length-2],w=e[e.length-1]);for(e=1;e<=a;e++)t=e/a,h=THREE.FontUtils.b2(t,p,n,j),t=THREE.FontUtils.b2(t,w,o,k),
 THREE.Path.prototype.getPoints=function(a,c){var a=a||12,b=[],g,f,h,e,j,k,l,m,n,o,p,w,t;g=0;for(f=this.actions.length;g<f;g++)switch(h=this.actions[g],e=h.action,h=h.args,e){case THREE.PathActions.LINE_TO:b.push(new THREE.Vector2(h[0],h[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:j=h[2];k=h[3];n=h[0];o=h[1];b.length>0?(e=b[b.length-1],p=e.x,w=e.y):(e=this.actions[g-1].args,p=e[e.length-2],w=e[e.length-1]);for(e=1;e<=a;e++)t=e/a,h=THREE.FontUtils.b2(t,p,n,j),t=THREE.FontUtils.b2(t,w,o,k),
 b.push(new THREE.Vector2(h,t));break;case THREE.PathActions.BEZIER_CURVE_TO:j=h[4];k=h[5];n=h[0];o=h[1];l=h[2];m=h[3];b.length>0?(e=b[b.length-1],p=e.x,w=e.y):(e=this.actions[g-1].args,p=e[e.length-2],w=e[e.length-1]);for(e=1;e<=a;e++)t=e/a,h=THREE.FontUtils.b3(t,p,n,l,j),t=THREE.FontUtils.b3(t,w,o,m,k),b.push(new THREE.Vector2(h,t));break;case THREE.PathActions.CSPLINE_THRU:e=this.actions[g-1].args;e=[new THREE.Vector2(e[e.length-2],e[e.length-1])];t=a*h[0].length;e=e.concat(h[0]);h=new THREE.SplineCurve(e);
 b.push(new THREE.Vector2(h,t));break;case THREE.PathActions.BEZIER_CURVE_TO:j=h[4];k=h[5];n=h[0];o=h[1];l=h[2];m=h[3];b.length>0?(e=b[b.length-1],p=e.x,w=e.y):(e=this.actions[g-1].args,p=e[e.length-2],w=e[e.length-1]);for(e=1;e<=a;e++)t=e/a,h=THREE.FontUtils.b3(t,p,n,l,j),t=THREE.FontUtils.b3(t,w,o,m,k),b.push(new THREE.Vector2(h,t));break;case THREE.PathActions.CSPLINE_THRU:e=this.actions[g-1].args;e=[new THREE.Vector2(e[e.length-2],e[e.length-1])];t=a*h[0].length;e=e.concat(h[0]);h=new THREE.SplineCurve(e);
 for(e=1;e<=t;e++)b.push(h.getPointAt(e/t));break;case THREE.PathActions.ARC:e=this.actions[g-1].args;j=h[0];k=h[1];l=h[2];n=h[3];t=h[4];o=!!h[5];m=e[e.length-2];p=e[e.length-1];e.length==0&&(m=p=0);w=t-n;var v=a*2;for(e=1;e<=v;e++)t=e/v,o||(t=1-t),t=n+t*w,h=m+j+l*Math.cos(t),t=p+k+l*Math.sin(t),b.push(new THREE.Vector2(h,t))}c&&b.push(b[0]);return b};
 for(e=1;e<=t;e++)b.push(h.getPointAt(e/t));break;case THREE.PathActions.ARC:e=this.actions[g-1].args;j=h[0];k=h[1];l=h[2];n=h[3];t=h[4];o=!!h[5];m=e[e.length-2];p=e[e.length-1];e.length==0&&(m=p=0);w=t-n;var v=a*2;for(e=1;e<=v;e++)t=e/v,o||(t=1-t),t=n+t*w,h=m+j+l*Math.cos(t),t=p+k+l*Math.sin(t),b.push(new THREE.Vector2(h,t))}c&&b.push(b[0]);return b};
 THREE.Path.prototype.getMinAndMax=function(){var a=this.getPoints(),c,b,g,f;c=b=Number.NEGATIVE_INFINITY;g=f=Number.POSITIVE_INFINITY;var h,e,j;e=0;for(j=a.length;e<j;e++){h=a[e];if(h.x>c)c=h.x;else if(h.x<g)g=h.x;if(h.y>b)b=h.y;else if(h.y<b)f=h.y}return{minX:g,minY:f,maxX:c,maxY:b}};THREE.Path.prototype.getPoint=function(a){for(var c=a*this.getLength(),b=this.sums,a=0;a<b.length;){if(b[a]>=c)return c=b[a]-c,a=this.curves[a],c=1-c/a.getLength(),a.getPointAt(c);a++}return null};
 THREE.Path.prototype.getMinAndMax=function(){var a=this.getPoints(),c,b,g,f;c=b=Number.NEGATIVE_INFINITY;g=f=Number.POSITIVE_INFINITY;var h,e,j;e=0;for(j=a.length;e<j;e++){h=a[e];if(h.x>c)c=h.x;else if(h.x<g)g=h.x;if(h.y>b)b=h.y;else if(h.y<b)f=h.y}return{minX:g,minY:f,maxX:c,maxY:b}};THREE.Path.prototype.getPoint=function(a){for(var c=a*this.getLength(),b=this.sums,a=0;a<b.length;){if(b[a]>=c)return c=b[a]-c,a=this.curves[a],c=1-c/a.getLength(),a.getPointAt(c);a++}return null};
-THREE.Path.prototype.getLength=function(){var a=[],c=0,b,g=this.curves.length;for(b=0;b<g;b++)c+=this.curves[b].getLength(),a.push(c);this.sums=a;return c};THREE.Path.prototype.createPointsGeometry=function(a){for(var a=this.getPoints(a,!0),c=new THREE.Geometry,b=0;b<a.length;b++)c.vertices.push(new THREE.Vertex(new THREE.Vector3(a[b].x,a[b].y,0)));return c};
+THREE.Path.prototype.getLength=function(){var a=[],c=0,b,g=this.curves.length;for(b=0;b<g;b++)c+=this.curves[b].getLength(),a.push(c);this.sums=a;return c};THREE.Path.prototype.createPointsGeometry=function(a){return this.createGeometry(this.getPoints(a,!0))};THREE.Path.prototype.createSpacedPointsGeometry=function(a){return this.createGeometry(this.getSpacedPoints(a,!0))};
+THREE.Path.prototype.createGeometry=function(a){for(var c=new THREE.Geometry,b=0;b<a.length;b++)c.vertices.push(new THREE.Vertex(new THREE.Vector3(a[b].x,a[b].y,0)));return c};
 THREE.Path.prototype.transform=function(a){a=new THREE.Path;a.moveTo(0,0);a.quadraticCurveTo(100,20,140,80);console.log(a.cacheArcLengths());var c=this.getMinAndMax(),b=this.getPoints(),g,f,h,e,j,k;g=0;for(f=b.length;g<f;g++)h=b[g],e=h.x,j=h.y,k=e/c.maxX,e=a.getPoint(k),j=a.getNormalVector(k).multiplyScalar(j),h.x=e.x+j.x,h.y=e.y+j.y;return b};
 THREE.Path.prototype.transform=function(a){a=new THREE.Path;a.moveTo(0,0);a.quadraticCurveTo(100,20,140,80);console.log(a.cacheArcLengths());var c=this.getMinAndMax(),b=this.getPoints(),g,f,h,e,j,k;g=0;for(f=b.length;g<f;g++)h=b[g],e=h.x,j=h.y,k=e/c.maxX,e=a.getPoint(k),j=a.getNormalVector(k).multiplyScalar(j),h.x=e.x+j.x,h.y=e.y+j.y;return b};
 THREE.Path.prototype.nltransform=function(a,c,b,g,f,h){var e=this.getPoints(),j,k,l,m,n;j=0;for(k=e.length;j<k;j++)l=e[j],m=l.x,n=l.y,l.x=a*m+c*n+b,l.y=g*n+f*m+h;return e};
 THREE.Path.prototype.nltransform=function(a,c,b,g,f,h){var e=this.getPoints(),j,k,l,m,n;j=0;for(k=e.length;j<k;j++)l=e[j],m=l.x,n=l.y,l.x=a*m+c*n+b,l.y=g*n+f*m+h;return e};
 THREE.Path.prototype.debug=function(a){var c=this.getMinAndMax();a||(a=document.createElement("canvas"),a.setAttribute("width",c.maxX+100),a.setAttribute("height",c.maxY+100),document.body.appendChild(a));c=a.getContext("2d");c.fillStyle="white";c.fillRect(0,0,a.width,a.height);c.strokeStyle="black";c.beginPath();var b,g,f,a=0;for(b=this.actions.length;a<b;a++)g=this.actions[a],f=g.args,g=g.action,g!=THREE.PathActions.CSPLINE_THRU&&c[g].apply(c,f);c.stroke();c.closePath();c.strokeStyle="red";g=this.transform(0.866,
 THREE.Path.prototype.debug=function(a){var c=this.getMinAndMax();a||(a=document.createElement("canvas"),a.setAttribute("width",c.maxX+100),a.setAttribute("height",c.maxY+100),document.body.appendChild(a));c=a.getContext("2d");c.fillStyle="white";c.fillRect(0,0,a.width,a.height);c.strokeStyle="black";c.beginPath();var b,g,f,a=0;for(b=this.actions.length;a<b;a++)g=this.actions[a],f=g.args,g=g.action,g!=THREE.PathActions.CSPLINE_THRU&&c[g].apply(c,f);c.stroke();c.closePath();c.strokeStyle="red";g=this.transform(0.866,
@@ -173,34 +174,34 @@ b,o=w[k+2]*b,p.push(new THREE.Vertex(new THREE.Vector3(m,n,o)))}}if(a.morphColor
 g.vertices[f],c,f))}})();g.computeCentroids();g.computeFaceNormals();this.hasNormals(g)&&g.computeTangents();c(g)};THREE.BinaryLoader=function(a){THREE.Loader.call(this,a)};THREE.BinaryLoader.prototype=new THREE.Loader;THREE.BinaryLoader.prototype.constructor=THREE.BinaryLoader;THREE.BinaryLoader.prototype.supr=THREE.Loader.prototype;
 g.vertices[f],c,f))}})();g.computeCentroids();g.computeFaceNormals();this.hasNormals(g)&&g.computeTangents();c(g)};THREE.BinaryLoader=function(a){THREE.Loader.call(this,a)};THREE.BinaryLoader.prototype=new THREE.Loader;THREE.BinaryLoader.prototype.constructor=THREE.BinaryLoader;THREE.BinaryLoader.prototype.supr=THREE.Loader.prototype;
 THREE.BinaryLoader.prototype={load:function(a){var c=a.model,b=a.callback,g=a.texture_path?a.texture_path:THREE.Loader.prototype.extractUrlbase(c),f=a.bin_path?a.bin_path:THREE.Loader.prototype.extractUrlbase(c),a=(new Date).getTime(),c=new Worker(c),h=this.showProgress?THREE.Loader.prototype.updateProgress:null;c.onmessage=function(a){THREE.BinaryLoader.prototype.loadAjaxBuffers(a.data.buffers,a.data.materials,b,f,g,h)};c.onerror=function(a){alert("worker.onerror: "+a.message+"\n"+a.data);a.preventDefault()};
 THREE.BinaryLoader.prototype={load:function(a){var c=a.model,b=a.callback,g=a.texture_path?a.texture_path:THREE.Loader.prototype.extractUrlbase(c),f=a.bin_path?a.bin_path:THREE.Loader.prototype.extractUrlbase(c),a=(new Date).getTime(),c=new Worker(c),h=this.showProgress?THREE.Loader.prototype.updateProgress:null;c.onmessage=function(a){THREE.BinaryLoader.prototype.loadAjaxBuffers(a.data.buffers,a.data.materials,b,f,g,h)};c.onerror=function(a){alert("worker.onerror: "+a.message+"\n"+a.data);a.preventDefault()};
 c.postMessage(a)},loadAjaxBuffers:function(a,c,b,g,f,h){var e=new XMLHttpRequest,j=g+"/"+a,k=0;e.onreadystatechange=function(){e.readyState==4?e.status==200||e.status==0?THREE.BinaryLoader.prototype.createBinModel(e.responseText,b,f,c):alert("Couldn't load ["+j+"] ["+e.status+"]"):e.readyState==3?h&&(k==0&&(k=e.getResponseHeader("Content-Length")),h({total:k,loaded:e.responseText.length})):e.readyState==2&&(k=e.getResponseHeader("Content-Length"))};e.open("GET",j,!0);e.overrideMimeType("text/plain; charset=x-user-defined");
 c.postMessage(a)},loadAjaxBuffers:function(a,c,b,g,f,h){var e=new XMLHttpRequest,j=g+"/"+a,k=0;e.onreadystatechange=function(){e.readyState==4?e.status==200||e.status==0?THREE.BinaryLoader.prototype.createBinModel(e.responseText,b,f,c):alert("Couldn't load ["+j+"] ["+e.status+"]"):e.readyState==3?h&&(k==0&&(k=e.getResponseHeader("Content-Length")),h({total:k,loaded:e.responseText.length})):e.readyState==2&&(k=e.getResponseHeader("Content-Length"))};e.open("GET",j,!0);e.overrideMimeType("text/plain; charset=x-user-defined");
-e.setRequestHeader("Content-Type","text/plain");e.send(null)},createBinModel:function(a,c,b,g){var f=function(b){function c(a,b){var e=m(a,b),g=m(a,b+1),f=m(a,b+2),h=m(a,b+3),j=(h<<1&255|f>>7)-127;e|=(f&127)<<16|g<<8;if(e==0&&j==-127)return 0;return(1-2*(h>>7))*(1+e*Math.pow(2,-23))*Math.pow(2,j)}function f(a,b){var c=m(a,b),e=m(a,b+1),g=m(a,b+2);return(m(a,b+3)<<24)+(g<<16)+(e<<8)+c}function k(a,b){var c=m(a,b);return(m(a,b+1)<<8)+c}function l(a,b){var c=m(a,b);return c>127?c-256:c}function m(a,
-b){return a.charCodeAt(b)&255}function n(b){var c,e,g;c=f(a,b);e=f(a,b+A);g=f(a,b+E);b=k(a,b+G);THREE.BinaryLoader.prototype.f3(x,c,e,g,b)}function o(b){var c,e,g,h,l,m;c=f(a,b);e=f(a,b+A);g=f(a,b+E);h=k(a,b+G);l=f(a,b+H);m=f(a,b+L);b=f(a,b+J);THREE.BinaryLoader.prototype.f3n(x,z,c,e,g,h,l,m,b)}function p(b){var c,e,g,h;c=f(a,b);e=f(a,b+D);g=f(a,b+K);h=f(a,b+F);b=k(a,b+I);THREE.BinaryLoader.prototype.f4(x,c,e,g,h,b)}function w(b){var c,e,g,h,l,m,n,o;c=f(a,b);e=f(a,b+D);g=f(a,b+K);h=f(a,b+F);l=k(a,
-b+I);m=f(a,b+O);n=f(a,b+M);o=f(a,b+C);b=f(a,b+P);THREE.BinaryLoader.prototype.f4n(x,z,c,e,g,h,l,m,n,o,b)}function t(b){var c,e;c=f(a,b);e=f(a,b+N);b=f(a,b+R);THREE.BinaryLoader.prototype.uv3(x.faceVertexUvs[0],B[c*2],B[c*2+1],B[e*2],B[e*2+1],B[b*2],B[b*2+1])}function v(b){var c,e,g;c=f(a,b);e=f(a,b+S);g=f(a,b+Y);b=f(a,b+Z);THREE.BinaryLoader.prototype.uv4(x.faceVertexUvs[0],B[c*2],B[c*2+1],B[e*2],B[e*2+1],B[g*2],B[g*2+1],B[b*2],B[b*2+1])}var x=this,y=0,u,z=[],B=[],A,E,G,H,L,J,D,K,F,I,O,M,C,P,N,R,
+e.setRequestHeader("Content-Type","text/plain");e.send(null)},createBinModel:function(a,c,b,g){var f=function(b){function c(a,b){var g=m(a,b),e=m(a,b+1),f=m(a,b+2),h=m(a,b+3),j=(h<<1&255|f>>7)-127;g|=(f&127)<<16|e<<8;if(g==0&&j==-127)return 0;return(1-2*(h>>7))*(1+g*Math.pow(2,-23))*Math.pow(2,j)}function f(a,b){var c=m(a,b),g=m(a,b+1),e=m(a,b+2);return(m(a,b+3)<<24)+(e<<16)+(g<<8)+c}function k(a,b){var c=m(a,b);return(m(a,b+1)<<8)+c}function l(a,b){var c=m(a,b);return c>127?c-256:c}function m(a,
+b){return a.charCodeAt(b)&255}function n(b){var c,g,e;c=f(a,b);g=f(a,b+A);e=f(a,b+E);b=k(a,b+G);THREE.BinaryLoader.prototype.f3(x,c,g,e,b)}function o(b){var c,g,e,h,l,m;c=f(a,b);g=f(a,b+A);e=f(a,b+E);h=k(a,b+G);l=f(a,b+H);m=f(a,b+L);b=f(a,b+J);THREE.BinaryLoader.prototype.f3n(x,z,c,g,e,h,l,m,b)}function p(b){var c,g,e,h;c=f(a,b);g=f(a,b+D);e=f(a,b+K);h=f(a,b+F);b=k(a,b+I);THREE.BinaryLoader.prototype.f4(x,c,g,e,h,b)}function w(b){var c,g,e,h,l,m,n,o;c=f(a,b);g=f(a,b+D);e=f(a,b+K);h=f(a,b+F);l=k(a,
+b+I);m=f(a,b+O);n=f(a,b+M);o=f(a,b+C);b=f(a,b+P);THREE.BinaryLoader.prototype.f4n(x,z,c,g,e,h,l,m,n,o,b)}function t(b){var c,g;c=f(a,b);g=f(a,b+N);b=f(a,b+R);THREE.BinaryLoader.prototype.uv3(x.faceVertexUvs[0],B[c*2],B[c*2+1],B[g*2],B[g*2+1],B[b*2],B[b*2+1])}function v(b){var c,g,e;c=f(a,b);g=f(a,b+S);e=f(a,b+Y);b=f(a,b+Z);THREE.BinaryLoader.prototype.uv4(x.faceVertexUvs[0],B[c*2],B[c*2+1],B[g*2],B[g*2+1],B[e*2],B[e*2+1],B[b*2],B[b*2+1])}var x=this,y=0,u,z=[],B=[],A,E,G,H,L,J,D,K,F,I,O,M,C,P,N,R,
 S,Y,Z,T,U,V,W,X,Q;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(x,g,b);u={signature:a.substr(y,8),header_bytes:m(a,y+8),vertex_coordinate_bytes:m(a,y+9),normal_coordinate_bytes:m(a,y+10),uv_coordinate_bytes:m(a,y+11),vertex_index_bytes:m(a,y+12),normal_index_bytes:m(a,y+13),uv_index_bytes:m(a,y+14),material_index_bytes:m(a,y+15),nvertices:f(a,y+16),nnormals:f(a,y+16+4),nuvs:f(a,y+16+8),ntri_flat:f(a,y+16+12),ntri_smooth:f(a,y+16+16),ntri_flat_uv:f(a,y+16+20),ntri_smooth_uv:f(a,y+
 S,Y,Z,T,U,V,W,X,Q;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(x,g,b);u={signature:a.substr(y,8),header_bytes:m(a,y+8),vertex_coordinate_bytes:m(a,y+9),normal_coordinate_bytes:m(a,y+10),uv_coordinate_bytes:m(a,y+11),vertex_index_bytes:m(a,y+12),normal_index_bytes:m(a,y+13),uv_index_bytes:m(a,y+14),material_index_bytes:m(a,y+15),nvertices:f(a,y+16),nnormals:f(a,y+16+4),nuvs:f(a,y+16+8),ntri_flat:f(a,y+16+12),ntri_smooth:f(a,y+16+16),ntri_flat_uv:f(a,y+16+20),ntri_smooth_uv:f(a,y+
 16+24),nquad_flat:f(a,y+16+28),nquad_smooth:f(a,y+16+32),nquad_flat_uv:f(a,y+16+36),nquad_smooth_uv:f(a,y+16+40)};y+=u.header_bytes;A=u.vertex_index_bytes;E=u.vertex_index_bytes*2;G=u.vertex_index_bytes*3;H=u.vertex_index_bytes*3+u.material_index_bytes;L=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes;J=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes*2;D=u.vertex_index_bytes;K=u.vertex_index_bytes*2;F=u.vertex_index_bytes*3;I=u.vertex_index_bytes*4;O=u.vertex_index_bytes*
 16+24),nquad_flat:f(a,y+16+28),nquad_smooth:f(a,y+16+32),nquad_flat_uv:f(a,y+16+36),nquad_smooth_uv:f(a,y+16+40)};y+=u.header_bytes;A=u.vertex_index_bytes;E=u.vertex_index_bytes*2;G=u.vertex_index_bytes*3;H=u.vertex_index_bytes*3+u.material_index_bytes;L=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes;J=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes*2;D=u.vertex_index_bytes;K=u.vertex_index_bytes*2;F=u.vertex_index_bytes*3;I=u.vertex_index_bytes*4;O=u.vertex_index_bytes*
 4+u.material_index_bytes;M=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes;C=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*2;P=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*3;N=u.uv_index_bytes;R=u.uv_index_bytes*2;S=u.uv_index_bytes;Y=u.uv_index_bytes*2;Z=u.uv_index_bytes*3;b=u.vertex_index_bytes*3+u.material_index_bytes;Q=u.vertex_index_bytes*4+u.material_index_bytes;T=u.ntri_flat*b;U=u.ntri_smooth*(b+u.normal_index_bytes*3);V=u.ntri_flat_uv*
 4+u.material_index_bytes;M=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes;C=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*2;P=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*3;N=u.uv_index_bytes;R=u.uv_index_bytes*2;S=u.uv_index_bytes;Y=u.uv_index_bytes*2;Z=u.uv_index_bytes*3;b=u.vertex_index_bytes*3+u.material_index_bytes;Q=u.vertex_index_bytes*4+u.material_index_bytes;T=u.ntri_flat*b;U=u.ntri_smooth*(b+u.normal_index_bytes*3);V=u.ntri_flat_uv*
-(b+u.uv_index_bytes*3);W=u.ntri_smooth_uv*(b+u.normal_index_bytes*3+u.uv_index_bytes*3);X=u.nquad_flat*Q;b=u.nquad_smooth*(Q+u.normal_index_bytes*4);Q=u.nquad_flat_uv*(Q+u.uv_index_bytes*4);y+=function(b){for(var g,f,h,j=u.vertex_coordinate_bytes*3,k=b+u.nvertices*j;b<k;b+=j)g=c(a,b),f=c(a,b+u.vertex_coordinate_bytes),h=c(a,b+u.vertex_coordinate_bytes*2),THREE.BinaryLoader.prototype.v(x,g,f,h);return u.nvertices*j}(y);y+=function(b){for(var c,e,g,f=u.normal_coordinate_bytes*3,h=b+u.nnormals*f;b<h;b+=
-f)c=l(a,b),e=l(a,b+u.normal_coordinate_bytes),g=l(a,b+u.normal_coordinate_bytes*2),z.push(c/127,e/127,g/127);return u.nnormals*f}(y);y+=function(b){for(var g,f,h=u.uv_coordinate_bytes*2,j=b+u.nuvs*h;b<j;b+=h)g=c(a,b),f=c(a,b+u.uv_coordinate_bytes),B.push(g,f);return u.nuvs*h}(y);T=y+T;U=T+U;V=U+V;W=V+W;X=W+X;b=X+b;Q=b+Q;(function(a){var b,c=u.vertex_index_bytes*3+u.material_index_bytes,e=c+u.uv_index_bytes*3,g=a+u.ntri_flat_uv*e;for(b=a;b<g;b+=e)n(b),t(b+c);return g-a})(U);(function(a){var b,c=u.vertex_index_bytes*
-3+u.material_index_bytes+u.normal_index_bytes*3,e=c+u.uv_index_bytes*3,g=a+u.ntri_smooth_uv*e;for(b=a;b<g;b+=e)o(b),t(b+c);return g-a})(V);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes,e=c+u.uv_index_bytes*4,g=a+u.nquad_flat_uv*e;for(b=a;b<g;b+=e)p(b),v(b+c);return g-a})(b);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*4,e=c+u.uv_index_bytes*4,g=a+u.nquad_smooth_uv*e;for(b=a;b<g;b+=e)w(b),v(b+c);return g-a})(Q);(function(a){var b,c=u.vertex_index_bytes*
-3+u.material_index_bytes,e=a+u.ntri_flat*c;for(b=a;b<e;b+=c)n(b);return e-a})(y);(function(a){var b,c=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes*3,e=a+u.ntri_smooth*c;for(b=a;b<e;b+=c)o(b);return e-a})(T);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes,e=a+u.nquad_flat*c;for(b=a;b<e;b+=c)p(b);return e-a})(W);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*4,e=a+u.nquad_smooth*c;for(b=a;b<e;b+=c)w(b);return e-a})(X);
+(b+u.uv_index_bytes*3);W=u.ntri_smooth_uv*(b+u.normal_index_bytes*3+u.uv_index_bytes*3);X=u.nquad_flat*Q;b=u.nquad_smooth*(Q+u.normal_index_bytes*4);Q=u.nquad_flat_uv*(Q+u.uv_index_bytes*4);y+=function(b){for(var g,f,h,j=u.vertex_coordinate_bytes*3,k=b+u.nvertices*j;b<k;b+=j)g=c(a,b),f=c(a,b+u.vertex_coordinate_bytes),h=c(a,b+u.vertex_coordinate_bytes*2),THREE.BinaryLoader.prototype.v(x,g,f,h);return u.nvertices*j}(y);y+=function(b){for(var c,g,e,f=u.normal_coordinate_bytes*3,h=b+u.nnormals*f;b<h;b+=
+f)c=l(a,b),g=l(a,b+u.normal_coordinate_bytes),e=l(a,b+u.normal_coordinate_bytes*2),z.push(c/127,g/127,e/127);return u.nnormals*f}(y);y+=function(b){for(var g,f,h=u.uv_coordinate_bytes*2,j=b+u.nuvs*h;b<j;b+=h)g=c(a,b),f=c(a,b+u.uv_coordinate_bytes),B.push(g,f);return u.nuvs*h}(y);T=y+T;U=T+U;V=U+V;W=V+W;X=W+X;b=X+b;Q=b+Q;(function(a){var b,c=u.vertex_index_bytes*3+u.material_index_bytes,g=c+u.uv_index_bytes*3,e=a+u.ntri_flat_uv*g;for(b=a;b<e;b+=g)n(b),t(b+c);return e-a})(U);(function(a){var b,c=u.vertex_index_bytes*
+3+u.material_index_bytes+u.normal_index_bytes*3,g=c+u.uv_index_bytes*3,e=a+u.ntri_smooth_uv*g;for(b=a;b<e;b+=g)o(b),t(b+c);return e-a})(V);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes,g=c+u.uv_index_bytes*4,e=a+u.nquad_flat_uv*g;for(b=a;b<e;b+=g)p(b),v(b+c);return e-a})(b);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*4,g=c+u.uv_index_bytes*4,e=a+u.nquad_smooth_uv*g;for(b=a;b<e;b+=g)w(b),v(b+c);return e-a})(Q);(function(a){var b,c=u.vertex_index_bytes*
+3+u.material_index_bytes,g=a+u.ntri_flat*c;for(b=a;b<g;b+=c)n(b);return g-a})(y);(function(a){var b,c=u.vertex_index_bytes*3+u.material_index_bytes+u.normal_index_bytes*3,g=a+u.ntri_smooth*c;for(b=a;b<g;b+=c)o(b);return g-a})(T);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes,g=a+u.nquad_flat*c;for(b=a;b<g;b+=c)p(b);return g-a})(W);(function(a){var b,c=u.vertex_index_bytes*4+u.material_index_bytes+u.normal_index_bytes*4,g=a+u.nquad_smooth*c;for(b=a;b<g;b+=c)w(b);return g-a})(X);
 this.computeCentroids();this.computeFaceNormals();THREE.Loader.prototype.hasNormals(this)&&this.computeTangents()};f.prototype=new THREE.Geometry;f.prototype.constructor=f;c(new f(b))},v:function(a,c,b,g){a.vertices.push(new THREE.Vertex(new THREE.Vector3(c,b,g)))},f3:function(a,c,b,g,f){a.faces.push(new THREE.Face3(c,b,g,null,null,a.materials[f]))},f4:function(a,c,b,g,f,h){a.faces.push(new THREE.Face4(c,b,g,f,null,null,a.materials[h]))},f3n:function(a,c,b,g,f,h,e,j,k){var h=a.materials[h],l=c[j*
 this.computeCentroids();this.computeFaceNormals();THREE.Loader.prototype.hasNormals(this)&&this.computeTangents()};f.prototype=new THREE.Geometry;f.prototype.constructor=f;c(new f(b))},v:function(a,c,b,g){a.vertices.push(new THREE.Vertex(new THREE.Vector3(c,b,g)))},f3:function(a,c,b,g,f){a.faces.push(new THREE.Face3(c,b,g,null,null,a.materials[f]))},f4:function(a,c,b,g,f,h){a.faces.push(new THREE.Face4(c,b,g,f,null,null,a.materials[h]))},f3n:function(a,c,b,g,f,h,e,j,k){var h=a.materials[h],l=c[j*
 3],m=c[j*3+1],j=c[j*3+2],n=c[k*3],o=c[k*3+1],k=c[k*3+2];a.faces.push(new THREE.Face3(b,g,f,[new THREE.Vector3(c[e*3],c[e*3+1],c[e*3+2]),new THREE.Vector3(l,m,j),new THREE.Vector3(n,o,k)],null,h))},f4n:function(a,c,b,g,f,h,e,j,k,l,m){var e=a.materials[e],n=c[k*3],o=c[k*3+1],k=c[k*3+2],p=c[l*3],w=c[l*3+1],l=c[l*3+2],t=c[m*3],v=c[m*3+1],m=c[m*3+2];a.faces.push(new THREE.Face4(b,g,f,h,[new THREE.Vector3(c[j*3],c[j*3+1],c[j*3+2]),new THREE.Vector3(n,o,k),new THREE.Vector3(p,w,l),new THREE.Vector3(t,v,
 3],m=c[j*3+1],j=c[j*3+2],n=c[k*3],o=c[k*3+1],k=c[k*3+2];a.faces.push(new THREE.Face3(b,g,f,[new THREE.Vector3(c[e*3],c[e*3+1],c[e*3+2]),new THREE.Vector3(l,m,j),new THREE.Vector3(n,o,k)],null,h))},f4n:function(a,c,b,g,f,h,e,j,k,l,m){var e=a.materials[e],n=c[k*3],o=c[k*3+1],k=c[k*3+2],p=c[l*3],w=c[l*3+1],l=c[l*3+2],t=c[m*3],v=c[m*3+1],m=c[m*3+2];a.faces.push(new THREE.Face4(b,g,f,h,[new THREE.Vector3(c[j*3],c[j*3+1],c[j*3+2]),new THREE.Vector3(n,o,k),new THREE.Vector3(p,w,l),new THREE.Vector3(t,v,
 m)],null,e))},uv3:function(a,c,b,g,f,h,e){var j=[];j.push(new THREE.UV(c,b));j.push(new THREE.UV(g,f));j.push(new THREE.UV(h,e));a.push(j)},uv4:function(a,c,b,g,f,h,e,j,k){var l=[];l.push(new THREE.UV(c,b));l.push(new THREE.UV(g,f));l.push(new THREE.UV(h,e));l.push(new THREE.UV(j,k));a.push(l)}};THREE.SceneLoader=function(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){};this.callbackSync=function(){};this.callbackProgress=function(){}};
 m)],null,e))},uv3:function(a,c,b,g,f,h,e){var j=[];j.push(new THREE.UV(c,b));j.push(new THREE.UV(g,f));j.push(new THREE.UV(h,e));a.push(j)},uv4:function(a,c,b,g,f,h,e,j,k){var l=[];l.push(new THREE.UV(c,b));l.push(new THREE.UV(g,f));l.push(new THREE.UV(h,e));l.push(new THREE.UV(j,k));a.push(l)}};THREE.SceneLoader=function(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){};this.callbackSync=function(){};this.callbackProgress=function(){}};
-THREE.SceneLoader.prototype={load:function(a,c){var b=this,g=new Worker(a);g.postMessage(0);var f=THREE.Loader.prototype.extractUrlbase(a);g.onmessage=function(a){function e(a,b){return b=="relativeToHTML"?a:f+"/"+a}function g(){for(p in D.objects)if(!C.objects[p])if(y=D.objects[p],y.geometry!==void 0){if(A=C.geometries[y.geometry]){var a=!1;L=[];for(N=0;N<y.materials.length;N++)L[N]=C.materials[y.materials[N]],a=L[N]instanceof THREE.MeshShaderMaterial;a&&A.computeTangents();u=y.position;r=y.rotation;
+THREE.SceneLoader.prototype={load:function(a,c){var b=this,g=new Worker(a);g.postMessage(0);var f=THREE.Loader.prototype.extractUrlbase(a);g.onmessage=function(a){function g(a,b){return b=="relativeToHTML"?a:f+"/"+a}function j(){for(p in D.objects)if(!C.objects[p])if(y=D.objects[p],y.geometry!==void 0){if(A=C.geometries[y.geometry]){var a=!1;L=[];for(N=0;N<y.materials.length;N++)L[N]=C.materials[y.materials[N]],a=L[N]instanceof THREE.MeshShaderMaterial;a&&A.computeTangents();u=y.position;r=y.rotation;
 q=y.quaternion;s=y.scale;q=0;L.length==0&&(L[0]=new THREE.MeshFaceMaterial);L.length>1&&(L=[new THREE.MeshFaceMaterial]);object=new THREE.Mesh(A,L);object.name=p;object.position.set(u[0],u[1],u[2]);q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]);object.scale.set(s[0],s[1],s[2]);object.visible=y.visible;C.scene.addObject(object);C.objects[p]=object;y.meshCollider&&(a=THREE.CollisionUtils.MeshColliderWBox(object),C.scene.collisions.colliders.push(a));
 q=y.quaternion;s=y.scale;q=0;L.length==0&&(L[0]=new THREE.MeshFaceMaterial);L.length>1&&(L=[new THREE.MeshFaceMaterial]);object=new THREE.Mesh(A,L);object.name=p;object.position.set(u[0],u[1],u[2]);q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]);object.scale.set(s[0],s[1],s[2]);object.visible=y.visible;C.scene.addObject(object);C.objects[p]=object;y.meshCollider&&(a=THREE.CollisionUtils.MeshColliderWBox(object),C.scene.collisions.colliders.push(a));
 if(y.castsShadow)a=new THREE.ShadowVolume(A),C.scene.addChild(a),a.position=object.position,a.rotation=object.rotation,a.scale=object.scale;y.trigger&&y.trigger.toLowerCase()!="none"&&(a={type:y.trigger,object:y},C.triggers[object.name]=a)}}else u=y.position,r=y.rotation,q=y.quaternion,s=y.scale,q=0,object=new THREE.Object3D,object.name=p,object.position.set(u[0],u[1],u[2]),q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]),object.scale.set(s[0],
 if(y.castsShadow)a=new THREE.ShadowVolume(A),C.scene.addChild(a),a.position=object.position,a.rotation=object.rotation,a.scale=object.scale;y.trigger&&y.trigger.toLowerCase()!="none"&&(a={type:y.trigger,object:y},C.triggers[object.name]=a)}}else u=y.position,r=y.rotation,q=y.quaternion,s=y.scale,q=0,object=new THREE.Object3D,object.name=p,object.position.set(u[0],u[1],u[2]),q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]),object.scale.set(s[0],
-s[1],s[2]),object.visible=y.visible!==void 0?y.visible:!1,C.scene.addObject(object),C.objects[p]=object,C.empties[p]=object,y.trigger&&y.trigger.toLowerCase()!="none"&&(a={type:y.trigger,object:y},C.triggers[object.name]=a)}function k(a){return function(c){C.geometries[a]=c;g();F-=1;b.onLoadComplete();m()}}function l(a){return function(b){C.geometries[a]=b}}function m(){b.callbackProgress({totalModels:O,totalTextures:M,loadedModels:O-F,loadedTextures:M-I},C);b.onLoadProgress();F==0&&I==0&&c(C)}var n,
+s[1],s[2]),object.visible=y.visible!==void 0?y.visible:!1,C.scene.addObject(object),C.objects[p]=object,C.empties[p]=object,y.trigger&&y.trigger.toLowerCase()!="none"&&(a={type:y.trigger,object:y},C.triggers[object.name]=a)}function k(a){return function(c){C.geometries[a]=c;j();F-=1;b.onLoadComplete();m()}}function l(a){return function(b){C.geometries[a]=b}}function m(){b.callbackProgress({totalModels:O,totalTextures:M,loadedModels:O-F,loadedTextures:M-I},C);b.onLoadProgress();F==0&&I==0&&c(C)}var n,
 o,p,w,t,v,x,y,u,z,B,A,E,G,H,L,J,D,K,F,I,O,M,C;D=a.data;H=new THREE.BinaryLoader;K=new THREE.JSONLoader;I=F=0;C={scene:new THREE.Scene,geometries:{},materials:{},textures:{},objects:{},cameras:{},lights:{},fogs:{},triggers:{},empties:{}};a=!1;for(p in D.objects)if(y=D.objects[p],y.meshCollider){a=!0;break}if(a)C.scene.collisions=new THREE.CollisionSystem;if(D.transform){a=D.transform.position;z=D.transform.rotation;var P=D.transform.scale;a&&C.scene.position.set(a[0],a[1],a[2]);z&&C.scene.rotation.set(z[0],
 o,p,w,t,v,x,y,u,z,B,A,E,G,H,L,J,D,K,F,I,O,M,C;D=a.data;H=new THREE.BinaryLoader;K=new THREE.JSONLoader;I=F=0;C={scene:new THREE.Scene,geometries:{},materials:{},textures:{},objects:{},cameras:{},lights:{},fogs:{},triggers:{},empties:{}};a=!1;for(p in D.objects)if(y=D.objects[p],y.meshCollider){a=!0;break}if(a)C.scene.collisions=new THREE.CollisionSystem;if(D.transform){a=D.transform.position;z=D.transform.rotation;var P=D.transform.scale;a&&C.scene.position.set(a[0],a[1],a[2]);z&&C.scene.rotation.set(z[0],
 z[1],z[2]);P&&C.scene.scale.set(P[0],P[1],P[2]);(a||z||P)&&C.scene.updateMatrix()}a=function(){I-=1;m();b.onLoadComplete()};for(t in D.cameras){z=D.cameras[t];if(z.type=="perspective")E=new THREE.Camera(z.fov,z.aspect,z.near,z.far);else if(z.type=="ortho")E=new THREE.Camera,E.projectionMatrix=THREE.Matrix4.makeOrtho(z.left,z.right,z.top,z.bottom,z.near,z.far);u=z.position;z=z.target;E.position.set(u[0],u[1],u[2]);E.target.position.set(z[0],z[1],z[2]);C.cameras[t]=E}for(w in D.lights)t=D.lights[w],
 z[1],z[2]);P&&C.scene.scale.set(P[0],P[1],P[2]);(a||z||P)&&C.scene.updateMatrix()}a=function(){I-=1;m();b.onLoadComplete()};for(t in D.cameras){z=D.cameras[t];if(z.type=="perspective")E=new THREE.Camera(z.fov,z.aspect,z.near,z.far);else if(z.type=="ortho")E=new THREE.Camera,E.projectionMatrix=THREE.Matrix4.makeOrtho(z.left,z.right,z.top,z.bottom,z.near,z.far);u=z.position;z=z.target;E.position.set(u[0],u[1],u[2]);E.target.position.set(z[0],z[1],z[2]);C.cameras[t]=E}for(w in D.lights)t=D.lights[w],
 E=t.color!==void 0?t.color:16777215,z=t.intensity!==void 0?t.intensity:1,t.type=="directional"?(u=t.direction,J=new THREE.DirectionalLight(E,z),J.position.set(u[0],u[1],u[2]),J.position.normalize()):t.type=="point"?(u=t.position,d=t.distance,J=new THREE.PointLight(E,z,d),J.position.set(u[0],u[1],u[2])):t.type=="ambient"&&(J=new THREE.AmbientLight(E)),C.scene.addLight(J),C.lights[w]=J;for(v in D.fogs)w=D.fogs[v],w.type=="linear"?G=new THREE.Fog(0,w.near,w.far):w.type=="exp2"&&(G=new THREE.FogExp2(0,
 E=t.color!==void 0?t.color:16777215,z=t.intensity!==void 0?t.intensity:1,t.type=="directional"?(u=t.direction,J=new THREE.DirectionalLight(E,z),J.position.set(u[0],u[1],u[2]),J.position.normalize()):t.type=="point"?(u=t.position,d=t.distance,J=new THREE.PointLight(E,z,d),J.position.set(u[0],u[1],u[2])):t.type=="ambient"&&(J=new THREE.AmbientLight(E)),C.scene.addLight(J),C.lights[w]=J;for(v in D.fogs)w=D.fogs[v],w.type=="linear"?G=new THREE.Fog(0,w.near,w.far):w.type=="exp2"&&(G=new THREE.FogExp2(0,
 w.density)),z=w.color,G.color.setRGB(z[0],z[1],z[2]),C.fogs[v]=G;if(C.cameras&&D.defaults.camera)C.currentCamera=C.cameras[D.defaults.camera];if(C.fogs&&D.defaults.fog)C.scene.fog=C.fogs[D.defaults.fog];z=D.defaults.bgcolor;C.bgColor=new THREE.Color;C.bgColor.setRGB(z[0],z[1],z[2]);C.bgColorAlpha=D.defaults.bgalpha;for(n in D.geometries)if(v=D.geometries[n],v.type=="bin_mesh"||v.type=="ascii_mesh")F+=1,b.onLoadStart();O=F;for(n in D.geometries)v=D.geometries[n],v.type=="cube"?(A=new THREE.CubeGeometry(v.width,
 w.density)),z=w.color,G.color.setRGB(z[0],z[1],z[2]),C.fogs[v]=G;if(C.cameras&&D.defaults.camera)C.currentCamera=C.cameras[D.defaults.camera];if(C.fogs&&D.defaults.fog)C.scene.fog=C.fogs[D.defaults.fog];z=D.defaults.bgcolor;C.bgColor=new THREE.Color;C.bgColor.setRGB(z[0],z[1],z[2]);C.bgColorAlpha=D.defaults.bgalpha;for(n in D.geometries)if(v=D.geometries[n],v.type=="bin_mesh"||v.type=="ascii_mesh")F+=1,b.onLoadStart();O=F;for(n in D.geometries)v=D.geometries[n],v.type=="cube"?(A=new THREE.CubeGeometry(v.width,
 v.height,v.depth,v.segmentsWidth,v.segmentsHeight,v.segmentsDepth,null,v.flipped,v.sides),C.geometries[n]=A):v.type=="plane"?(A=new THREE.PlaneGeometry(v.width,v.height,v.segmentsWidth,v.segmentsHeight),C.geometries[n]=A):v.type=="sphere"?(A=new THREE.SphereGeometry(v.radius,v.segmentsWidth,v.segmentsHeight),C.geometries[n]=A):v.type=="cylinder"?(A=new THREE.CylinderGeometry(v.numSegs,v.topRad,v.botRad,v.height,v.topOffset,v.botOffset),C.geometries[n]=A):v.type=="torus"?(A=new THREE.TorusGeometry(v.radius,
 v.height,v.depth,v.segmentsWidth,v.segmentsHeight,v.segmentsDepth,null,v.flipped,v.sides),C.geometries[n]=A):v.type=="plane"?(A=new THREE.PlaneGeometry(v.width,v.height,v.segmentsWidth,v.segmentsHeight),C.geometries[n]=A):v.type=="sphere"?(A=new THREE.SphereGeometry(v.radius,v.segmentsWidth,v.segmentsHeight),C.geometries[n]=A):v.type=="cylinder"?(A=new THREE.CylinderGeometry(v.numSegs,v.topRad,v.botRad,v.height,v.topOffset,v.botOffset),C.geometries[n]=A):v.type=="torus"?(A=new THREE.TorusGeometry(v.radius,
-v.tube,v.segmentsR,v.segmentsT),C.geometries[n]=A):v.type=="icosahedron"?(A=new THREE.IcosahedronGeometry(v.subdivisions),C.geometries[n]=A):v.type=="bin_mesh"?H.load({model:e(v.url,D.urlBaseType),callback:k(n)}):v.type=="ascii_mesh"?K.load({model:e(v.url,D.urlBaseType),callback:k(n)}):v.type=="embedded_mesh"&&(v=D.embeds[v.id])&&K.createModel(v,l(n),"");for(x in D.textures)if(n=D.textures[x],n.url instanceof Array){I+=n.url.length;for(H=0;H<n.url.length;H++)b.onLoadStart()}else I+=1,b.onLoadStart();
-M=I;for(x in D.textures){n=D.textures[x];if(n.mapping!=void 0&&THREE[n.mapping]!=void 0)n.mapping=new THREE[n.mapping];if(n.url instanceof Array){H=[];for(var N=0;N<n.url.length;N++)H[N]=e(n.url[N],D.urlBaseType);H=THREE.ImageUtils.loadTextureCube(H,n.mapping,a)}else{H=THREE.ImageUtils.loadTexture(e(n.url,D.urlBaseType),n.mapping,a);if(THREE[n.minFilter]!=void 0)H.minFilter=THREE[n.minFilter];if(THREE[n.magFilter]!=void 0)H.magFilter=THREE[n.magFilter];if(n.repeat){H.repeat.set(n.repeat[0],n.repeat[1]);
+v.tube,v.segmentsR,v.segmentsT),C.geometries[n]=A):v.type=="icosahedron"?(A=new THREE.IcosahedronGeometry(v.subdivisions),C.geometries[n]=A):v.type=="bin_mesh"?H.load({model:g(v.url,D.urlBaseType),callback:k(n)}):v.type=="ascii_mesh"?K.load({model:g(v.url,D.urlBaseType),callback:k(n)}):v.type=="embedded_mesh"&&(v=D.embeds[v.id])&&K.createModel(v,l(n),"");for(x in D.textures)if(n=D.textures[x],n.url instanceof Array){I+=n.url.length;for(H=0;H<n.url.length;H++)b.onLoadStart()}else I+=1,b.onLoadStart();
+M=I;for(x in D.textures){n=D.textures[x];if(n.mapping!=void 0&&THREE[n.mapping]!=void 0)n.mapping=new THREE[n.mapping];if(n.url instanceof Array){H=[];for(var N=0;N<n.url.length;N++)H[N]=g(n.url[N],D.urlBaseType);H=THREE.ImageUtils.loadTextureCube(H,n.mapping,a)}else{H=THREE.ImageUtils.loadTexture(g(n.url,D.urlBaseType),n.mapping,a);if(THREE[n.minFilter]!=void 0)H.minFilter=THREE[n.minFilter];if(THREE[n.magFilter]!=void 0)H.magFilter=THREE[n.magFilter];if(n.repeat){H.repeat.set(n.repeat[0],n.repeat[1]);
 if(n.repeat[0]!=1)H.wrapS=THREE.RepeatWrapping;if(n.repeat[1]!=1)H.wrapT=THREE.RepeatWrapping}n.offset&&H.offset.set(n.offset[0],n.offset[1]);if(n.wrap){K={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping};if(K[n.wrap[0]]!==void 0)H.wrapS=K[n.wrap[0]];if(K[n.wrap[1]]!==void 0)H.wrapT=K[n.wrap[1]]}}C.textures[x]=H}for(o in D.materials){x=D.materials[o];for(B in x.parameters)if(B=="envMap"||B=="map"||B=="lightMap")x.parameters[B]=C.textures[x.parameters[B]];else if(B=="shading")x.parameters[B]=
 if(n.repeat[0]!=1)H.wrapS=THREE.RepeatWrapping;if(n.repeat[1]!=1)H.wrapT=THREE.RepeatWrapping}n.offset&&H.offset.set(n.offset[0],n.offset[1]);if(n.wrap){K={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping};if(K[n.wrap[0]]!==void 0)H.wrapS=K[n.wrap[0]];if(K[n.wrap[1]]!==void 0)H.wrapT=K[n.wrap[1]]}}C.textures[x]=H}for(o in D.materials){x=D.materials[o];for(B in x.parameters)if(B=="envMap"||B=="map"||B=="lightMap")x.parameters[B]=C.textures[x.parameters[B]];else if(B=="shading")x.parameters[B]=
 x.parameters[B]=="flat"?THREE.FlatShading:THREE.SmoothShading;else if(B=="blending")x.parameters[B]=THREE[x.parameters[B]]?THREE[x.parameters[B]]:THREE.NormalBlending;else if(B=="combine")x.parameters[B]=x.parameters[B]=="MixOperation"?THREE.MixOperation:THREE.MultiplyOperation;else if(B=="vertexColors")if(x.parameters[B]=="face")x.parameters[B]=THREE.FaceColors;else if(x.parameters[B])x.parameters[B]=THREE.VertexColors;if(x.parameters.opacity!==void 0&&x.parameters.opacity<1)x.parameters.transparent=
 x.parameters[B]=="flat"?THREE.FlatShading:THREE.SmoothShading;else if(B=="blending")x.parameters[B]=THREE[x.parameters[B]]?THREE[x.parameters[B]]:THREE.NormalBlending;else if(B=="combine")x.parameters[B]=x.parameters[B]=="MixOperation"?THREE.MixOperation:THREE.MultiplyOperation;else if(B=="vertexColors")if(x.parameters[B]=="face")x.parameters[B]=THREE.FaceColors;else if(x.parameters[B])x.parameters[B]=THREE.VertexColors;if(x.parameters.opacity!==void 0&&x.parameters.opacity<1)x.parameters.transparent=
 !0;if(x.parameters.normalMap){n=THREE.ShaderUtils.lib.normal;a=THREE.UniformsUtils.clone(n.uniforms);H=x.parameters.color;K=x.parameters.specular;v=x.parameters.ambient;G=x.parameters.shininess;a.tNormal.texture=C.textures[x.parameters.normalMap];if(x.parameters.normalMapFactor)a.uNormalScale.value=x.parameters.normalMapFactor;if(x.parameters.map)a.tDiffuse.texture=x.parameters.map,a.enableDiffuse.value=!0;if(x.parameters.lightMap)a.tAO.texture=x.parameters.lightMap,a.enableAO.value=!0;if(x.parameters.specularMap)a.tSpecular.texture=
 !0;if(x.parameters.normalMap){n=THREE.ShaderUtils.lib.normal;a=THREE.UniformsUtils.clone(n.uniforms);H=x.parameters.color;K=x.parameters.specular;v=x.parameters.ambient;G=x.parameters.shininess;a.tNormal.texture=C.textures[x.parameters.normalMap];if(x.parameters.normalMapFactor)a.uNormalScale.value=x.parameters.normalMapFactor;if(x.parameters.map)a.tDiffuse.texture=x.parameters.map,a.enableDiffuse.value=!0;if(x.parameters.lightMap)a.tAO.texture=x.parameters.lightMap,a.enableAO.value=!0;if(x.parameters.specularMap)a.tSpecular.texture=
-C.textures[x.parameters.specularMap],a.enableSpecular.value=!0;a.uDiffuseColor.value.setHex(H);a.uSpecularColor.value.setHex(K);a.uAmbientColor.value.setHex(v);a.uShininess.value=G;if(x.parameters.opacity)a.uOpacity.value=x.parameters.opacity;x=new THREE.MeshShaderMaterial({fragmentShader:n.fragmentShader,vertexShader:n.vertexShader,uniforms:a,lights:!0,fog:!0})}else x=new THREE[x.type](x.parameters);C.materials[o]=x}g();b.callbackSync(C)}}};
+C.textures[x.parameters.specularMap],a.enableSpecular.value=!0;a.uDiffuseColor.value.setHex(H);a.uSpecularColor.value.setHex(K);a.uAmbientColor.value.setHex(v);a.uShininess.value=G;if(x.parameters.opacity)a.uOpacity.value=x.parameters.opacity;x=new THREE.MeshShaderMaterial({fragmentShader:n.fragmentShader,vertexShader:n.vertexShader,uniforms:a,lights:!0,fog:!0})}else x=new THREE[x.type](x.parameters);C.materials[o]=x}j();b.callbackSync(C)}}};
 THREE.MarchingCubes=function(a,c){THREE.Object3D.call(this);this.materials=c instanceof Array?c:[c];this.init=function(a){this.isolation=80;this.size=a;this.size2=this.size*this.size;this.size3=this.size2*this.size;this.halfsize=this.size/2;this.delta=2/this.size;this.yd=this.size;this.zd=this.size2;this.field=new Float32Array(this.size3);this.normal_cache=new Float32Array(this.size3*3);this.vlist=new Float32Array(36);this.nlist=new Float32Array(36);this.firstDraw=!0;this.maxCount=4096;this.count=
 THREE.MarchingCubes=function(a,c){THREE.Object3D.call(this);this.materials=c instanceof Array?c:[c];this.init=function(a){this.isolation=80;this.size=a;this.size2=this.size*this.size;this.size3=this.size2*this.size;this.halfsize=this.size/2;this.delta=2/this.size;this.yd=this.size;this.zd=this.size2;this.field=new Float32Array(this.size3);this.normal_cache=new Float32Array(this.size3*3);this.vlist=new Float32Array(36);this.nlist=new Float32Array(36);this.firstDraw=!0;this.maxCount=4096;this.count=
 0;this.hasNormal=this.hasPos=!1;this.positionArray=new Float32Array(this.maxCount*3);this.normalArray=new Float32Array(this.maxCount*3)};this.lerp=function(a,c,f){return a+(c-a)*f};this.VIntX=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j+e*this.delta;c[h+1]=k;c[h+2]=l;f[h]=this.lerp(m[a],m[a+3],e);f[h+1]=this.lerp(m[a+1],m[a+4],e);f[h+2]=this.lerp(m[a+2],m[a+5],e)};this.VIntY=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j;c[h+1]=k+e*this.delta;c[h+
 0;this.hasNormal=this.hasPos=!1;this.positionArray=new Float32Array(this.maxCount*3);this.normalArray=new Float32Array(this.maxCount*3)};this.lerp=function(a,c,f){return a+(c-a)*f};this.VIntX=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j+e*this.delta;c[h+1]=k;c[h+2]=l;f[h]=this.lerp(m[a],m[a+3],e);f[h+1]=this.lerp(m[a+1],m[a+4],e);f[h+2]=this.lerp(m[a+2],m[a+5],e)};this.VIntY=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j;c[h+1]=k+e*this.delta;c[h+
 2]=l;c=a+this.yd*3;f[h]=this.lerp(m[a],m[c],e);f[h+1]=this.lerp(m[a+1],m[c+1],e);f[h+2]=this.lerp(m[a+2],m[c+2],e)};this.VIntZ=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j;c[h+1]=k;c[h+2]=l+e*this.delta;c=a+this.zd*3;f[h]=this.lerp(m[a],m[c],e);f[h+1]=this.lerp(m[a+1],m[c+1],e);f[h+2]=this.lerp(m[a+2],m[c+2],e)};this.compNorm=function(a){var c=a*3;this.normal_cache[c]==0&&(this.normal_cache[c]=this.field[a-1]-this.field[a+1],this.normal_cache[c+1]=this.field[a-this.yd]-this.field[a+
 2]=l;c=a+this.yd*3;f[h]=this.lerp(m[a],m[c],e);f[h+1]=this.lerp(m[a+1],m[c+1],e);f[h+2]=this.lerp(m[a+2],m[c+2],e)};this.VIntZ=function(a,c,f,h,e,j,k,l,m,n){e=(e-m)/(n-m);m=this.normal_cache;c[h]=j;c[h+1]=k;c[h+2]=l+e*this.delta;c=a+this.zd*3;f[h]=this.lerp(m[a],m[c],e);f[h+1]=this.lerp(m[a+1],m[c+1],e);f[h+2]=this.lerp(m[a+2],m[c+2],e)};this.compNorm=function(a){var c=a*3;this.normal_cache[c]==0&&(this.normal_cache[c]=this.field[a-1]-this.field[a+1],this.normal_cache[c+1]=this.field[a-this.yd]-this.field[a+

+ 50 - 15
examples/webgl_geometry_shapes.html

@@ -71,7 +71,9 @@
 				parent.position.y = 50;
 				parent.position.y = 50;
 				scene.addChild( parent );
 				scene.addChild( parent );
 
 
-				function addGeometry( geometry, points, color, x, y, z, rx, ry, rz, s ) {
+				function addGeometry( geometry, points, spacedPoints, color, x, y, z, rx, ry, rz, s ) {
+
+					// 3d shape
 
 
 					var mesh = new THREE.Mesh( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true } ) ] );
 					var mesh = new THREE.Mesh( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true } ) ] );
 					mesh.position.set( x, y, z - 75 );
 					mesh.position.set( x, y, z - 75 );
@@ -79,29 +81,51 @@
 					mesh.scale.set( s, s, s );
 					mesh.scale.set( s, s, s );
 					parent.addChild( mesh );
 					parent.addChild( mesh );
 
 
+					// solid line
+
 					var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, linewidth: 2 } ) );
 					var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, linewidth: 2 } ) );
 					line.position.set( x, y, z + 25 );
 					line.position.set( x, y, z + 25 );
 					line.rotation.set( rx, ry, rz );
 					line.rotation.set( rx, ry, rz );
 					line.scale.set( s, s, s );
 					line.scale.set( s, s, s );
 					parent.addChild( line );
 					parent.addChild( line );
 
 
-					var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
+					// transparent line from real points
+
+					var line = new THREE.Line( points, new THREE.LineBasicMaterial( { color: color, opacity: 0.5 } ) );
 					line.position.set( x, y, z + 75 );
 					line.position.set( x, y, z + 75 );
 					line.rotation.set( rx, ry, rz );
 					line.rotation.set( rx, ry, rz );
 					line.scale.set( s, s, s );
 					line.scale.set( s, s, s );
 					parent.addChild( line );
 					parent.addChild( line );
 
 
+					// vertices from real points
+
 					var pgeo = THREE.GeometryUtils.clone( points );
 					var pgeo = THREE.GeometryUtils.clone( points );
-					var particles = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2,opacity: 0.5 } ) );
+					var particles = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.75 } ) );
 					particles.position.set( x, y, z + 75 );
 					particles.position.set( x, y, z + 75 );
 					particles.rotation.set( rx, ry, rz );
 					particles.rotation.set( rx, ry, rz );
 					particles.scale.set( s, s, s );
 					particles.scale.set( s, s, s );
 					parent.addChild( particles );
 					parent.addChild( particles );
 
 
+					// transparent line from equidistance sampled points
+
+					var line = new THREE.Line( spacedPoints, new THREE.LineBasicMaterial( { color: color, opacity: 0.2 } ) );
+					line.position.set( x, y, z + 100 );
+					line.rotation.set( rx, ry, rz );
+					line.scale.set( s, s, s );
+					parent.addChild( line );
+
+					// equidistance sampled points
+
+					var pgeo = THREE.GeometryUtils.clone( spacedPoints );
+					var particles2 = new THREE.ParticleSystem( pgeo, new THREE.ParticleBasicMaterial( { color: color, size: 2, opacity: 0.5 } ) );
+					particles2.position.set( x, y, z + 100 );
+					particles2.rotation.set( rx, ry, rz );
+					particles2.scale.set( s, s, s );
+					parent.addChild( particles2 );
+
 				}
 				}
 
 
-				var lineDivisions = 12, lineMaterial = new THREE.LineBasicMaterial( { color: 0xff0000 } );
-				var extrudeSettings = {	amount: 20,  bevelEnabled: true, bevelSegments: 2, steps: 2 }; //amount: 40, steps: 2
+				var extrudeSettings = {	amount: 20,  bevelEnabled: true, bevelSegments: 2, steps: 2 }; // amount: 40, steps: 2
 
 
 				// California
 				// California
 
 
@@ -131,8 +155,10 @@
 				californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
 				californiaPts.push( new THREE.Vector2 ( 610, 320 ) );
 
 
 				var californiaShape = new THREE.Shape( californiaPts );
 				var californiaShape = new THREE.Shape( californiaPts );
+
 				var california3d = new THREE.ExtrudeGeometry( californiaShape, { amount: 20	} );
 				var california3d = new THREE.ExtrudeGeometry( californiaShape, { amount: 20	} );
 				var californiaPoints = californiaShape.createPointsGeometry();
 				var californiaPoints = californiaShape.createPointsGeometry();
+				var californiaSpacedPoints = californiaShape.createSpacedPointsGeometry( 100 );
 
 
 				// Triangle
 				// Triangle
 
 
@@ -144,6 +170,7 @@
 
 
 				var triangle3d = triangleShape.extrude( extrudeSettings );
 				var triangle3d = triangleShape.extrude( extrudeSettings );
 				var trianglePoints = triangleShape.createPointsGeometry();
 				var trianglePoints = triangleShape.createPointsGeometry();
+				var triangleSpacedPoints = triangleShape.createSpacedPointsGeometry();
 
 
 
 
 				// Heart
 				// Heart
@@ -162,6 +189,7 @@
 
 
 				var heart3d = heartShape.extrude( extrudeSettings );
 				var heart3d = heartShape.extrude( extrudeSettings );
 				var heartPoints = heartShape.createPointsGeometry();
 				var heartPoints = heartShape.createPointsGeometry();
+				var heartSpacedPoints = heartShape.createSpacedPointsGeometry();
 
 
 				//heartShape.debug( document.getElementById("debug") );
 				//heartShape.debug( document.getElementById("debug") );
 
 
@@ -178,6 +206,7 @@
 
 
 				var square3d = squareShape.extrude( extrudeSettings );
 				var square3d = squareShape.extrude( extrudeSettings );
 				var squarePoints = squareShape.createPointsGeometry();
 				var squarePoints = squareShape.createPointsGeometry();
+				var squareSpacedPoints = squareShape.createSpacedPointsGeometry();
 
 
 				// Rectangle
 				// Rectangle
 
 
@@ -192,6 +221,7 @@
 
 
 				var rect3d = rectShape.extrude( extrudeSettings );
 				var rect3d = rectShape.extrude( extrudeSettings );
 				var rectPoints = rectShape.createPointsGeometry();
 				var rectPoints = rectShape.createPointsGeometry();
+				var rectSpacedPoints = rectShape.createSpacedPointsGeometry();
 
 
 				// Rounded rectangle
 				// Rounded rectangle
 
 
@@ -200,6 +230,7 @@
 
 
 				var roundedRect3d = roundedRectShape.extrude( extrudeSettings );
 				var roundedRect3d = roundedRectShape.extrude( extrudeSettings );
 				var roundedRectPoints = roundedRectShape.createPointsGeometry();
 				var roundedRectPoints = roundedRectShape.createPointsGeometry();
+				var roundedRectSpacedPoints = roundedRectShape.createSpacedPointsGeometry();
 
 
 				function roundedRect( ctx, x, y, width, height, radius ){
 				function roundedRect( ctx, x, y, width, height, radius ){
 
 
@@ -227,6 +258,7 @@
 
 
 				var circle3d = circleShape.extrude( extrudeSettings );
 				var circle3d = circleShape.extrude( extrudeSettings );
 				var circlePoints = circleShape.createPointsGeometry();
 				var circlePoints = circleShape.createPointsGeometry();
+				var circleSpacedPoints = circleShape.createSpacedPointsGeometry();
 
 
 				// Fish
 				// Fish
 
 
@@ -243,6 +275,7 @@
 
 
 				var fish3d = fishShape.extrude( extrudeSettings );
 				var fish3d = fishShape.extrude( extrudeSettings );
 				var fishPoints = fishShape.createPointsGeometry();
 				var fishPoints = fishShape.createPointsGeometry();
+				var fishSpacedPoints = fishShape.createSpacedPointsGeometry();
 
 
 				// Arc circle
 				// Arc circle
 
 
@@ -257,6 +290,7 @@
 
 
 				var arc3d = arcShape.extrude( extrudeSettings );
 				var arc3d = arcShape.extrude( extrudeSettings );
 				var arcPoints = arcShape.createPointsGeometry();
 				var arcPoints = arcShape.createPointsGeometry();
+				var arcSpacedPoints = arcShape.createSpacedPointsGeometry();
 
 
 				// Spline shape + path extrusion
 				// Spline shape + path extrusion
 
 
@@ -284,16 +318,17 @@
 
 
 				var splineShape3d = splineShape.extrude( extrudeSettings );
 				var splineShape3d = splineShape.extrude( extrudeSettings );
 				var splinePoints = splineShape.createPointsGeometry( );
 				var splinePoints = splineShape.createPointsGeometry( );
-
-				addGeometry( california3d, californiaPoints,	0xffaa00, -300, -100, 0,     0, 0, 0, 0.25 );
-				addGeometry( triangle3d, trianglePoints,		0xffee00, -180,    0, 0,     0, 0, 0, 1 );
-				addGeometry( roundedRect3d, roundedRectPoints, 	0x005500, -150,  150, 0,     0, 0, 0, 1 );
-				addGeometry( square3d, squarePoints,			0x0055ff,  150,  100, 0,     0, 0, 0, 1 );
-				addGeometry( heart3d, heartPoints,				0xff1100,    0,  100, 0,   3.14, 0, 0, 1 );
-				addGeometry( circle3d, circlePoints,			0x00ff11,  120,  250, 0,     0, 0, 0, 1 );
-				addGeometry( fish3d, fishPoints,				0x222222,  -50,  200, 0,     0, 0, 0, 1 );
-				addGeometry( splineShape3d, splinePoints, 		0x888888,  -50,  -100, -50,  0, 0, 0, 0.2 );
-				addGeometry( arc3d, arcPoints,					0xbb4422,  150,    0, 0,     0, 0, 0, 1 );
+				var splineSpacedPoints = splineShape.createSpacedPointsGeometry( );
+
+				addGeometry( california3d, californiaPoints, californiaSpacedPoints,	0xffaa00, -300, -100, 0,     0, 0, 0, 0.25 );
+				addGeometry( triangle3d, trianglePoints, triangleSpacedPoints, 			0xffee00, -180,    0, 0,     0, 0, 0, 1 );
+				addGeometry( roundedRect3d, roundedRectPoints, roundedRectSpacedPoints,	0x005500, -150,  150, 0,     0, 0, 0, 1 );
+				addGeometry( square3d, squarePoints, squareSpacedPoints,				0x0055ff,  150,  100, 0,     0, 0, 0, 1 );
+				addGeometry( heart3d, heartPoints, heartSpacedPoints,					0xff1100,    0,  100, 0,   3.14, 0, 0, 1 );
+				addGeometry( circle3d, circlePoints, circleSpacedPoints,				0x00ff11,  120,  250, 0,     0, 0, 0, 1 );
+				addGeometry( fish3d, fishPoints, fishSpacedPoints,						0x222222,  -50,  200, 0,     0, 0, 0, 1 );
+				addGeometry( splineShape3d, splinePoints, splineSpacedPoints,			0x888888,  -50,  -100, -50,  0, 0, 0, 0.2 );
+				addGeometry( arc3d, arcPoints, arcSpacedPoints,							0xbb4422,  150,    0, 0,     0, 0, 0, 1 );
 
 
 				//
 				//
 
 

+ 29 - 10
src/extras/geometries/Path.js

@@ -165,21 +165,27 @@ THREE.Path.prototype.arc = function ( aX, aY, aRadius,
 */
 */
 
 
 
 
-THREE.Path.prototype.getSpacedPoints = function ( divisions ) {
+THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
 
 
 	if ( !divisions ) divisions = 40;
 	if ( !divisions ) divisions = 40;
 
 
-	var pts = [];
+	var points = [];
+
 	for ( var i = 0; i < divisions; i++ ) {
 	for ( var i = 0; i < divisions; i++ ) {
 
 
-		pts.push( this.getPoint( i / divisions ) );
+		points.push( this.getPoint( i / divisions ) );
 
 
-		//if(!this.getPoint(i/divisions)) throw "DIE";
+		//if( !this.getPoint( i / divisions ) ) throw "DIE";
 
 
 	}
 	}
 
 
-	//console.log(pts);
-	return pts;
+	if ( closedPath ) {
+
+		points.push( points[ 0 ] );
+
+	}
+
+	return points;
 
 
 };
 };
 
 
@@ -481,17 +487,31 @@ THREE.Path.prototype.getLength = function() {
 };
 };
 
 
 
 
-/// Returns geometry created from path points (for Line or ParticleSystem objects)
+/// Generate geometry from path points (for Line or ParticleSystem objects)
 
 
 THREE.Path.prototype.createPointsGeometry = function( divisions ) {
 THREE.Path.prototype.createPointsGeometry = function( divisions ) {
 
 
     var pts = this.getPoints( divisions, true );
     var pts = this.getPoints( divisions, true );
+	return this.createGeometry( pts );
+
+};
+
+// Generate geometry from equidistance sampling along the path
+
+THREE.Path.prototype.createSpacedPointsGeometry = function( divisions ) {
+
+    var pts = this.getSpacedPoints( divisions, true );
+	return this.createGeometry( pts );
+
+};
+
+THREE.Path.prototype.createGeometry = function( points ) {
 
 
 	var geometry = new THREE.Geometry();
 	var geometry = new THREE.Geometry();
 
 
-    for( var i = 0; i < pts.length; i ++ ) {
+    for( var i = 0; i < points.length; i ++ ) {
 
 
-        geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( pts[ i ].x, pts[ i ].y, 0 ) ) );
+        geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( points[ i ].x, points[ i ].y, 0 ) ) );
 
 
     }
     }
 
 
@@ -500,7 +520,6 @@ THREE.Path.prototype.createPointsGeometry = function( divisions ) {
 };
 };
 
 
 
 
-
 // ALL THINGS BELOW TO BE REFACTORED
 // ALL THINGS BELOW TO BE REFACTORED
 // QN: Transform final pts or transform ACTIONS or add transform filters?
 // QN: Transform final pts or transform ACTIONS or add transform filters?