build/pgo/js-input/3d-thingy.html

changeset 0
6474c204b198
     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 +

mercurial