1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/pgo/js-input/3d-thingy.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,390 @@ 1.4 +<html> 1.5 +<head> 1.6 +<title>3d thingy</title> 1.7 +<style type="text/css"> 1.8 +div.z2 { position:absolute; z-index:2; } 1.9 +div.z1 { position:absolute; z-index:1; } 1.10 +</style> 1.11 +<script type="text/javascript"> 1.12 +/************************************************************************** 1.13 +JavaScript Graphics Library 0.0.1, Updated Source Code at Scriptersoft.com 1.14 +Copyright (C) 2005 Kurt L. Whicher 1.15 +November,13,2005 1.16 + 1.17 +This library is free software; you can redistribute it and/or 1.18 +modify it under the terms of the GNU Lesser General Public 1.19 +License as published by the Free Software Foundation; either 1.20 +version 2.1 of the License, or (at your option) any later version. 1.21 + 1.22 +This library is distributed in the hope that it will be useful, 1.23 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.24 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.25 +Lesser General Public License for more details. 1.26 + 1.27 +You should have received a copy of the GNU Lesser General Public 1.28 +License along with this library; if not, write to the Free Software 1.29 +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1.30 +**************************************************************************/ 1.31 + 1.32 +//________________________________________ global variables 1.33 + 1.34 +var S_piDoubled=Math.PI*2; 1.35 +var S_deg2Rad=Math.PI/180; 1.36 + 1.37 +//_______________________________________________ functions 1.38 + 1.39 +function S_matrix() { 1.40 + return [1,0,0,0, 1.41 + 0,1,0,0, 1.42 + 0,0,1,0, 1.43 + 0,0,0,1]; 1.44 +} 1.45 +function S_vec2D(x,y) { this.x=x; this.y=y; } 1.46 +function S_vec3D(x,y,z) { this.x=x; this.y=y; this.z=z; } 1.47 +function S_subVec2D(a,b) { 1.48 + return new S_vec2D(a.x-b.x, a.y-b.y); 1.49 +} 1.50 +function S_subVec3D(a,b) { 1.51 + return new S_vec3D(a.x-b.x, a.y-b.y, a.z-b.z); 1.52 +} 1.53 +function S_dotVec3D(a, b) { return a.x*b.x+a.y*b.y+a.z*b.z; } 1.54 +function S_cross(a,b) { 1.55 + return new S_vec3D( a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x); 1.56 +} 1.57 +function S_lengthSquaredVec3D(v) { return S_dotVec3D(v,v); } 1.58 +function S_lengthVec3D(v) { return Math.sqrt(S_lengthSquaredVec3D(v)); } 1.59 +function S_normalizeVec3D(v) { 1.60 + var l=S_lengthVec3D(v), nv=new S_vec3D(0,0,0); 1.61 + if(l!=0) { nv.x=v.x/l; nv.y=v.y/l; nv.z=v.z/l; } 1.62 + return nv; 1.63 +} 1.64 +function S_rotate(m,ax,a) { // transformation matrix, axis, angle 1.65 + var i,j,ij=new Array(),v=new Array(),c=Math.cos(a),s=Math.sin(a); 1.66 + if (ax=="x") ij=[1,2,5,6,9,10,13,14]; 1.67 + else if (ax=="y") ij=[2,0,6,4,10,8,14,12]; 1.68 + else if (ax=="z") ij=[0,1,4,5,8,9,12,13]; 1.69 + for (i=0;i<8;i++) v[i]=m[ij[i]]; 1.70 + for (i=0,j=1;i<8;i+=2,j+=2) { 1.71 + m[ij[i]]=v[i]*c-v[j]*s; 1.72 + m[ij[j]]=v[i]*s+v[j]*c 1.73 + } 1.74 +} 1.75 +function S_checkBrowser() { 1.76 + if (document.getElementById) return true; else return false; 1.77 +} 1.78 +function S_zIndex(e,z) { document.getElementById(e).style.zIndex=z; } 1.79 +function S_rgbColor(r,g,b) { 1.80 + var i, c=[r,g,b]; 1.81 + for(i=0; i<3; i++) { 1.82 + c[i]=Math.floor(c[i]); 1.83 + if(c[i]<0) c[i]=0; else if(c[i]>255) c[i]=255; 1.84 + } 1.85 + return c; 1.86 +} 1.87 +function S_rgbColorString(c) { 1.88 + return "rgb("+c[0]+","+c[1]+","+c[2]+")"; 1.89 +} 1.90 +function S_vertice(x,y,z) { 1.91 + this.x=x; this.y=y; this.z=z; this.w=1; 1.92 + this.t=new S_vec3D(x,y,z); // transformed 3d 1.93 + this.p=new S_vec2D(0,0); // projected 2d 1.94 +} 1.95 +function S_face(v0,v1,v2,c) { // 3 vertice faces 1.96 + this.v=[v0,v1,v2]; this.c=c; this.b=0; // b:brightness 1.97 + this.d=true; // display: true or false 1.98 +} 1.99 +// x coordinate, number of vertices, distance 1.100 +function S_verticeRing(x,nv,d) { 1.101 + var i,a,v=new Array(); 1.102 + for(i=0;i<nv;i++) { 1.103 + a=S_piDoubled*i/nv; 1.104 + v[i]=new S_vertice(x,d*Math.sin(a),d*Math.cos(a)); 1.105 + } 1.106 + return v; 1.107 +} 1.108 +function S_triangleRing(r1,r2,c,clr) { // rows 1 & 2, cols, color 1.109 + var i,j,tr=new Array(); 1.110 + for(i=0,j=1;i<c;i++,j=++j%c) { 1.111 + tr.push(new S_face(r1+i,r2+i,r2+j,clr)); 1.112 + tr.push(new S_face(r1+i,r2+j,r1+j,clr)); 1.113 + } 1.114 + return tr; 1.115 +} 1.116 +function S_model(v,f) { 1.117 + // vertice & face arrays, transformation matrix, display boolean 1.118 + this.v=v; this.f=f, this.tm=S_matrix(), this.d=true; 1.119 +} 1.120 +S_model.prototype.S_rotateX=function(a) { 1.121 + S_rotate(this.tm,"x",a*=S_deg2Rad); 1.122 +} 1.123 +S_model.prototype.S_rotateY=function(a) { 1.124 + S_rotate(this.tm,"y",a*=S_deg2Rad); 1.125 +} 1.126 +S_model.prototype.S_rotateZ=function(a) { 1.127 + S_rotate(this.tm,"z",a*=S_deg2Rad); 1.128 +} 1.129 +S_model.prototype.S_show=function() { this.d=true; } 1.130 +S_model.prototype.S_hide=function() { this.d=false; } 1.131 +function S_cube(d,c) { //distance & color 1.132 + return new S_cone(d,d,Math.cos(Math.PI/4)*d*2,1,4,c); 1.133 +} 1.134 +function S_cylinder(w,h,r,c,clr,e) { 1.135 + return new S_cone(w,w,h,r,c,clr,e); 1.136 +} 1.137 +// width, height, "rows", "columns", color, ends 1.138 +function S_cone(w1,w2,h,r,c,clr,e) { 1.139 + var i,r1=0,r2=c,v=new Array(),t=new Array(),rxc=r*c; 1.140 + for(i=0;i<=r;i++) 1.141 + v=v.concat(S_verticeRing(h*(0.5-i/r),c,w1*i/r+w2*(r-i)/r)); 1.142 + for(i=0;i<r;i++,r1+=c,r2+=c) 1.143 + t=t.concat(S_triangleRing(r1,r2,c,clr)); 1.144 + if (e!="hideEnds") 1.145 + for(i=1;i<(c-1);i++) { 1.146 + t.push(new S_face(0,i,i+1,clr)); 1.147 + t.push(new S_face(rxc,rxc+i+1,rxc+i,clr)); 1.148 + } 1.149 + return new S_model(v,t); 1.150 +} 1.151 +function S_sphere(d,r,c,clr) { 1.152 + // distance, "rows">=2, "columns">=3, color paramaters 1.153 + var v=new Array(),t=new Array(),r_1xc=(r-1)*c,r_2xc=(r-2)*c; 1.154 + var i,j,tmp,r1=0,r2=c; 1.155 + for(i=1;i<r;i++) { 1.156 + tmp=Math.PI*i/r; 1.157 + v=v.concat(S_verticeRing(d*Math.cos(tmp),c,Math.sin(tmp)*d)); 1.158 + } 1.159 + v.push(new S_vertice( d,0,0)); 1.160 + v.push(new S_vertice(-d,0,0)); 1.161 + for(i=0;i<(r-2);i++,r1+=c,r2+=c) 1.162 + t=t.concat(S_triangleRing(r1,r2,c,clr)); 1.163 + for(i=0,j=1;i<c;i++,j=++j%c) { 1.164 + t.push(new S_face(r_1xc,i,j,clr)); 1.165 + t.push(new S_face(r_1xc+1,r_2xc+j,r_2xc+i,clr)); 1.166 + } 1.167 + return new S_model(v,t); 1.168 +} 1.169 +S_model.prototype.S_scale=function(x) { 1.170 + this.tm[0]*=x; this.tm[5]*=x; this.tm[10]*=x; 1.171 +} 1.172 +S_model.prototype.S_faceColor=function(i,c) { this.f[i].c=c; } 1.173 +S_model.prototype.S_scaleX=function(s) { this.tm[0]*=s; } 1.174 +S_model.prototype.S_scaleY=function(s) { this.tm[5]*=s; } 1.175 +S_model.prototype.S_scaleZ=function(s) { this.tm[10]*=s; } 1.176 +function S_scene(dv,l,t,w,h,cmra) { // left, top, width, height 1.177 + this.dv=dv; 1.178 + this.ps=1; // pixel size 1.179 + this.l=l; this.t=t; this.w=w; this.h=h; 1.180 + this.cx=l+w/2; this.cy=t+h/2; // center x, center y 1.181 + this.dt="paint"; // output type 1.182 + this.m=new Array(); // model array 1.183 + this.lght=new S_light(); 1.184 + this.lc=S_rgbColor(255,255,255); // light color 1.185 + this.cmra=-cmra; // camera on z axis 1.186 + this.bfr=S_buffer(h,w); 1.187 +} 1.188 +function S_buffer(h,w) { 1.189 + var i, j, b=new Array(); 1.190 + for(i=0;i<h;i++) { 1.191 + b[i]=new Array(); 1.192 + for(j=0;j<w;j++) b[i][j]=new S_pixel(); 1.193 + } 1.194 + return b; 1.195 +} 1.196 +function S_pixel() { // display boolean, color 1.197 + this.d=true; this.c=0; 1.198 +} 1.199 +S_pixel.prototype.S_setColor=function(c) { 1.200 + this.d=true; this.c=c; 1.201 +} 1.202 +S_pixel.prototype.S_hide=function() { this.d=false; } 1.203 +S_scene.prototype.S_pixelSize=function(ps){ this.ps=ps; } 1.204 +S_scene.prototype.S_widthAndHeight=function(w,h){ this.w=w; this.h=h; } 1.205 +S_scene.prototype.S_center=function(cx,cy){ this.cx=cx; this.cy=cy; } 1.206 +S_scene.prototype.S_paint=function(){ this.dt="paint"; } 1.207 +S_scene.prototype.S_models=function() { 1.208 + var i; this.m=new Array(); 1.209 + for(i=0;i<arguments.length;i++) this.m.push(arguments[i]); 1.210 +} 1.211 +S_scene.prototype.S_lightColor=function(c){ this.lc=c; } 1.212 +S_scene.prototype.S_project=function() { 1.213 + var i, j, v, tm, d, m; 1.214 + for(i=0;i<this.m.length;i++) { 1.215 + m=this.m[i]; tm=this.m[i].tm; 1.216 + for(j=0;j<m.v.length;j++) { 1.217 + v=m.v[j]; 1.218 + v.t.x=v.x*tm[0]+v.y*tm[4]+v.z*tm[8]+v.w*tm[12]; 1.219 + v.t.y=v.x*tm[1]+v.y*tm[5]+v.z*tm[9]+v.w*tm[13]; 1.220 + v.t.z=v.x*tm[2]+v.y*tm[6]+v.z*tm[10]+v.w*tm[14]; 1.221 + d=(this.cmra-v.t.z/2); 1.222 + if (d<0) { 1.223 + v.p.x=(this.cmra*v.t.x/d)+this.cx; 1.224 + v.p.y=-(this.cmra*v.t.y/d)+this.cy; 1.225 + } 1.226 + } 1.227 + } 1.228 +} 1.229 +S_scene.prototype.S_display=function(disp){ 1.230 + var i, j, k, s="", ds, c, cnt=0; // ds:div start 1.231 + this.tr=new Array(); // triangles ready to draw 1.232 + this.S_project(); 1.233 + this.S_adjustLight(); 1.234 + this.S_clearBuffer(); 1.235 + for(i=0;i<this.m.length;i++) { 1.236 + this.m[i].S_setupFaces(this.tr,this.lght.t); 1.237 + for(j=0;j<this.tr.length;j++) { // loop through triangles 1.238 + c=S_divColor(this.tr[j].c,this.lc,this.tr[j].b); 1.239 + S_setupBuffer(this,this.tr[j].p,c); 1.240 + } 1.241 + } 1.242 + for(i=0;i<this.h;i++) { 1.243 + ds=-1; 1.244 + for(j=0,k=1;j<this.w;j++,k++) { 1.245 + if((this.bfr[i][j].d==true)&&(ds==-1)) ds=j; 1.246 + if( (this.bfr[i][j].d==true)&& 1.247 + ( (k==this.w)|| 1.248 + (this.bfr[i][k].d==false)|| 1.249 + (!S_sameColor(this.bfr[i][j].c, this.bfr[i][k].c)) ) ) { 1.250 + s+=S_divString(S_rgbColorString(this.bfr[i][j].c),this.t+i*this.ps,this.l+ds*this.ps,this.ps,(k-ds)*this.ps); 1.251 + ds=-1; 1.252 + cnt++; 1.253 + } 1.254 + } 1.255 + } 1.256 + S_writeInnerHTML(this.dv,s); 1.257 + if(disp=="ShowCount") alert(cnt); 1.258 +} 1.259 +S_scene.prototype.S_displayAndShowCount=function(){ 1.260 + this.S_display("ShowCount"); 1.261 +} 1.262 +S_model.prototype.S_setupFaces=function(tr,lght) { 1.263 + var i, j, fn, v, p=new Array(); // vertice & projection arrays 1.264 + var z=new Array(); 1.265 + for(i=0;i<this.f.length;i++) { // loop through faces 1.266 + v=this.f[i].v; 1.267 + for(j=0;j<3;j++) { p[j]=this.v[v[j]].p; } 1.268 + for(j=0;j<3;j++) { z[j]=this.v[v[j]].t.z; } 1.269 + if (((p[1].x-p[0].x)*(p[2].y-p[0].y))<((p[2].x-p[0].x)*(p[1].y-p[0].y))) { 1.270 + this.f[i].d=true; 1.271 + fn=S_faceNormal(this.v[v[0]].t, this.v[v[1]].t, this.v[v[2]].t); 1.272 + this.f[i].b=S_faceIntensity(fn,lght); 1.273 + tr.push(new S_triangle(fn,this.f[i].b,p.slice(),this.f[i].c,z)); 1.274 + } else { this.f[i].d=false; } 1.275 + } 1.276 +} 1.277 +// normal, brightness, array of 2D projection coordinates, and z depth 1.278 +function S_triangle(fn,b,p,c,z) { 1.279 + this.fn=fn; this.b=b; this.p=p; this.z=z; this.c=c; 1.280 +} 1.281 +function S_faceNormal(a,b,c){ 1.282 + var cr=S_cross(S_subVec3D(b,a), S_subVec3D(b,c)); 1.283 + return S_normalizeVec3D(cr); 1.284 +} 1.285 +function S_faceIntensity(fn,lght) { 1.286 + var i=S_dotVec3D(fn,lght); return (i>0)?i:0; 1.287 +} 1.288 +function S_divColor(c,lc,b) { // c:array of colors 1.289 + var i, clr=new Array(); 1.290 + for(i=0;i<3;i++) clr[i]=Math.floor(c[i]+(lc[i]-c[i]+1)*b); 1.291 + for(i=0;i<3;i++) if (clr[i]>lc[i]) { clr[i]=lc[i]; } 1.292 + return S_rgbColor(clr[0],clr[1],clr[2]); 1.293 +} 1.294 +function S_sameColor(a,b) { 1.295 + for(var i=0;i<3;i++) { if(a[i]!=b[i]) return false; } 1.296 + return true; 1.297 +} 1.298 +function S_setupBuffer(scn,p,c) { 1.299 + // temp, counters, min, max, scanline, vertice & slope arrays 1.300 + var t,i,j,xmin=new Array(),xmax=new Array(),sl; 1.301 + var v=new Array(), m=new Array(); 1.302 + p.sort(function(a,b) { return a.y-b.y; } ); 1.303 + for(i=0;i<3;i++) p[i].y=Math.floor(p[i].y); 1.304 + v[0]=S_subVec2D(p[1],p[0]); 1.305 + v[1]=S_subVec2D(p[2],p[0]); 1.306 + v[2]=S_subVec2D(p[2],p[1]); 1.307 + for(i=0;i<3;i++) { m[i]=(v[i].y!=0)?v[i].x/v[i].y:0; } 1.308 + for(i=0,sl=scn.t;i<scn.h;i++,sl++) { 1.309 + xmin[i]=1000;xmax[i]=0; 1.310 + if((sl>=p[0].y)&&(sl<=p[2].y)) { 1.311 + xmin[i]=xmax[i]=Math.floor(p[0].x+m[1]*(sl-p[0].y)); 1.312 + } 1.313 + if((sl>=p[0].y)&&(sl<=p[1].y)) { 1.314 + t=Math.floor(p[0].x+m[0]*(sl-p[0].y)); 1.315 + if(t<xmin[i]) xmin[i]=Math.floor(t); 1.316 + else if(t>xmax[i]) xmax[i]=Math.floor(t); 1.317 + } 1.318 + if((sl>=p[1].y)&&(sl<=p[2].y)) { 1.319 + t=Math.floor(p[1].x+m[2]*(sl-p[1].y)); 1.320 + if(t<xmin[i]) xmin[i]=Math.floor(t); 1.321 + else if(t>xmax[i]) xmax[i]=Math.floor(t); 1.322 + } 1.323 + for(j=0;j<scn.w;j++) 1.324 + if((j>=(xmin[i]-scn.l))&&(j<=(xmax[i]-scn.l))) { 1.325 + scn.bfr[i][j].d=true; scn.bfr[i][j].c=c; 1.326 + } 1.327 + } 1.328 +} 1.329 +function S_light() { 1.330 + this.x=0; this.y=1; this.z=0; this.w=1; // original coordinates 1.331 + this.t=new S_vec3D(0,1,0); // transformed coordinates 1.332 + this.tm=new S_matrix(); 1.333 +} 1.334 +S_scene.prototype.S_adjustLight=function() { 1.335 + var m=this.lght.tm, l=this.lght; 1.336 + l.t.x=l.x*m[0]+l.y*m[4]+ l.z*m[8]+l.w*m[12]; 1.337 + l.t.y=l.x*m[1]+l.y*m[5]+ l.z*m[9]+l.w*m[13]; 1.338 + l.t.z=l.x*m[2]+l.y*m[6]+ l.z*m[10]+l.w*m[14]; 1.339 + l.t=S_normalizeVec3D(l.t); 1.340 +} 1.341 +S_scene.prototype.S_lightRotateX=function(a) { 1.342 + S_rotate(this.lght.tm,"x",a*=S_deg2Rad); 1.343 +} 1.344 +S_scene.prototype.S_lightRotateY=function(a) { 1.345 + S_rotate(this.lght.tm,"y",a*=S_deg2Rad); 1.346 +} 1.347 +S_scene.prototype.S_lightRotateZ=function(a) { 1.348 + S_rotate(this.lght.tm,"z",a*=S_deg2Rad); 1.349 +} 1.350 +S_scene.prototype.S_clearBuffer=function() { 1.351 + for(var i=0;i<this.h;i++) 1.352 + for(var j=0;j<this.w;j++) this.bfr[i][j].d=false; 1.353 +} 1.354 +function S_divString(b,t,l,h,w) { 1.355 + var s='<div style="background-color:'+b+';position:absolute;'; 1.356 + s+='top:'+t+'px;left:'+l+'px;height:'+h+'px;width:'+w; 1.357 + return s+'px;font-size:0;visibility:visible"></div>'; 1.358 +} 1.359 +function S_writeInnerHTML(id,text) { 1.360 + document.getElementById(id).innerHTML = text; 1.361 +} 1.362 +</script> 1.363 +</head> 1.364 +<body> 1.365 +<div class="z1" id="graphicsDiv">Text to be replaced with graphics.</div> 1.366 +<script type="text/javascript"> 1.367 +if(S_checkBrowser()) { 1.368 +var intrvl; 1.369 +// Create a new scene with parameters for 1.370 +// div id, left, top, width, height, and camera distance 1.371 +var scn=new S_scene("graphicsDiv",75,25,100,100,300); 1.372 +scn.S_pixelSize(3); // set scene pixel size 1.373 +var c=S_rgbColor(0,0,127); // color 1.374 +var c2=S_rgbColor(0,127,127); // color 1.375 +var m=new S_cube(18,c); // model 1.376 +m.S_faceColor(4,c2); 1.377 +m.S_faceColor(5,c2); 1.378 +m.S_scaleX(2.5); // scale model along x axis 1.379 +scn.S_models(m); // add model(s) to scene 1.380 +scn.S_lightRotateX(-25); // adjust light 1.381 +function r(){ // rotation function 1.382 +m.S_rotateX(11); // rotate model around y axis 1.383 +m.S_rotateY(5); // rotate model around y axis 1.384 +m.S_rotateZ(7); // rotate model around z axis 1.385 +scn.S_display(); // display scene 1.386 +} // end rotation function 1.387 +intrvl=setInterval('r();',75); 1.388 +} 1.389 +</script> 1.390 + 1.391 +</body> 1.392 +</html> 1.393 +