demos\blackmajic\canvas\js\touch.js
  1  window.loadScript("parpevision.js")
  2  window.loadScript("touch_meshdata.js")
  3 
  4 function startTouch() {
  5   if(!widget.my_app) {
  6     widget.my_app=new TouchApp(widget)
  7   }
  8   else {
  9     widget.my_app.onInterval();
 10   }
 11 }
 12 function stopTouch() {
 13 
 14 }
 15 function TouchApp(cv)
 16 {
 17   var _this = this;
 18   this.mTickCount = 0;
 19   this.mLoadCount = 2;
 20 
 21   this.canvas = cv
 22   P3D.g = this.canvas.getContext("2d");
 23 
 24   this.vUP   = new Vec3(0, 1, 0);
 25   this.vAT   = new Vec3(0, 0, 0);
 26   this.mEye  = new Vec3(1, 0, 15);
 27   this.mEyeA = new Vec3(0, 0, 20);
 28 
 29   this.mViewport = {};
 30   this.mProjMat  = new M44();
 31   this.mWorldMat = new M44();
 32   this.mViewMat  = new M44();
 33   this.mAllMat   = new M44();
 34 
 35   this.ipod = new iPodModel(MESH_IPOD);
 36 
 37   var tex = new Image();
 38   this.ipod.texture = tex;
 39   tex.onload = function(){ _this.start(); };
 40   tex.src = "canvas/images/20090319144649.png";
 41 
 42   tex = new Image();
 43   this.texture2 = tex;
 44   tex.onload = function(){ _this.start(); };
 45   tex.src = "canvas/images/20090226031413.png";
 46 }
 47 
 48 TouchApp.prototype = {
 49   start: function() {
 50     if (--this.mLoadCount > 0) return;
 51     this.mViewport.w = this.canvas.width;
 52     this.mViewport.h = this.canvas.height;
 53     this.mViewport.ow = Math.round(this.canvas.width/2);
 54     this.mViewport.oh = Math.round(this.canvas.height/2);
 55     this.setupTransform();
 56     this.onInterval();
 57     var _this = this;
 58     this.canvas.addEventListener("mousemove", function(e){_this.onMouseMove(e);}, false);
 59   },
 60 
 61   onInterval: function() {
 62     if(this.canvas.showing) {
 63       this.mEye.smul(0.7);
 64       this.mEye.x += this.mEyeA.x * 0.3;
 65       this.mEye.y += this.mEyeA.y * 0.3;
 66       this.mEye.z += this.mEyeA.z * 0.3;
 67       this.updateViewTrans();
 68 
 69       this.mWorldMat.ident();
 70       this.calcAllTransforms();
 71       this.transformVertices(MESH_floor);
 72 
 73       this.mWorldMat.glRotate(0.14, 1, 0, 0);
 74       this.calcAllTransforms();
 75       this.transformVertices(this.ipod.mesh);
 76 
 77       P3D.clear("#000", this.mViewport.w, this.mViewport.h);
 78       this.drawFloor();
 79       this.ipod.render(this);
 80 
 81       this.mTickCount++;
 82       var _this = this;
 83       setTimeout(function(){_this.onInterval();}, 20);
 84     }
 85   },
 86 
 87   updateViewTrans: function(ry) {
 88     this.mViewMat.lookAtLH(this.vUP, this.mEye, this.vAT);
 89   },
 90 
 91   onMouseMove: function(e) {
 92     this.setEyePosTarget(e.clientX - this.mViewport.ow, e.clientY - this.mViewport.oh);
 93   },
 94 
 95   setEyePosTarget: function(tx, ty) {
 96     var R = 20;
 97     this.mEyeA.y = 30 - ty*0.4;
 98     if (this.mEyeA.y < -0.7) {
 99       R += -0.7 - this.mEyeA.y;
100       this.mEyeA.y = -0.7;
101     }
102     this.mEyeA.z = Math.cos(tx*0.02) * R;
103     this.mEyeA.x = Math.sin(tx*0.02) * R;
104   },
105 
106   setupTransform: function() {
107     this.mWorldMat.ident();
108     this.mProjMat.perspectiveLH(8, 5, 4, 900);
109     this.mViewMat.ident();
110   },
111 
112   calcAllTransforms: function() {
113     if (!this._mTmpMat) this._mTmpMat = new M44();
114     this._mTmpMat.mul(this.mWorldMat, this.mViewMat);
115     this.mAllMat.mul(this._mTmpMat, this.mProjMat);
116   },
117 
118   transformVertices: function(mesh) {
119     var i;
120     var m = this.mAllMat;
121     var hw = this.mViewport.ow;
122     var hh = this.mViewport.oh;
123 
124     if ((mesh.poss.length % 3) != 0)
125       throw "invalid length";
126 
127     var poss = mesh.poss;
128     var plen = poss.length/3;
129 
130     if (!mesh.tl_poss) {
131       mesh.tl_poss = new Array(plen * 4);
132     }
133     var tl_poss = mesh.tl_poss;
134 
135     var pi = 0, ti = 0, spos = new Array(4), p = new Vec3();
136     for (i = 0;i < plen;i++) {
137       p.x = poss[pi  ];
138       p.y = poss[pi+1];
139       p.z = poss[pi+2];
140       pi += 3;
141 
142       m.transVec3(spos, p.x, p.y, p.z);
143 
144       var W = spos[3];
145       spos[0] /= W;
146       spos[1] /= W;
147       spos[2] /= W;
148 
149       spos[0] *= this.mViewport.w;
150       spos[1] *= -this.mViewport.h;
151       spos[0] += hw;
152       spos[1] += hh;
153 
154       tl_poss[ti++] = spos[0];
155       tl_poss[ti++] = spos[1];
156       tl_poss[ti++] = spos[2];
157       ti++;
158     }
159   },
160 
161   drawFloor: function() {
162     P3D.texture = this.texture2;
163 // console.log(MESH_floor.tl_poss[2] + "  " + MESH_floor.tl_poss[6])
164     P3D.drawByIndexBuffer(MESH_floor.tl_poss, MESH_floor.face_groups[0], MESH_floor.texcoords, -1, true);
165   }
166 }
167 
168 function iPodModel(mesh) {
169   this.texture = null;
170   this.mesh = mesh;
171   this.uvbuf = new Array(124);
172   this.sphmap_uvbuf = new Array(124);
173 
174   this.uvbuf[112] = 0;
175   this.uvbuf[113] = 0;
176 
177   this.uvbuf[114] = 0;
178   this.uvbuf[115] = 0.875;
179 
180   this.uvbuf[116] = 0.3333;
181   this.uvbuf[117] = 0;
182 
183   this.uvbuf[118] = 0.3333;
184   this.uvbuf[119] = 0.875;
185 
186   this.uvbuf[120] = 0;
187   this.uvbuf[121] = 0.4375;
188 
189   this.uvbuf[122] = 0.3333;
190   this.uvbuf[123] = 0.4375;
191 }
192 
193 iPodModel.prototype = {
194   render: function(renderContext) {
195     P3D.texture = this.texture;
196     P3D.drawByIndexBuffer(this.mesh.tl_poss, this.mesh.face_groups[0], this.uvbuf, -1);
197 
198     this.setSphereMapUVs(2, renderContext);
199     P3D.drawByIndexBuffer(this.mesh.tl_poss, this.mesh.face_groups[2], this.sphmap_uvbuf, -1);
200     P3D.texture = null;
201 
202     var face_plate = this.mesh.face_groups[1];
203     var vi, i, len = face_plate.length;
204     for (i = 0;i < len;i += 3) {
205       vi = face_plate[i];
206       this.uvbuf[vi << 1] = "#000";
207     }
208 
209     P3D.drawByIndexBuffer(this.mesh.tl_poss, this.mesh.face_groups[1], this.uvbuf, -1);
210   },
211 
212   setSphereMapUVs: function(gi, renderContext) {
213     var faces = this.mesh.face_groups[gi];
214     var poss  = this.mesh.poss;
215     var i, len = faces.length/3;
216     var v0, v1, v2, vN, vNt;
217     var vlen = poss.length;
218 
219     if (!this.mesh.N_list) {
220 // generate N vector
221       vN = new Vec3();
222       var vA = new Vec3(), vB = new Vec3();
223       this.mesh.N_list = new Array( poss.length );
224 
225       for (i = 0;i < vlen;i++) {
226         this.mesh.N_list[i] = new Vec3(0, 0, 0);
227       }
228 
229       for (i = 0;i < len;i++) {
230         v0 = faces[i*3  ];
231         v1 = faces[i*3+1];
232         v2 = faces[i*3+2];
233 
234         vA.x = poss[v1*3  ] - poss[v0*3  ];
235         vA.y = poss[v1*3+1] - poss[v0*3+1];
236         vA.z = poss[v1*3+2] - poss[v0*3+2];
237 
238         vB.x = poss[v2*3  ] - poss[v1*3  ];
239         vB.y = poss[v2*3+1] - poss[v1*3+1];
240         vB.z = poss[v2*3+2] - poss[v1*3+2];
241 
242         vN.cp(vB, vA).normalize();
243 
244         this.mesh.N_list[v0].add(vN);
245         this.mesh.N_list[v1].add(vN);
246         this.mesh.N_list[v2].add(vN);
247       }
248 
249       for (i = 0;i < vlen;i++) {
250         this.mesh.N_list[i].normalize();
251       }
252 
253 // generate N vector
254     }
255 /*
256 for (i = 0;i < vlen;i++) {
257   vN = this.mesh.N_list[i];
258   this.sphmap_uvbuf[i<<1     ] = (vN.y < -0.3) ? "#700" : (vN.y < 0.2) ? "#a00" : (vN.y < 0.4) ? "#c00" : "#f00"
259 }
260 return;
261 */
262     var spos = [0,0,0,0];
263     var viewRot = (new M44()).copyFrom(renderContext.mViewMat).transpose33();
264     var worldRot = (new M44()).copyFrom(renderContext.mWorldMat);
265     viewRot._41 = viewRot._42 = viewRot._43 = 0;
266     viewRot.transVec3(spos, 0, 0, 1);
267 
268     var in_vector = (new Vec3(spos[0], spos[1], spos[2])).normalize();
269     var rN = new Vec3(), rlen;
270 
271     vN = new Vec3();
272     for (i = 0;i < vlen;i++) {
273       vNt = this.mesh.N_list[i];
274       worldRot.transVec3(spos, vNt.x, vNt.y, vNt.z);
275       vN.x = spos[0];
276       vN.y = spos[1];
277       vN.z = spos[2];
278 
279       rlen = vN.dpWith(in_vector) * -2;
280 
281       rN.copyFrom(in_vector);
282 
283       rN.x += vN.x * rlen;
284       rN.y += vN.y * rlen;
285       rN.z += vN.z * rlen;
286 
287       this.sphmap_uvbuf[i<<1     ] = rN.x/2*0.666 + 0.666666;
288       this.sphmap_uvbuf[(i<<1)+ 1] = -rN.y/2.01 + 0.5;
289     }
290   }
291 }
292 
293