4
Copyright (C) 2007 Apple Inc. All rights reserved.
6
Redistribution and use in source and binary forms, with or without
7
modification, are permitted provided that the following conditions
9
1. Redistributions of source code must retain the above copyright
10
notice, this list of conditions and the following disclaimer.
11
2. Redistributions in binary form must reproduce the above copyright
12
notice, this list of conditions and the following disclaimer in the
13
documentation and/or other materials provided with the distribution.
15
THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
<title>SunSpider 3d-cube</title>
39
var _sunSpiderStartDate = new Date();
42
// http://www.speich.net/computer/moztesting/3d.htm
43
// Created by Simon Speich
46
var MTrans = new Array(); // transformation matrix
47
var MQube = new Array(); // position information of qube
48
var I = new Array(); // entity matrix
49
var Origin = new Object();
50
var Testing = new Object();
53
var DisplArea = new Object();
54
DisplArea.Width = 300;
55
DisplArea.Height = 300;
57
function DrawLine(From, To) {
62
var dx = Math.abs(x2 - x1);
63
var dy = Math.abs(y2 - y1);
73
if (x2 >= x1) { IncX1 = 1; IncX2 = 1; }
74
else { IncX1 = -1; IncX2 = -1; }
75
if (y2 >= y1) { IncY1 = 1; IncY2 = 1; }
76
else { IncY1 = -1; IncY2 = -1; }
94
NumPix = Math.round(Q.LastPx + NumPix);
97
for (; i < NumPix; i++) {
110
function CalcCross(V0, V1) {
111
var Cross = new Array();
112
Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];
113
Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];
114
Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];
118
function CalcNormal(V0, V1, V2) {
119
var A = new Array(); var B = new Array();
120
for (var i = 0; i < 3; i++) {
121
A[i] = V0[i] - V1[i];
122
B[i] = V2[i] - V1[i];
125
var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]);
126
for (var i = 0; i < 3; i++) A[i] = A[i] / Length;
131
function CreateP(X,Y,Z) {
135
// multiplies two matrices
136
function MMulti(M1, M2) {
137
var M = [[],[],[],[]];
142
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];
147
//multiplies matrix with vector
148
function VMulti(M, V) {
149
var Vect = new Array();
151
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];
155
function VMulti2(M, V) {
156
var Vect = new Array();
158
for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];
163
function MAdd(M1, M2) {
164
var M = [[],[],[],[]];
169
for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];
174
function Translate(M, Dx, Dy, Dz) {
184
function RotateX(M, Phi) {
187
var Cos = Math.cos(a);
188
var Sin = Math.sin(a);
198
function RotateY(M, Phi) {
201
var Cos = Math.cos(a);
202
var Sin = Math.sin(a);
212
function RotateZ(M, Phi) {
215
var Cos = Math.cos(a);
216
var Sin = Math.sin(a);
226
function DrawQube() {
227
// calc current normals
228
var CurN = new Array();
231
for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);
232
if (CurN[0][2] < 0) {
233
if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };
234
if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };
235
if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };
236
if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };
238
if (CurN[1][2] < 0) {
239
if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };
240
if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };
241
if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
242
if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };
244
if (CurN[2][2] < 0) {
245
if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
246
if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
247
if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
248
if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
250
if (CurN[3][2] < 0) {
251
if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
252
if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };
253
if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };
254
if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };
256
if (CurN[4][2] < 0) {
257
if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };
258
if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };
259
if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };
260
if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
262
if (CurN[5][2] < 0) {
263
if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };
264
if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
265
if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };
266
if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };
268
Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
273
if (Testing.LoopCount > Testing.LoopMax) return;
274
var TestingStr = String(Testing.LoopCount);
275
while (TestingStr.length < 3) TestingStr = "0" + TestingStr;
276
MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);
277
MTrans = RotateX(MTrans, 1);
278
MTrans = RotateY(MTrans, 3);
279
MTrans = RotateZ(MTrans, 5);
280
MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);
281
MQube = MMulti(MTrans, MQube);
283
for (; i > -1; i--) {
284
Q[i].V = VMulti(MTrans, Q[i].V);
291
function Init(CubeSize) {
293
Origin.V = [150,150,20,1];
294
Testing.LoopCount = 0;
295
Testing.LoopMax = 50;
299
Testing.TimeTemp = 0;
300
Testing.TimeTotal = 0;
301
Testing.Init = false;
303
// transformation matrix
311
// position information of qube
328
Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);
329
Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);
330
Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);
331
Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);
332
Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);
333
Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);
334
Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);
335
Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);
338
Q[8] = new CreateP(0, 0, 0);
340
// anti-clockwise edge check
341
Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];
343
// calculate squad normals
344
Q.Normal = new Array();
345
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);
348
Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
350
// create line pixels
351
Q.NumPx = 9 * 2 * CubeSize;
352
for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);
354
MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);
355
MQube = MMulti(MTrans, MQube);
359
Q[i].V = VMulti(MTrans, Q[i].V);
366
for ( var i = 20; i <= 160; i *= 2 ) {
380
var _sunSpiderInterval = new Date() - _sunSpiderStartDate;
382
document.getElementById("console").innerHTML = _sunSpiderInterval;