-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathjsprimmesher.min.js
3 lines (3 loc) · 37.5 KB
/
jsprimmesher.min.js
1
2
3
"use strict";
//JSPrimMesher Copyright(c)2013 Teravus & Dahlia BSD-3Clause https://github.com/Teravus/JSPrimMesher
var JSPrimMesher=JSPrimMesher||{REVISION:"2"};JSPrimMesher.Angle=function(b,a,c){this.angle=b||0;this.X=a||0;this.Y=c||0};JSPrimMesher.Angle.prototype={constructor:JSPrimMesher.Angle};JSPrimMesher.AngleList=function(){this.iX=0;this.iY=0;this.angles3=new Array();this.normals3=new Array();this.angles4=new Array();this.normals4=new Array();this.initialized=false;this.angles24=new Array();this.angles=new Array();this.normals=new Array();this.angles3[0]=new JSPrimMesher.Angle(0,1,0);this.angles3[1]=new JSPrimMesher.Angle(0.3333333333333333,-0.5,0.8660254037844387);this.angles3[2]=new JSPrimMesher.Angle(0.6666666666666666,-0.5,-0.8660254037844384);this.angles3[3]=new JSPrimMesher.Angle(1,1,0);this.normals3[0]=new JSPrimMesher.Coord(0.25,0.4330127019,0).Normalize();this.normals3[1]=new JSPrimMesher.Coord(-0.5,0,0).Normalize();this.normals3[2]=new JSPrimMesher.Coord(0.25,-0.4330127019,0).Normalize();this.normals3[3]=new JSPrimMesher.Coord(0.25,0.4330127019,0).Normalize();this.angles4[0]=new JSPrimMesher.Angle(0,1,0);this.angles4[1]=new JSPrimMesher.Angle(0.25,0,1);this.angles4[2]=new JSPrimMesher.Angle(0.5,-1,0);this.angles4[3]=new JSPrimMesher.Angle(0.75,0,-1);this.angles4[4]=new JSPrimMesher.Angle(1,1,0);this.normals4[0]=new JSPrimMesher.Coord(0.5,0.5,0).Normalize();this.normals4[1]=new JSPrimMesher.Coord(-0.5,0.5,0).Normalize();this.normals4[2]=new JSPrimMesher.Coord(-0.5,-0.5,0).Normalize();this.normals4[3]=new JSPrimMesher.Coord(0.5,-0.5,0).Normalize();this.normals4[4]=new JSPrimMesher.Coord(0.5,0.5,0).Normalize();this.angles24[0]=new JSPrimMesher.Angle(0,1,0);this.angles24[1]=new JSPrimMesher.Angle(0.041666666666666664,0.9659258262890683,0.25881904510252074);this.angles24[2]=new JSPrimMesher.Angle(0.08333333333333333,0.8660254037844387,0.5);this.angles24[3]=new JSPrimMesher.Angle(0.125,0.7071067811865476,0.7071067811865475);this.angles24[4]=new JSPrimMesher.Angle(0.16666666666666666,0.5,0.8660254037844386);this.angles24[5]=new JSPrimMesher.Angle(0.20833333333333331,0.25881904510252096,0.9659258262890682);this.angles24[6]=new JSPrimMesher.Angle(0.25,0,1);this.angles24[7]=new JSPrimMesher.Angle(0.29166666666666663,-0.25881904510252063,0.9659258262890683);this.angles24[8]=new JSPrimMesher.Angle(0.3333333333333333,-0.5,0.8660254037844387);this.angles24[9]=new JSPrimMesher.Angle(0.375,-0.7071067811865475,0.7071067811865476);this.angles24[10]=new JSPrimMesher.Angle(0.41666666666666663,-0.8660254037844385,0.5);this.angles24[11]=new JSPrimMesher.Angle(0.4583333333333333,-0.9659258262890682,0.258819045102521);this.angles24[12]=new JSPrimMesher.Angle(0.5,-1,0);this.angles24[13]=new JSPrimMesher.Angle(0.5416666666666666,-0.9659258262890684,-0.25881904510252035);this.angles24[14]=new JSPrimMesher.Angle(0.5833333333333333,-0.8660254037844388,-0.5);this.angles24[15]=new JSPrimMesher.Angle(0.6249999999999999,-0.7071067811865479,-0.7071067811865471);this.angles24[16]=new JSPrimMesher.Angle(0.6666666666666666,-0.5,-0.8660254037844384);this.angles24[17]=new JSPrimMesher.Angle(0.7083333333333333,-0.2588190451025215,-0.9659258262890681);this.angles24[18]=new JSPrimMesher.Angle(0.75,0,-1);this.angles24[19]=new JSPrimMesher.Angle(0.7916666666666666,0.2588190451025203,-0.9659258262890684);this.angles24[20]=new JSPrimMesher.Angle(0.8333333333333333,0.5,-0.866025403784439);this.angles24[21]=new JSPrimMesher.Angle(0.875,0.7071067811865474,-0.7071067811865477);this.angles24[22]=new JSPrimMesher.Angle(0.9166666666666666,0.8660254037844384,-0.5);this.angles24[23]=new JSPrimMesher.Angle(0.9583333333333333,0.9659258262890681,-0.25881904510252157);this.angles24[24]=new JSPrimMesher.Angle(1,1,0);this.initialized=true};JSPrimMesher.AngleList.prototype={constructor:JSPrimMesher.AngleList,interpolatePoints:function(b,d,c){var a=(b-d.angle)/(c.angle-d.angle);return new JSPrimMesher.Angle(b,d.X+a*(c.X-d.X),d.Y+a*(c.Y-d.Y))},intersection:function(d,j,c,i,a,h,k,g){var f=(g-h)*(c-d)-(k-a)*(i-j);var e=(k-a)*(j-h)-(g-h)*(d-a);if(f!=0){var b=e/f;this.iX=(d+b*(c-d));this.iY=(j+b*(i-j))}},makeAngles:function(q,o,r){this.angles=new Array();this.normals=new Array();var m=Math.PI*2;var l=1/m;if(q<1){throw"number of sides not greater then zero"}if(r<=o){throw"stopAngle not greater then startAngle"}if((q==3)||(q==4)||(q=24)){o*=l;r*=l;var e=new Array();if(q==3){e=this.angles3}else{if(q==4){e=this.angles4}else{e=this.angles24}}var d=~~(o*q);var h=e.length-1;if(r<1){h=(~~(r*q)+1)}if(h==d){h++}for(var s=d;s<h+1;s++){this.angles.push(e[s]);if(q==3){this.normals.push(this.normals3[s])}else{if(q==4){this.normals.push(this.normals4[s])}}}if(o>0){this.angles[0]=this.interpolatePoints(o,this.angles[0],this.angles[1])}if(r<1){var n=this.angles.length-1;this.angles[n]=this.interpolatePoints(r,this.angles[n-1],this.angles[n])}}else{var b=m/q;var i=~~(o/b);var p=b*i;var f=i;var j=r;if(r<m){j=b*(~~(r/b)+1);if(j<r){j+=b}if(j>m){j=m}}while(p<=j){var k=new JSPrimMesher.Angle(p,Math.cos(p),Math.sin(p));this.angles.push(k);f+=1;p=b*f}if(o>this.angles[0].angle){this.intersection(this.angles[0].X,this.angles[0].Y,this.angles[1].X,this.angles[1].Y,0,0,Math.cos(o),Math.sin(o));var c=new JSPrimMesher.Angle(o,this.iX,this.iY);this.angles[0]=c}var g=this.angles.length-1;if(r<this.angles[g].angle){this.intersection(this.angles[g-1].X,this.angles[g-1].Y,this.angles[g].X,this.angles[g].Y,0,0,Math.cos(r),Math.sin(r));var a=new JSPrimMesher.Angle(r,this.iX,this.iY);this.angles[g]=a}}}};JSPrimMesher.Coord=function(a,c,b){this.X=a||0;this.Y=c||0;this.Z=b||0};JSPrimMesher.Coord.prototype={constructor:JSPrimMesher.Coord,Length:function(){return Math.sqrt(this.X*this.X+this.Y*this.Y+this.Z*this.Z)},Invert:function(){this.X=-this.X;this.Y=-this.Y;this.Z=-this.Z;return new JSPrimMesher.Coord(this.X,this.Y,this.Z)},Normalize:function(){var a=this.Length();var e=this.X;var d=this.Y;var b=this.Z;if(a>1e-7){var c=1/a;e*=c;d*=c;b*=c}else{e=0;d=0;b=0}return new JSPrimMesher.Coord(e,d,b)},ToString:function(){return""+this.X+" "+this.Y+" "+this.Z+""},Copy:function(){return new JSPrimMesher.Coord(this.X,this.Y,this.Z)}};JSPrimMesher.Coord.Cross=function(b,a){return new JSPrimMesher.Coord(b.Y*a.Z-a.Y*b.Z,b.Z*a.X-a.Z*b.X,b.X*a.Y-a.X*b.Y)};JSPrimMesher.Coord.Add=function(c,b){return new JSPrimMesher.Coord(c.X+b.X,c.Y+b.Y,c.Z+b.Z)};JSPrimMesher.Coord.Mul=function(b,a){return new JSPrimMesher.Coord(b.X*a.X,b.Y*a.Y,b.Z*a.Z)};JSPrimMesher.Coord.Dot=function(b,a){return b.X*a.X+b.Y*a.Y+b.Z*a.Z};JSPrimMesher.Coord.MulQuat=function(a,c){var b=new JSPrimMesher.Coord(0,0,0);b.X=c.W*c.W*a.X+2*c.Y*c.W*a.Z-2*c.Z*c.W*a.Y+c.X*c.X*a.X+2*c.Y*c.X*a.Y+2*c.Z*c.X*a.Z-c.Z*c.Z*a.X-c.Y*c.Y*a.X;b.Y=2*c.X*c.Y*a.X+c.Y*c.Y*a.Y+2*c.Z*c.Y*a.Z+2*c.W*c.Z*a.X-c.Z*c.Z*a.Y+c.W*c.W*a.Y-2*c.X*c.W*a.Z-c.X*c.X*a.Y;b.Z=2*c.X*c.Z*a.X+2*c.Y*c.Z*a.Y+c.Z*c.Z*a.Z-2*c.W*c.Y*a.X-c.Y*c.Y*a.Z+2*c.W*c.X*a.Y-c.X*c.X*a.Z+c.W*c.W*a.Z;return b};JSPrimMesher.Face=function(i,h,g,f,e,d,c,b,a){this.primFace=0;this.v1=i||0;this.v2=h||0;this.v3=g||0;this.n1=f||0;this.n2=e||0;this.n3=d||0;this.uv1=c||0;this.uv2=b||0;this.uv3=a||0};JSPrimMesher.Face.prototype={constructor:JSPrimMesher.Face,SurfaceNormal:function(f){var e=f[this.v1];var d=f[this.v2];var c=f[this.v3];var b=new JSPrimMesher.Coord(d.X-e.X,d.Y-e.Y,d.Z-e.Z);var a=new JSPrimMesher.Coord(c.X-e.X,c.Y-e.Y,c.Z-e.Z);return JSPrimMesher.Coord.Cross(b,a).Normalize()},Copy:function(){return new JSPrimMesher.Face(this.v1,this.v2,this.v3,this.n1,this.n2,this.n3,this.uv1,this.uv2,this.uv3)}};JSPrimMesher.Path=function(){this.pathNodes=new Array();this.twistBegin=0;this.twistEnd=0;this.topShearX=0;this.topShearY=0;this.pathCutBegin=0;this.pathCutEnd=1;this.dimpleBegin=0;this.dimpleEnd=1;this.skew=0;this.holeSizeX=1;this.holeSizeY=0.25;this.taperX=0;this.taperY=0;this.radius=0;this.revolutions=1;this.stepsPerRevolution=24;this.twoPi=2*Math.PI};JSPrimMesher.Path.prototype={constructor:JSPrimMesher.Path,Create:function(a,w){if(a==JSPrimMesher.PathType.Linear||a==JSPrimMesher.PathType.Flexible){var l=0;var f=this.pathCutEnd-this.pathCutBegin;var g=this.twistEnd-this.twistBegin;var o=Math.abs(g);if(o>0.01){w+=~~(o*3.66)}var j=-0.5;var h=f/w;var s=h*0.999999;var C=this.topShearX*this.pathCutBegin;var p=this.topShearY*this.pathCutBegin;var n=j;var i=this.topShearX*f/w;var E=this.topShearY*f/w;var A=this.pathCutBegin;n+=A;var r=false;while(!r){var c=new JSPrimMesher.PathNode();c.xScale=1;if(this.taperX==0){c.xScale=1}else{if(this.taperX>0){c.xScale=1-A*this.taperX}else{c.xScale=1+(1-A)*this.taperX}}c.yScale=1;if(this.taperY==0){c.yScale=1}else{if(this.taperY>0){c.yScale=1-A*this.taperY}else{c.yScale=1+(1-A)*this.taperY}}var b=this.twistBegin+g*A;c.rotation=JSPrimMesher.Quat.QuatAxisAngle(new JSPrimMesher.Coord(0,0,1),b);c.position=new JSPrimMesher.Coord(C,p,n);c.percentOfPath=A;this.pathNodes.push(c);if(l<w){l+=1;A+=s;C+=i;p+=E;n+=h;if(A>this.pathCutEnd){r=true}}else{r=true}}}else{var g=this.twistEnd-this.twistBegin;var o=Math.abs(g);if(o>0.01){if(o>Math.PI*1.5){w*=2}if(o>Math.PI*3){w*=2}}var q=this.holeSizeY*0.5;var x=this.pathCutEnd-this.pathCutBegin;var d=this.skew*2*x;var m=this.pathCutBegin*2*this.skew-this.skew;var u=this.topShearX*(0.25+0.5*(0.5-this.holeSizeY));var B=1+Math.abs(this.topShearY)*0.25;var v=(this.twoPi*this.pathCutBegin*this.revolutions)-this.topShearY*0.9;var t=(this.twoPi*this.pathCutEnd*this.revolutions)-this.topShearY*0.9;var h=this.twoPi/this.stepsPerRevolution;var l=~~(v/h);var y=v;var r=false;while(!r){var c=new JSPrimMesher.PathNode();var D=(1-Math.abs(this.skew))*this.holeSizeX;var e=this.holeSizeY;var A=y/(this.twoPi*this.revolutions);var k=(y-v)/(t-v);if(this.taperX>0.01){D*=1-A*this.taperX}else{if(this.taperX<-0.01){D*=1+(1-A)*this.taperX}}if(this.taperY>0.01){e*=1-A*this.taperY}else{if(this.taperY<-0.01){e*=1+(1-A)*this.taperY}}c.xScale=D;c.yScale=e;var z=1;if(this.radius>0.001){z=1-this.radius*A}else{if(this.radius<0.001){z=1+this.radius*(1-A)}}var b=this.twistBegin+g*A;var C=0.5*(m+d*k);C+=Math.sin(y)*u;var p=B*Math.cos(y)*(0.5-q)*z;var n=Math.sin(y+this.topShearY)*(0.5-q)*z;c.position=new JSPrimMesher.Coord(C,p,n);c.rotation=JSPrimMesher.Quat.QuatAxisAngle(new JSPrimMesher.Coord(1,0,0),y+this.topShearY);if(g!=0||this.twistBegin!=0){c.rotation=JSPrimMesher.Quat.Mul(c.rotation,JSPrimMesher.Quat.QuatAxisAngle(new JSPrimMesher.Coord(0,0,1),b))}c.percentOfPath=A;this.pathNodes.push(c);if(y>=t-0.01){r=true}else{l+=1;y=h*l;if(y>t){y=t}}}}}};JSPrimMesher.PathNode=function(){this.position=new JSPrimMesher.Coord();this.rotation=new JSPrimMesher.Quat(0,0,0,1);this.xScale=0;this.yScale=0;this.percentOfPath=0};JSPrimMesher.PathNode.prototype={constructor:JSPrimMesher.PathNode};JSPrimMesher.PathType={Linear:0,Circular:1,Flexible:2};JSPrimMesher.PrimMesh=function(e,c,b,d,a){this.errorMessage="";this.twoPi=2*Math.PI;this.coords=new Array();this.normals=new Array();this.faces=new Array();this.viewerFaces=new Array();this.sides=4;this.hollowSides=4;this.profileStart=0;this.profileEnd=1;this.hollow=0;this.twistBegin=0;this.twistEnd=0;this.topShearX=0;this.topShearY=0;this.pathCutBegin=0;this.pathCutEnd=1;this.dimpleBegin=0;this.dimpleEnd=1;this.skew=0;this.holeSizeX=1;this.holeSizeY=0.25;this.taperX=0;this.taperY=0;this.radius=0;this.revolutions=1;this.stepsPerRevolution=24;this.profileOuterFaceNumber=-1;this.profileHollowFaceNumber=-1;this.hasProfileCut=false;this.hasHollow=false;this.calcVertexNormals=false;this.normalsProcessed=false;this.viewerMode=false;this.sphereMode=false;this.numPrimFaces=0;this.coords=new Array();this.faces=new Array();this.sides=e||4;this.profileStart=c||0;this.profileEnd=b||1;this.hollow=d||0;this.hollowSides=a||4;if(e<3){this.sides=3}if(a<3){this.hollowSides=3}if(c<0){this.profileStart=0}if(b>1){this.profileEnd=1}if(b<0.02){this.profileEnd=0.02}if(c>=b){this.profileStart=this.profileEnd-0.02}if(d>0.99){this.hollow=0.99}if(d<0){this.hollow=0}this.hasProfileCut=(this.profileStart>0||this.profileEnd<1);this.hasHollow=(this.hollow>0.001)};JSPrimMesher.PrimMesh.prototype={constructor:JSPrimMesher.PrimMesh,ParamsToDisplayString:function(){var a="";a+="sides..................: "+this.sides;a+="\nhollowSides..........: "+this.hollowSides;a+="\nprofileStart.........: "+this.profileStart;a+="\nprofileEnd...........: "+this.profileEnd;a+="\nhollow...............: "+this.hollow;a+="\ntwistBegin...........: "+this.twistBegin;a+="\ntwistEnd.............: "+this.twistEnd;a+="\ntopShearX............: "+this.topShearX;a+="\ntopShearY............: "+this.topShearY;a+="\npathCutBegin.........: "+this.pathCutBegin;a+="\npathCutEnd...........: "+this.pathCutEnd;a+="\ndimpleBegin..........: "+this.dimpleBegin;a+="\ndimpleEnd............: "+this.dimpleEnd;a+="\nskew.................: "+this.skew;a+="\nholeSizeX............: "+this.holeSizeX;a+="\nholeSizeY............: "+this.holeSizeY;a+="\ntaperX...............: "+this.taperX;a+="\ntaperY...............: "+this.taperY;a+="\nradius...............: "+this.radius;a+="\nrevolutions..........: "+this.revolutions;a+="\nstepsPerRevolution...: "+this.stepsPerRevolution;a+="\nsphereMode...........: "+this.sphereMode;a+="\nhasProfileCut........: "+this.hasProfileCut;a+="\nhasHollow............: "+this.hasHollow;a+="\nviewerMode...........: "+this.viewerMode;return a},SurfaceNormalCoord:function(e,d,c){var b=new JSPrimMesher.Coord(d.X-e.X,d.Y-e.Y,d.Z-e.Z);var a=new JSPrimMesher.Coord(c.X-e.X,c.Y-e.Y,c.Z-e.Z);var f=JSPrimMesher.Coord.Cross(b,a);f=f.Normalize();return f},SurfaceNormalFace:function(a){return SurfaceNormalCoord(this.coords[a.v1],this.coords[a.v2],this.coords[a.v3])},SurfaceNormal:function(b){var a=this.faces.length;if(b<0||b>=a){throw"faceIndex out of range"}return SurfaceNormalFace(this.faces[b])},Copy:function(){var a=new JSPrimMesher.PrimMesh(this.sides,this.profileStart,this.profileEnd,this.hollow,this.hollowSides);a.twistBegin=this.twistBegin;a.twistEnd=this.twistEnd;a.topShearX=this.topShearX;a.topShearY=this.topShearY;a.pathCutBegin=this.pathCutBegin;a.pathCutEnd=this.pathCutEnd;a.dimpleBegin=this.dimpleBegin;a.dimpleEnd=this.dimpleEnd;a.skew=this.skew;a.holeSizeX=this.holeSizeX;a.holeSizeY=this.holeSizeY;a.taperX=this.taperX;a.taperY=this.taperY;a.radius=this.radius;a.revolutions=this.revolutions;a.stepsPerRevolution=this.stepsPerRevolution;a.calcVertexNormals=this.calcVertexNormals;a.normalsProcessed=this.normalsProcessed;a.viewerMode=this.viewerMode;a.numPrimFaces=this.numPrimFaces;a.errorMessage=this.errorMessage;a.coords=this.coords.concat();a.faces=this.faces.concat();a.viewerFaces=this.viewerFaces.concat();a.normals=this.normals.concat();return a},CalcNormals:function(){if(normalsProcessed){return}normalsProcessed=true;var a=faces.length;if(!this.calcVertexNormals){this.normals=new Array()}for(var b=0;b<a;b++){var c=faces[b];this.normals.push(this.SurfaceNormal(b).Normalize());var d=normals.length-1;c.n1=d;c.n2=d;c.n3=d;this.faces[b]=c}},AddPos:function(a,h,g){var f=0;var b=this.coords.length;var d=new JSPrimMesher.Coord(0,0);for(f=0;f<b;f++){d=this.coords[f];d.X+=a;d.Y+=h;d.Z+=g;this.coords[f]=d}if(this.viewerFaces){var e=this.viewerFaces.length;for(f=0;f<e;f++){var c=this.viewerFaces[f];c.AddPos(a,h,g);this.viewerFaces[f]=c}}},AddRot:function(f){var d=0;var a=this.coords.length;for(d=0;d<a;d++){this.coords[d]=JSPrimMesher.Coord.MulQuat(this.coords[d],f)}if(this.normals){var e=this.normals.length;for(d=0;d<e;d++){this.normals[d]=JSPrimMesher.Coord.MulQuat(this.normals[d],f)}}if(this.viewerFaces!=null){var c=this.viewerFaces.length;for(d=0;d<c;d++){var b=this.viewerFaces[d];b.v1=Coord.MulQuat(b.v1,f);b.v2=Coord.MulQuat(b.v2,f);b.v3=Coord.MulQuat(b.v3,f);b.n1=Coord.MulQuat(b.n1,f);b.n2=Coord.MulQuat(b.n2,f);b.n3=Coord.MulQuat(b.n3,f);this.viewerFaces[d]=b}}},Scale:function(b,h,g){var f=0;var c=this.coords.length;var a=new JSPrimMesher.Coord(b,h,g);for(f=0;f<c;f++){this.coords[f]=JSPrimMesher.Coord.Mul(this.coords[f],a)}if(this.viewerFaces!=null){var e=this.viewerFaces.length;for(f=0;f<e;f++){var d=this.viewerFaces[f];d.v1=JSPrimMesher.Coord.Mul(d.v1,a);d.v2=JSPrimMesher.Coord.Mul(d.v2,a);d.v3=JSPrimMesher.Coord.Mul(d.v3,a);this.viewerFaces[f]=d}}},ProfileOuterFaceNumber:function(){return this.profileOuterFaceNumber},ProfileHollowFaceNumber:function(){return this.profileHollowFaceNumber},HasProfileCut:function(){return this.hasProfileCut},HasHollow:function(){return this.hasHollow},Extrude:function(l){var k=false;this.coords=new Array();this.faces=new Array();if(this.viewerMode){this.viewerFaces=new Array();this.calcVertexNormals=true}if(this.calcVertexNormals){this.normals=new Array()}var F=1;var s=this.pathCutEnd-this.pathCutBegin;this.normalsProcessed=false;if(this.viewerMode&&this.sides==3){if(Math.abs(this.taperX)>0.01||Math.abs(this.taperY)>0.01){F=~~(F*4.5*s)}}if(this.sphereMode){this.hasProfileCut=this.profileEnd-this.profileStart<0.4999}else{this.hasProfileCut=this.profileEnd-this.profileStart<0.9999}this.hasHollow=(this.hollow>0.001);var g=this.twistBegin/360*this.twoPi;var J=this.twistEnd/360*this.twoPi;var y=J-g;var r=Math.abs(y);if(r>0.01){F+=~~(r*3.66)}var E=this.hollow;if(l==JSPrimMesher.PathType.Circular){k=false;if(this.pathCutBegin!=0||this.pathCutEnd!=1){k=true}else{if(this.taperX!=0||this.taperY!=0){k=true}else{if(this.skew!=0){k=true}else{if(y!=0){k=true}else{if(this.radius!=0){k=true}}}}}}else{k=true}var z=0;if(l==JSPrimMesher.PathType.Circular){if(this.sides==3){z=Math.PI;if(this.hollowSides==4){if(E>0.7){E=0.7}E*=0.707}else{E*=0.5}}else{if(this.sides==4){z=0.25*Math.PI;if(this.hollowSides!=4){E*=0.707}}else{if(this.sides>4){z=Math.PI;if(this.hollowSides==4){if(E>0.7){E=0.7}E/=0.7}}}}}else{if(this.sides==3){if(this.hollowSides==4){if(E>0.7){E=0.7}E*=0.707}else{E*=0.5}}else{if(this.sides==4){z=1.25*Math.PI;if(this.hollowSides!=4){E*=0.707}}else{if(this.sides==24&&this.hollowSides==4){E*=1.414}}}}var c=new JSPrimMesher.Profile(this.sides,this.profileStart,this.profileEnd,E,this.hollowSides,true,this.calcVertexNormals);this.errorMessage=c.errorMessage;this.numPrimFaces=c.numPrimFaces;var v=c.bottomFaceNumber+1;var O=v+1;if(!k){v-=2;O-=2}this.profileOuterFaceNumber=c.outerFaceNumber;if(!k){this.profileOuterFaceNumber--}if(this.hasHollow){this.profileHollowFaceNumber=c.hollowFaceNumber;if(!k){this.profileHollowFaceNumber--}}var G=-1;var u=-1;if(this.hasProfileCut){if(this.hasHollow){G=c.coords.length-1;u=c.numOuterVerts-1}else{G=0;u=c.numOuterVerts}}if(z!=0){c.AddRot(JSPrimMesher.Quat.QuatAxisAngle(new JSPrimMesher.Coord(0,0,1),z));if(this.viewerMode){c.MakeFaceUVs()}}var j=new JSPrimMesher.Coord();var h=new JSPrimMesher.Coord();var d=0;var q=0;var L=new JSPrimMesher.Path();L.twistBegin=g;L.twistEnd=J;L.topShearX=this.topShearX;L.topShearY=this.topShearY;L.pathCutBegin=this.pathCutBegin;L.pathCutEnd=this.pathCutEnd;L.dimpleBegin=this.dimpleBegin;L.dimpleEnd=this.dimpleEnd;L.skew=this.skew;L.holeSizeX=this.holeSizeX;L.holeSizeY=this.holeSizeY;L.taperX=this.taperX;L.taperY=this.taperY;L.radius=this.radius;L.revolutions=this.revolutions;L.stepsPerRevolution=this.stepsPerRevolution;L.Create(l,F);for(var o=0;o<L.pathNodes.length;o++){var B=L.pathNodes[o];var b=c.Copy(true);b.Scale(B.xScale,B.yScale);b.AddRot(B.rotation);b.AddPosCoord(B.position);if(k&&o==0){b.FlipNormals();if(this.viewerMode){var K=b.faceNormal;var p=new JSPrimMesher.ViewerFace(c.bottomFaceNumber);var e=b.faces.length;var x=b.faces.concat();for(var P=0;P<e;P++){p=new JSPrimMesher.ViewerFace(c.bottomFaceNumber);var T=x[P];p.v1=b.coords[T.v1].Copy();p.v2=b.coords[T.v2].Copy();p.v3=b.coords[T.v3].Copy();p.coordIndex1=T.v1;p.coordIndex2=T.v2;p.coordIndex3=T.v3;p.n1=K.Copy();p.n2=K.Copy();p.n3=K.Copy();p.uv1=b.faceUVs[T.v1].Copy();p.uv2=b.faceUVs[T.v2].Copy();p.uv3=b.faceUVs[T.v3].Copy();if(l==JSPrimMesher.PathType.Linear){p.uv1=p.uv1.Flip();p.uv2=p.uv2.Flip();p.uv3=p.uv3.Flip()}this.viewerFaces.push(p)}}}var Q=this.coords.length;b.AddValue2FaceVertexIndices(Q);var t=b.coords.length;var S=Q;while(t--){this.coords[S+t]=b.coords[t].Copy()}if(this.calcVertexNormals){b.AddValue2FaceNormalIndices(this.normals.length);S=this.normals.length;t=b.vertexNormals.length;while(t--){this.normals[S+t]=b.vertexNormals[t].Copy()}}if(B.percentOfPath<this.pathCutBegin+0.01||B.percentOfPath>this.pathCutEnd-0.01){S=this.faces.length}t=b.faces.length;while(t--){this.faces[S+t]=b.faces[t].Copy()}var M=b.coords.length;var V=new JSPrimMesher.Face(0,0,0);var U=new JSPrimMesher.Face(0,0,0);q=1-B.percentOfPath;if(o>0){var A=Q+1;var N=this.coords.length;if(this.sides<5||this.hasProfileCut||this.hasHollow){A--}for(var P=A;P<N;P++){var f=P+1;if(P==N-1){f=A}var R=P-A;V=new JSPrimMesher.Face(0,0,0);V.v1=P;V.v2=P-M;V.v3=f;V.n1=V.v1;V.n2=V.v2;V.n3=V.v3;this.faces.push(V);U=new JSPrimMesher.Face(0,0,0);U.v1=f;U.v2=P-M;U.v3=f-M;U.n1=U.v1;U.n2=U.v2;U.n3=U.v3;this.faces.push(U);if(this.viewerMode){var a=c.faceNumbers[R];if(!k){a-=1}var D=new JSPrimMesher.ViewerFace(a);var C=new JSPrimMesher.ViewerFace(a);var H=R;if(!this.hasHollow&&this.sides>4&&H<b.us.length-1){H++}var n=b.us[H];var m=1;if(H<(~~(b.us.length))-1){m=b.us[H+1]}if(R==G||R==u){n=0;m=1}else{if(this.sides<5){if(R<c.numOuterVerts){n*=this.sides;m*=this.sides;m-=~~(n);n-=~~(n);if(m<0.1){m=1}}}}if(this.sphereMode){if(R!=G&&R!=u){n=n*2-1;m=m*2-1;if(R>=b.numOuterVerts){n-=E;m-=E}}}D.uv1.U=n;D.uv2.U=n;D.uv3.U=m;D.uv1.V=q;D.uv2.V=d;D.uv3.V=q;C.uv1.U=m;C.uv2.U=n;C.uv3.U=m;C.uv1.V=q;C.uv2.V=d;C.uv3.V=d;D.v1=this.coords[V.v1].Copy();D.v2=this.coords[V.v2].Copy();D.v3=this.coords[V.v3].Copy();C.v1=this.coords[U.v1].Copy();C.v2=this.coords[U.v2].Copy();C.v3=this.coords[U.v3].Copy();D.coordIndex1=V.v1;D.coordIndex2=V.v2;D.coordIndex3=V.v3;C.coordIndex1=U.v1;C.coordIndex2=U.v2;C.coordIndex3=U.v3;if(R==G){D.primFaceNumber=v;C.primFaceNumber=v;D.n1=b.cutNormal1;D.n2=D.n3=j;C.n1=C.n3=b.cutNormal1;C.n2=j}else{if(R==u){D.primFaceNumber=O;C.primFaceNumber=O;D.n1=b.cutNormal2;D.n2=h;D.n3=h;C.n1=b.cutNormal2;C.n3=b.cutNormal2;C.n2=h}else{if((this.sides<5&&R<b.numOuterVerts)||(this.hollowSides<5&&R>=b.numOuterVerts)){D.CalcSurfaceNormal();C.CalcSurfaceNormal()}else{D.n1=this.normals[V.n1].Copy();D.n2=this.normals[V.n2].Copy();D.n3=this.normals[V.n3].Copy();C.n1=this.normals[U.n1].Copy();C.n2=this.normals[U.n2].Copy();C.n3=this.normals[U.n3].Copy()}}}this.viewerFaces.push(D);this.viewerFaces.push(C)}}}j=b.cutNormal1;h=b.cutNormal2;d=q;if(k&&o==L.pathNodes.length-1&&this.viewerMode){var K=b.faceNormal;var p=new JSPrimMesher.ViewerFace();p.primFaceNumber=0;var I=b.faces.length;var w=b.faces;for(var P=0;P<I;P++){p=new JSPrimMesher.ViewerFace();p.primFaceNumber=0;var T=w[P];p.v1=b.coords[T.v1-Q].Copy();p.v2=b.coords[T.v2-Q].Copy();p.v3=b.coords[T.v3-Q].Copy();p.coordIndex1=T.v1-Q;p.coordIndex2=T.v2-Q;p.coordIndex3=T.v3-Q;p.n1=K.Copy();p.n2=K.Copy();p.n3=K.Copy();p.uv1=b.faceUVs[T.v1-Q];p.uv2=b.faceUVs[T.v2-Q];p.uv3=b.faceUVs[T.v3-Q];if(l==JSPrimMesher.PathType.Linear){p.uv1=p.uv1.Flip();p.uv2=p.uv2.Flip();p.uv3=p.uv3.Flip()}this.viewerFaces.push(p)}}}},ExtrudeLinear:function(){this.Extrude(JSPrimMesher.PathType.Linear)},ExtrudeCircular:function(){this.Extrude(JSPrimMesher.PathType.Circular)},PlanarMapping:function(d,g){var c=new JSPrimMesher.Coord(1,0,0);var b=new JSPrimMesher.Coord(0,1,0);var f=new JSPrimMesher.Coord(g.X,g.Y,g.Z);for(var e=0;e<this.viewerFaces.length;e++){var a=this.viewerFaces[e];if(a.primFaceNumber==d){a.Planarize(f);this.viewerFaces[e]=a}}}};JSPrimMesher.Profile=function(H,a,N,W,B,p,V){this.twoPi=2*Math.PI;this.errorMessage="";this.coords=new Array();this.faces=new Array();this.vertexNormals=new Array();this.us=new Array();this.faceUVs=new Array();this.faceNumbers=new Array();this.outerCoordIndices=new Array();this.hollowCoordIndices=new Array();this.cut1CoordIndices=new Array();this.cut2CoordIndices=new Array();this.faceNormal=new JSPrimMesher.Coord(0,0,1);this.cutNormal1=new JSPrimMesher.Coord(0,0,0);this.cutNormal2=new JSPrimMesher.Coord(0,0,0);this.numOuterVerts=0;this.numHollowVerts=0;this.outerFaceNumber=-1;this.hollowFaceNumber=-1;this.bottomFaceNumber=0;this.numPrimFaces=0;var T=H||-1;var x=a||0;var X=N||0;var F=W||0;var m=B||0;var aa=(p!==undefined)?p:false;this.calcVertexNormals=(V!==undefined)?V:false;if(T==-1){return}var c=new JSPrimMesher.Coord(0,0,0);var E=new Array();var h=new Array();var t=new Array();if(this.calcVertexNormals){this.outerCoordIndices=new Array();this.hollowCoordIndices=new Array();this.cut1CoordIndices=new Array();this.cut2CoordIndices=new Array()}var o=(F>0);var v=(x>0||X<1);var y=new JSPrimMesher.AngleList();var Z=new JSPrimMesher.AngleList();var n=0.5;var O=0.5;if(T==4){n=0.707107;O=0.707107}var e=x*this.twoPi;var l=X*this.twoPi;try{y.makeAngles(T,e,l)}catch(L){errorMessage="makeAngles failed : Exception "+L.message+"\nsides: "+T+" startAngle: "+e+" stopAngle: "+l;return}this.numOuterVerts=y.angles.length;var G=(T<5&&!o&&!v);if(o){if(T==m){Z=y}else{try{Z.makeAngles(m,e,l)}catch(L){errorMessage="makeAngles failed: Exception: "+L.message+"\nsides: "+T+" startAngle: "+e+" stopAngle: "+l;return}}this.numHollowVerts=Z.angles.length}else{if(!G){this.coords.push(c);if(this.calcVertexNormals){this.vertexNormals.push(new JSPrimMesher.Coord(0,0,1))}this.us.push(0)}}var I=0;var s=new JSPrimMesher.Angle(0,0,0);var b=new JSPrimMesher.Coord(0,0,0);if(o&&m!=T){var J=Z.angles.length;for(var U=0;U<J;U++){s=Z.angles[U];b=new JSPrimMesher.Coord();b.X=F*n*s.X;b.Y=F*O*s.Y;b.Z=I;E.push(b);if(this.calcVertexNormals){if(m<5){h.push(Z.normals[U].Invert())}else{h.push(new JSPrimMesher.Coord(-s.X,-s.Y,0))}if(m==4){t.push(s.angle*F*0.707107)}else{t.push(s.angle*F)}}}}var D=0;var r=y.angles.length;for(var U=0;U<r;U++){s=y.angles[U];b=new JSPrimMesher.Coord(0,0,0);b.X=s.X*n;b.Y=s.Y*O;b.Z=I;this.coords.push(b);if(this.calcVertexNormals){this.outerCoordIndices.push(this.coords.length-1);var K=s.angle;if(T<5){this.vertexNormals.push(y.normals[U]);this.us.push(K)}else{this.vertexNormals.push(new JSPrimMesher.Coord(s.X,s.Y,0));this.us.push(K)}}if(o){if(m==T){b=new JSPrimMesher.Coord(b.X,b.Y,b.Z);b.X*=F;b.Y*=F;b.Z=I;E.push(b);if(this.calcVertexNormals){if(T<5){h.push(y.normals[U].Invert())}else{h.push(new JSPrimMesher.Coord(-s.X,-s.Y,0))}t.push(s.angle*F)}}}else{if(!G&&aa&&s.angle>0.0001){var Y=new JSPrimMesher.Face(0,D,D+1);this.faces.push(Y)}}D+=1}if(o){E=E.reverse();if(this.calcVertexNormals){h=h.reverse();t=t.reverse()}if(aa){var g=this.numOuterVerts+this.numHollowVerts;if(this.numOuterVerts==this.numHollowVerts){for(var M=0;M<this.numOuterVerts-1;M++){var Y=new JSPrimMesher.Face(M,M+1,g-M-1);this.faces.push(Y);Y=new JSPrimMesher.Face(M+1,g-M-2,g-M-1);this.faces.push(Y)}}else{if(this.numOuterVerts<this.numHollowVerts){var S=0;var A=this.numOuterVerts-1;for(var R=0;R<this.numHollowVerts;R++){if(S<A){if(y.angles[S+1].angle-Z.angles[R].angle<Z.angles[R].angle-y.angles[S].angle+0.000001){var Y=new JSPrimMesher.Face(g-R-1,S,S+1);this.faces.push(Y);S+=1}}var Y=new JSPrimMesher.Face(S,g-R-2,g-R-1);this.faces.push(Y)}}else{var d=0;var A=this.numHollowVerts-1;for(var R=0;R<this.numOuterVerts;R++){if(d<A){if(Z.angles[d+1].angle-y.angles[R].angle<y.angles[R].angle-Z.angles[d].angle+0.000001){var Y=new JSPrimMesher.Face(R,g-d-2,g-d-1);this.faces.push(Y);d+=1}}var w=new JSPrimMesher.Face(g-d-1,R,R+1);this.faces.push(w)}}}}if(this.calcVertexNormals){for(var Q=0;Q<E.length;Q++){this.coords.push(E[Q]);this.hollowCoordIndices.push(this.coords.length-1)}}else{this.coords=this.coords.concat(E)}if(this.calcVertexNormals){this.vertexNormals=this.vertexNormals.concat(h);this.us=this.us.concat(t)}}if(G&&aa){if(T==3){this.faces.push(new JSPrimMesher.Face(0,1,2))}else{if(T==4){this.faces.push(new JSPrimMesher.Face(0,1,2));this.faces.push(new JSPrimMesher.Face(0,2,3))}}}if(this.calcVertexNormals&&v){var f=this.numOuterVerts-1;if(o){this.cut1CoordIndices.push(0);this.cut1CoordIndices.push(this.coords.length-1);this.cut2CoordIndices.push(f+1);this.cut2CoordIndices.push(f);this.cutNormal1.X=this.coords[0].Y-this.coords[this.coords.length-1].Y;this.cutNormal1.Y=-(this.coords[0].X-this.coords[this.coords.length-1].X);this.cutNormal2.X=this.coords[f+1].Y-this.coords[f].Y;this.cutNormal2.Y=-(this.coords[f+1].X-this.coords[f].X)}else{this.cut1CoordIndices.push(0);this.cut1CoordIndices.push(1);this.cut2CoordIndices.push(f);this.cut2CoordIndices.push(0);this.cutNormal1.X=this.vertexNormals[1].Y;this.cutNormal1.Y=-this.vertexNormals[1].X;this.cutNormal2.X=-this.vertexNormals[this.vertexNormals.length-2].Y;this.cutNormal2.Y=this.vertexNormals[this.vertexNormals.length-2].X}this.cutNormal1=this.cutNormal1.Normalize();this.cutNormal2=this.cutNormal2.Normalize()}this.MakeFaceUVs();E=null;h=null;t=null;if(this.calcVertexNormals){var q=1;var C=0;this.outerFaceNumber=q;if(v&&!o){C=1}else{C=0}if(C>0){this.faceNumbers.push(-1)}for(var R=0;R<this.numOuterVerts-1;R++){if(T<5){this.faceNumbers.push(q++)}else{this.faceNumbers.push(q)}}if(v){this.faceNumbers.push(-1)}else{this.faceNumbers.push(q++)}if(T>4&&(o||v)){q++}if(T<5&&(o||v)&&this.numOuterVerts<T){q++}if(o){for(var P=0;P<this.numHollowVerts;P++){this.faceNumbers.push(q)}this.hollowFaceNumber=q++}this.bottomFaceNumber=q++;if(o&&v){this.faceNumbers.push(q++)}for(var R=0;R<this.faceNumbers.length;R++){if(this.faceNumbers[R]==-1){this.faceNumbers[R]=q++}}this.numPrimFaces=q}};JSPrimMesher.Profile.prototype={constructor:JSPrimMesher.Profile,MakeFaceUVs:function(){this.faceUVs=new Array();for(var a=0;a<this.coords.length;a++){this.faceUVs.push(new JSPrimMesher.UVCoord(1-(0.5+this.coords[a].X),1-(0.5-this.coords[a].Y)))}},Copy:function(b){var c=(b!==undefined)?b:true;var d=new JSPrimMesher.Profile();d.coords=new Array(this.coords.length);var a=this.coords.length;while(a--){d.coords[a]=this.coords[a].Copy()}d.faceUVs=new Array(this.faceUVs.length);a=this.faceUVs.length;while(a--){d.faceUVs[a]=this.faceUVs[a].Copy()}if(c){d.faces=new Array(this.faces.length);a=this.faces.length;while(a--){d.faces[a]=this.faces[a].Copy()}}if((d.calcVertexNormals=this.calcVertexNormals)==true){d.vertexNormals=new Array(this.vertexNormals.length);a=this.vertexNormals.length;while(a--){d.vertexNormals[a]=this.vertexNormals[a].Copy()}d.faceNormal=new JSPrimMesher.Coord(this.faceNormal.X,this.faceNormal.Y,this.faceNormal.Z);d.cutNormal1=new JSPrimMesher.Coord(this.cutNormal1.X,this.cutNormal1.Y,this.cutNormal1.Z);d.cutNormal2=new JSPrimMesher.Coord(this.cutNormal2.X,this.cutNormal2.Y,this.cutNormal2.Z);d.us=JSON.parse(JSON.stringify(this.us));d.faceNumbers=JSON.parse(JSON.stringify(this.faceNumbers));d.cut1CoordIndices=JSON.parse(JSON.stringify(this.cut1CoordIndices));d.cut2CoordIndices=JSON.parse(JSON.stringify(this.cut2CoordIndices));d.hollowCoordIndices=JSON.parse(JSON.stringify(this.hollowCoordIndices));d.outerCoordIndices=JSON.parse(JSON.stringify(this.outerCoordIndices))}d.numOuterVerts=this.numOuterVerts;d.numHollowVerts=this.numHollowVerts;return d},AddPosCoord:function(a){this.AddPos(a.X,a.Y,a.Z)},AddPos:function(a,f,e){var b=new JSPrimMesher.Coord();var d=this.coords.length;for(var c=0;c<d;c++){b=this.coords[c];b.X+=a;b.Y+=f;b.Z+=e;this.coords[c]=b}},AddRot:function(d){var c=this.coords.length;for(var a=0;a<c;a++){this.coords[a]=JSPrimMesher.Coord.MulQuat(this.coords[a],d)}if(this.calcVertexNormals){var e=this.vertexNormals.length;for(var b=0;b<e;b++){this.vertexNormals[b]=JSPrimMesher.Coord.MulQuat(this.vertexNormals[b],d)}this.faceNormal=JSPrimMesher.Coord.MulQuat(this.faceNormal,d);this.cutNormal1=JSPrimMesher.Coord.MulQuat(this.cutNormal1,d);this.cutNormal2=JSPrimMesher.Coord.MulQuat(this.cutNormal2,d)}},Scale:function(a,e){var c=new JSPrimMesher.Coord(0,0,0);var b=this.coords.length;for(var d=0;d<b;d++){c=this.coords[d];c.X*=a;c.Y*=e;this.coords[d]=c}},FlipNormals:function(){var e=0;var b=this.faces.length;var g=new JSPrimMesher.Face();var d=0;for(e=0;e<b;e++){g=this.faces[e];d=g.v3;g.v3=g.v1;g.v1=d;this.faces[e]=g}if(this.calcVertexNormals){var a=this.vertexNormals.length;if(a>0){var h=this.vertexNormals[a-1];h.Z=-h.Z;this.vertexNormals[a-1]=h}}this.faceNormal.X=-this.faceNormal.X;this.faceNormal.Y=-this.faceNormal.Y;this.faceNormal.Z=-this.faceNormal.Z;var c=this.faceUVs.length;for(e=0;e<c;e++){var f=this.faceUVs[e];f.V=1-f.V;this.faceUVs[e]=f}},AddValue2FaceVertexIndices:function(b){var a=this.faces.length;var d=new JSPrimMesher.Face();for(var c=0;c<a;c++){d=this.faces[c];d.v1+=b;d.v2+=b;d.v3+=b;this.faces[c]=d}},AddValue2FaceNormalIndices:function(b){if(this.calcVertexNormals){var a=this.faces.length;var d=new JSPrimMesher.Face();for(var c=0;c<a;c++){d=this.faces[c];d.n1+=b;d.n2+=b;d.n3+=b;this.faces[c]=d}}},DumpRaw:function(){var b="";var c=this.faces.length;for(var a=0;a<c;a++){b=b.concat(this.coords[this.faces[a].v1].ToString()+" "+this.coords[this.faces[a].v2].ToString()+" "+this.coords[this.faces[a].v3].ToString()+"\n")}return b}};JSPrimMesher.Quat=function(a,d,c,b){this.X=a||0;this.Y=d||0;this.Z=c||0;this.W=(b!=undefined)?b:1};JSPrimMesher.Quat.prototype={constructor:JSPrimMesher.Quat,set:function(a,d,c,b){this.X=a;this.Y=d;this.Z=c;this.W=b;return this},QuatAxisAngle:function(d,f){var e=d.Normalize();var b=f*0.5;var h=Math.cos(b);var a=Math.sin(b);var g=new JSPrimMesher.Quat(e.X*a,e.Y*a,e.Z*a,h);g.Normalize();return reQuat},Length:function(){return Math.sqrt(this.X*this.X+this.Y*this.Y+this.Z*this.Z+this.W*this.W)},Normalize:function(){var a=this.Length();if(a>1e-7){var b=1/a;this.X*=b;this.Y*=b;this.Z*=b;this.W*=b}else{this.X=0;this.Y=0;this.Z=0;this.W=1}},Mul:function(b,f){var a=b.W*f.X+b.X*f.W+b.Y*f.Z-b.Z*f.Y;var e=b.W*f.Y-b.X*f.Z+b.Y*f.W+b.Z*f.X;var d=b.W*f.Z+b.X*f.Y-b.Y*f.X+b.Z*f.W;var c=b.W*f.W-b.X*f.X-b.Y*f.Y-b.Z*f.Z;return new JSPrimMesher.Quat(a,e,d,c)},ToString:function(){return"> X: "+this.X+", Y: "+this.Y+", Z: "+this.Z+", W: "+this.W+" <"}};JSPrimMesher.Quat.Mul=function(b,f){var a=b.W*f.X+b.X*f.W+b.Y*f.Z-b.Z*f.Y;var e=b.W*f.Y-b.X*f.Z+b.Y*f.W+b.Z*f.X;var d=b.W*f.Z+b.X*f.Y-b.Y*f.X+b.Z*f.W;var c=b.W*f.W-b.X*f.X-b.Y*f.Y-b.Z*f.Z;return new JSPrimMesher.Quat(a,e,d,c)};JSPrimMesher.Quat.QuatAxisAngle=function(d,f){var e=d.Normalize();var b=f*0.5;var h=Math.cos(b);var a=Math.sin(b);var g=new JSPrimMesher.Quat(e.X*a,e.Y*a,e.Z*a,h);g.Normalize();return g};JSPrimMesher.UVCoord=function(b,a){this.U=b||0;this.V=a||0};JSPrimMesher.UVCoord.prototype={constructor:JSPrimMesher.UVCoord,Flip:function(){return new JSPrimMesher.UVCoord(1-this.U,1-this.V)},Copy:function(){return new JSPrimMesher.UVCoord(this.U,this.V)}};var JSVertexIndexer=JSVertexIndexer||{revision:"72"};JSVertexIndexer.ViewerVertex=function(c,b,a){this.v=c;this.n=b;this.uv=a};JSVertexIndexer.ViewerVertex.prototype={constructor:JSVertexIndexer.ViewerVertex};JSVertexIndexer.ViewerPolygon=function(c,b,a){this.v1=c;this.v2=b;this.v3=a};JSVertexIndexer.ViewerPolygon.prototype={constructor:JSVertexIndexer.ViewerPolygon};JSVertexIndexer.VertexIndexer=function(n){var e=0;for(var h=0;h<n.viewerFaces.length;h++){var f=n.viewerFaces[h];if(e<f.primFaceNumber){e=f.primFaceNumber}}this.numPrimFaces=e+1;this.viewerVertices=new Array(this.numPrimFaces);this.viewerPolygons=new Array(this.numPrimFaces);var b=new Array(this.numPrimFaces);var m=new Array(this.numPrimFaces);var c=new Array(this.numPrimFaces);for(var d=0;d<this.numPrimFaces;d++){m[d]=0;c[d]=0}for(f in n.viewerFaces){c[f.primFaceNumber]+=3}for(var p=0;p<this.numPrimFaces;p++){var g=new Array(n.coords.length);for(var d=0;d<n.coords.length;d++){g[d]=-1}b[p]=g;this.viewerVertices[p]=new Array();this.viewerPolygons[p]=new Array()}for(var a=0;a<n.viewerFaces.length;a++){var f=n.viewerFaces[a];var l=-1;var k=-1;var j=-1;var g=b[f.primFaceNumber];var o=this.viewerVertices[f.primFaceNumber];if(g[f.coordIndex1]<0){o.push(new JSVertexIndexer.ViewerVertex(f.v1,f.n1,f.uv1));l=o.length-1;g[f.coordIndex1]=l}else{l=g[f.coordIndex1]}if(g[f.coordIndex2]<0){o.push(new JSVertexIndexer.ViewerVertex(f.v2,f.n2,f.uv2));k=o.length-1;g[f.coordIndex2]=k}else{k=g[f.coordIndex2]}if(g[f.coordIndex3]<0){o.push(new JSVertexIndexer.ViewerVertex(f.v3,f.n3,f.uv3));j=o.length-1;g[f.coordIndex3]=j}else{j=g[f.coordIndex3]}this.viewerPolygons[f.primFaceNumber].push(new JSVertexIndexer.ViewerPolygon(l,k,j))}};JSVertexIndexer.VertexIndexer.prototype={constructor:JSVertexIndexer.VertexIndexer};JSPrimMesher.ViewerFace=function(a){this.primFaceNumber=a||0;this.v1=new JSPrimMesher.Coord(0,0);this.v2=new JSPrimMesher.Coord(0,0);this.v3=new JSPrimMesher.Coord(0,0);this.n1=new JSPrimMesher.Coord(0,0);this.n2=new JSPrimMesher.Coord(0,0);this.n3=new JSPrimMesher.Coord(0,0);this.uv1=new JSPrimMesher.UVCoord(0,0);this.uv2=new JSPrimMesher.UVCoord(0,0);this.uv3=new JSPrimMesher.UVCoord(0,0);this.coordIndex1=-1;this.coordIndex2=-1;this.coordIndex3=-1};JSPrimMesher.ViewerFace.prototype={constructor:JSPrimMesher.ViewerFace,Scale:function(a,c,b){this.v1.X*=a;this.v1.Y*=c;this.v1.Z*=b;this.v2.X*=a;this.v2.Y*=c;this.v2.Z*=b;this.v3.X*=a;this.v3.Y*=c;this.v3.Z*=b},AddPos:function(a,c,b){this.v1.X+=a;this.v2.X+=a;this.v3.X+=a;this.v1.Y+=c;this.v2.Y+=c;this.v3.Y+=c;this.v1.Z+=b;this.v2.Z+=b;this.v3.Z+=b},AddRot:function(a){this.v1=JSPrimMesher.Coord.MulQuat(v1,a);this.v2=JSPrimMesher.Coord.MulQuat(v2,a);this.v3=JSPrimMesher.Coord.MulQuat(v3,a);this.n1=JSPrimMesher.Coord.MulQuat(n1,a);this.n2=JSPrimMesher.Coord.MulQuat(n2,a);this.n3=JSPrimMesher.Coord.MulQuat(n3,a)},CalcSurfaceNormal:function(){var b=new JSPrimMesher.Coord(this.v2.X-this.v1.X,this.v2.Y-this.v1.Y,this.v2.Z-this.v1.Z);var a=new JSPrimMesher.Coord(this.v3.X-this.v1.X,this.v3.Y-this.v1.Y,this.v3.Z-this.v1.Z);this.n1=this.n2=this.n3=JSPrimMesher.Coord.Cross(b,a).Normalize()},Copy:function(){var a=new JSPrimMesher.ViewerFace(this.primFaceNumber);a.v1=this.v1.Copy();a.v2=this.v2.Copy();a.v3=this.v3.Copy();a.n1=this.n1.Copy();a.n2=this.n2.Copy();a.n3=this.n3.Copy();a.uv1=this.uv1.Copy();a.uv2=this.uv2.Copy();a.uv3=this.uv3.Copy();a.coordIndex1=this.coordIndex1;a.coordIndex2=this.coordIndex2;a.coordIndex3=this.coordIndex3},Planarize:function(a){this.PlanarCalc(this.v1,this.n1,this.uv1,a);this.PlanarCalc(this.v2,this.n2,this.uv2,a);this.PlanarCalc(this.v3,this.n3,this.uv3,a)},PlanarCalc:function(b,i,a,g){var e=new JSPrimMesher.Coord(1,0,0);var c=new JSPrimMesher.Coord(0,1,0);var k;var j;var h;var f;f=JSPrimMesher.Coord.Dot(i,e);if(f>=0.5||f<=-0.5){k=c.Copy();if(i.X<0){k.X=k.X*-1;k.Y=k.Y*-1;k.Z=k.Z*-1}}else{k=e.Copy();if(i.Y<0){k.X=k.X*-1;k.Y=k.Y*-1;k.Z=k.Z*-1}}j=JSPrimMesher.Coord.Cross(k,i);h=JSPrimMesher.Coord.Mul(b,g);a.U=1+(JSPrimMesher.Coord.Dot(k,h)*2-0.5);a.V=-1*(JSPrimMesher.Coord.Dot(j,h)*2-0.5)}};