Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / worker / bomb-subtests / 3d-cube.js
1 // 3D Cube Rotation
2 // http://www.speich.net/computer/moztesting/3d.htm
3 // Created by Simon Speich
4
5 var Q = new Array();
6 var MTrans = new Array();  // transformation matrix
7 var MQube = new Array();  // position information of qube
8 var I = new Array();      // entity matrix
9 var Origin = new Object();
10 var Testing = new Object();
11 var LoopTimer;
12
13 var validation = {
14  20: 2889.0000000000045,
15  40: 2889.0000000000055,
16  80: 2889.000000000005,
17  160: 2889.0000000000055
18 };
19
20 var DisplArea = new Object();
21 DisplArea.Width = 300;
22 DisplArea.Height = 300;
23
24 function DrawLine(From, To) {
25   var x1 = From.V[0];
26   var x2 = To.V[0];
27   var y1 = From.V[1];
28   var y2 = To.V[1];
29   var dx = Math.abs(x2 - x1);
30   var dy = Math.abs(y2 - y1);
31   var x = x1;
32   var y = y1;
33   var IncX1, IncY1;
34   var IncX2, IncY2;  
35   var Den;
36   var Num;
37   var NumAdd;
38   var NumPix;
39
40   if (x2 >= x1) {  IncX1 = 1; IncX2 = 1;  }
41   else { IncX1 = -1; IncX2 = -1; }
42   if (y2 >= y1)  {  IncY1 = 1; IncY2 = 1; }
43   else { IncY1 = -1; IncY2 = -1; }
44   if (dx >= dy) {
45     IncX1 = 0;
46     IncY2 = 0;
47     Den = dx;
48     Num = dx / 2;
49     NumAdd = dy;
50     NumPix = dx;
51   }
52   else {
53     IncX2 = 0;
54     IncY1 = 0;
55     Den = dy;
56     Num = dy / 2;
57     NumAdd = dx;
58     NumPix = dy;
59   }
60
61   NumPix = Math.round(Q.LastPx + NumPix);
62
63   var i = Q.LastPx;
64   for (; i < NumPix; i++) {
65     Num += NumAdd;
66     if (Num >= Den) {
67       Num -= Den;
68       x += IncX1;
69       y += IncY1;
70     }
71     x += IncX2;
72     y += IncY2;
73   }
74   Q.LastPx = NumPix;
75 }
76
77 function CalcCross(V0, V1) {
78   var Cross = new Array();
79   Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];
80   Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];
81   Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];
82   return Cross;
83 }
84
85 function CalcNormal(V0, V1, V2) {
86   var A = new Array();   var B = new Array(); 
87   for (var i = 0; i < 3; i++) {
88     A[i] = V0[i] - V1[i];
89     B[i] = V2[i] - V1[i];
90   }
91   A = CalcCross(A, B);
92   var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); 
93   for (var i = 0; i < 3; i++) A[i] = A[i] / Length;
94   A[3] = 1;
95   return A;
96 }
97
98 function CreateP(X,Y,Z) {
99   this.V = [X,Y,Z,1];
100 }
101
102 // multiplies two matrices
103 function MMulti(M1, M2) {
104   var M = [[],[],[],[]];
105   var i = 0;
106   var j = 0;
107   for (; i < 4; i++) {
108     j = 0;
109     for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j];
110   }
111   return M;
112 }
113
114 //multiplies matrix with vector
115 function VMulti(M, V) {
116   var Vect = new Array();
117   var i = 0;
118   for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3];
119   return Vect;
120 }
121
122 function VMulti2(M, V) {
123   var Vect = new Array();
124   var i = 0;
125   for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];
126   return Vect;
127 }
128
129 // add to matrices
130 function MAdd(M1, M2) {
131   var M = [[],[],[],[]];
132   var i = 0;
133   var j = 0;
134   for (; i < 4; i++) {
135     j = 0;
136     for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];
137   }
138   return M;
139 }
140
141 function Translate(M, Dx, Dy, Dz) {
142   var T = [
143   [1,0,0,Dx],
144   [0,1,0,Dy],
145   [0,0,1,Dz],
146   [0,0,0,1]
147   ];
148   return MMulti(T, M);
149 }
150
151 function RotateX(M, Phi) {
152   var a = Phi;
153   a *= Math.PI / 180;
154   var Cos = Math.cos(a);
155   var Sin = Math.sin(a);
156   var R = [
157   [1,0,0,0],
158   [0,Cos,-Sin,0],
159   [0,Sin,Cos,0],
160   [0,0,0,1]
161   ];
162   return MMulti(R, M);
163 }
164
165 function RotateY(M, Phi) {
166   var a = Phi;
167   a *= Math.PI / 180;
168   var Cos = Math.cos(a);
169   var Sin = Math.sin(a);
170   var R = [
171   [Cos,0,Sin,0],
172   [0,1,0,0],
173   [-Sin,0,Cos,0],
174   [0,0,0,1]
175   ];
176   return MMulti(R, M);
177 }
178
179 function RotateZ(M, Phi) {
180   var a = Phi;
181   a *= Math.PI / 180;
182   var Cos = Math.cos(a);
183   var Sin = Math.sin(a);
184   var R = [
185   [Cos,-Sin,0,0],
186   [Sin,Cos,0,0],
187   [0,0,1,0],   
188   [0,0,0,1]
189   ];
190   return MMulti(R, M);
191 }
192
193 function DrawQube() {
194   // calc current normals
195   var CurN = new Array();
196   var i = 5;
197   Q.LastPx = 0;
198   for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);
199   if (CurN[0][2] < 0) {
200     if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };
201     if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };
202     if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };
203     if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };
204   }
205   if (CurN[1][2] < 0) {
206     if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };
207     if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };
208     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
209     if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };
210   }
211   if (CurN[2][2] < 0) {
212     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
213     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
214     if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
215     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
216   }
217   if (CurN[3][2] < 0) {
218     if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
219     if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };
220     if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };
221     if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };
222   }
223   if (CurN[4][2] < 0) {
224     if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };
225     if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };
226     if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };
227     if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
228   }
229   if (CurN[5][2] < 0) {
230     if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };
231     if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
232     if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };
233     if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };
234   }
235   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
236   Q.LastPx = 0;
237 }
238
239 function Loop() {
240   if (Testing.LoopCount > Testing.LoopMax) return;
241   var TestingStr = String(Testing.LoopCount);
242   while (TestingStr.length < 3) TestingStr = "0" + TestingStr;
243   MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);
244   MTrans = RotateX(MTrans, 1);
245   MTrans = RotateY(MTrans, 3);
246   MTrans = RotateZ(MTrans, 5);
247   MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);
248   MQube = MMulti(MTrans, MQube);
249   var i = 8;
250   for (; i > -1; i--) {
251     Q[i].V = VMulti(MTrans, Q[i].V);
252   }
253   DrawQube();
254   Testing.LoopCount++;
255   Loop();
256 }
257
258 function Init(CubeSize) {
259   // init/reset vars
260   Origin.V = [150,150,20,1];
261   Testing.LoopCount = 0;
262   Testing.LoopMax = 50;
263   Testing.TimeMax = 0;
264   Testing.TimeAvg = 0;
265   Testing.TimeMin = 0;
266   Testing.TimeTemp = 0;
267   Testing.TimeTotal = 0;
268   Testing.Init = false;
269
270   // transformation matrix
271   MTrans = [
272   [1,0,0,0],
273   [0,1,0,0],
274   [0,0,1,0],
275   [0,0,0,1]
276   ];
277   
278   // position information of qube
279   MQube = [
280   [1,0,0,0],
281   [0,1,0,0],
282   [0,0,1,0],
283   [0,0,0,1]
284   ];
285   
286   // entity matrix
287   I = [
288   [1,0,0,0],
289   [0,1,0,0],
290   [0,0,1,0],
291   [0,0,0,1]
292   ];
293   
294   // create qube
295   Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);
296   Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);
297   Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);
298   Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);
299   Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);
300   Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);
301   Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);
302   Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);
303   
304   // center of gravity
305   Q[8] = new CreateP(0, 0, 0);
306   
307   // anti-clockwise edge check
308   Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];
309   
310   // calculate squad normals
311   Q.Normal = new Array();
312   for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V);
313   
314   // line drawn ?
315   Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
316   
317   // create line pixels
318   Q.NumPx = 9 * 2 * CubeSize;
319   for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);
320   
321   MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);
322   MQube = MMulti(MTrans, MQube);
323
324   var i = 0;
325   for (; i < 9; i++) {
326     Q[i].V = VMulti(MTrans, Q[i].V);
327   }
328   DrawQube();
329   Testing.Init = true;
330   Loop();
331   
332   // Perform a simple sum-based verification.
333   var sum = 0;
334   for (var i = 0; i < Q.length; ++i) {
335     var vector = Q[i].V;
336     for (var j = 0; j < vector.length; ++j)
337       sum += vector[j];
338   }
339   if (sum != validation[CubeSize])
340     throw "Error: bad vector sum for CubeSize = " + CubeSize + "; expected " + validation[CubeSize] + " but got " + sum;
341 }
342
343 for ( var i = 20; i <= 160; i *= 2 ) {
344   Init(i);
345 }
346
347 Q = null;
348 MTrans = null;
349 MQube = null;
350 I = null;
351 Origin = null;
352 Testing = null;
353 LoopTime = null;
354 DisplArea = null;
355
356 postMessage("done");
357 close();