blob: 1143aac25464bed6d87261ac4d35479a8dc0ef4e [file] [log] [blame]
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zeroxlab.kubench;
import org.zeroxlab.zeroxbenchmark.Tester;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import java.util.Random;
public class Kubench extends Tester implements GLSurfaceView.GLSurfaceViewClient {
public final String TAG = "Kubench";
public final static String PACKAGE = "org.zeroxlab.kubench";
public String getTag() {
return TAG;
}
public static String getFullClassName() {
return PACKAGE + ".Kubench";
}
public int sleepBeforeStart() {
return 1000; //1 second
}
public int sleepBetweenRound() {
return 0;
}
public void oneRound() {
// do nothing;
}
private GLWorld makeGLWorld()
{
GLWorld world = new GLWorld();
int one = 0x10000;
int half = 0x08000;
GLColor red = new GLColor(one, 0, 0);
GLColor green = new GLColor(0, one, 0);
GLColor blue = new GLColor(0, 0, one);
GLColor yellow = new GLColor(one, one, 0);
GLColor orange = new GLColor(one, half, 0);
GLColor white = new GLColor(one, one, one);
GLColor black = new GLColor(0, 0, 0);
// coordinates for our cubes
float c0 = -1.0f;
float c1 = -0.38f;
float c2 = -0.32f;
float c3 = 0.32f;
float c4 = 0.38f;
float c5 = 1.0f;
// top back, left to right
mCubes[0] = new Cube(world, c0, c4, c0, c1, c5, c1);
mCubes[1] = new Cube(world, c2, c4, c0, c3, c5, c1);
mCubes[2] = new Cube(world, c4, c4, c0, c5, c5, c1);
// top middle, left to right
mCubes[3] = new Cube(world, c0, c4, c2, c1, c5, c3);
mCubes[4] = new Cube(world, c2, c4, c2, c3, c5, c3);
mCubes[5] = new Cube(world, c4, c4, c2, c5, c5, c3);
// top front, left to right
mCubes[6] = new Cube(world, c0, c4, c4, c1, c5, c5);
mCubes[7] = new Cube(world, c2, c4, c4, c3, c5, c5);
mCubes[8] = new Cube(world, c4, c4, c4, c5, c5, c5);
// middle back, left to right
mCubes[9] = new Cube(world, c0, c2, c0, c1, c3, c1);
mCubes[10] = new Cube(world, c2, c2, c0, c3, c3, c1);
mCubes[11] = new Cube(world, c4, c2, c0, c5, c3, c1);
// middle middle, left to right
mCubes[12] = new Cube(world, c0, c2, c2, c1, c3, c3);
mCubes[13] = null;
mCubes[14] = new Cube(world, c4, c2, c2, c5, c3, c3);
// middle front, left to right
mCubes[15] = new Cube(world, c0, c2, c4, c1, c3, c5);
mCubes[16] = new Cube(world, c2, c2, c4, c3, c3, c5);
mCubes[17] = new Cube(world, c4, c2, c4, c5, c3, c5);
// bottom back, left to right
mCubes[18] = new Cube(world, c0, c0, c0, c1, c1, c1);
mCubes[19] = new Cube(world, c2, c0, c0, c3, c1, c1);
mCubes[20] = new Cube(world, c4, c0, c0, c5, c1, c1);
// bottom middle, left to right
mCubes[21] = new Cube(world, c0, c0, c2, c1, c1, c3);
mCubes[22] = new Cube(world, c2, c0, c2, c3, c1, c3);
mCubes[23] = new Cube(world, c4, c0, c2, c5, c1, c3);
// bottom front, left to right
mCubes[24] = new Cube(world, c0, c0, c4, c1, c1, c5);
mCubes[25] = new Cube(world, c2, c0, c4, c3, c1, c5);
mCubes[26] = new Cube(world, c4, c0, c4, c5, c1, c5);
// paint the sides
int i, j;
// set all faces black by default
for (i = 0; i < 27; i++) {
Cube cube = mCubes[i];
if (cube != null) {
for (j = 0; j < 6; j++)
cube.setFaceColor(j, black);
}
}
// paint top
for (i = 0; i < 9; i++)
mCubes[i].setFaceColor(Cube.kTop, orange);
// paint bottom
for (i = 18; i < 27; i++)
mCubes[i].setFaceColor(Cube.kBottom, red);
// paint left
for (i = 0; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kLeft, yellow);
// paint right
for (i = 2; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kRight, white);
// paint back
for (i = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kBack, blue);
// paint front
for (i = 6; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kFront, green);
for (i = 0; i < 27; i++)
if (mCubes[i] != null)
world.addShape(mCubes[i]);
// initialize our permutation to solved position
mPermutation = new int[27];
for (i = 0; i < mPermutation.length; i++)
mPermutation[i] = i;
createLayers();
updateLayers();
world.generate();
return world;
}
private void createLayers() {
mLayers[kUp] = new Layer(Layer.kAxisY);
mLayers[kDown] = new Layer(Layer.kAxisY);
mLayers[kLeft] = new Layer(Layer.kAxisX);
mLayers[kRight] = new Layer(Layer.kAxisX);
mLayers[kFront] = new Layer(Layer.kAxisZ);
mLayers[kBack] = new Layer(Layer.kAxisZ);
mLayers[kMiddle] = new Layer(Layer.kAxisX);
mLayers[kEquator] = new Layer(Layer.kAxisY);
mLayers[kSide] = new Layer(Layer.kAxisZ);
}
private void updateLayers() {
Layer layer;
GLShape[] shapes;
int i, j, k;
// up layer
layer = mLayers[kUp];
shapes = layer.mShapes;
for (i = 0; i < 9; i++)
shapes[i] = mCubes[mPermutation[i]];
// down layer
layer = mLayers[kDown];
shapes = layer.mShapes;
for (i = 18, k = 0; i < 27; i++)
shapes[k++] = mCubes[mPermutation[i]];
// left layer
layer = mLayers[kLeft];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// right layer
layer = mLayers[kRight];
shapes = layer.mShapes;
for (i = 2, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// front layer
layer = mLayers[kFront];
shapes = layer.mShapes;
for (i = 6, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
// back layer
layer = mLayers[kBack];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
// middle layer
layer = mLayers[kMiddle];
shapes = layer.mShapes;
for (i = 1, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// equator layer
layer = mLayers[kEquator];
shapes = layer.mShapes;
for (i = 9, k = 0; i < 18; i++)
shapes[k++] = mCubes[mPermutation[i]];
// side layer
layer = mLayers[kSide];
shapes = layer.mShapes;
for (i = 3, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
}
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
// Make sure to create a TRANSLUCENT window. This is required
// for SurfaceView to work. Eventually this'll be done by
// the system automatically.
getWindow().setFormat(PixelFormat.TRANSLUCENT);
// We don't need a title either.
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setTitle(TAG);
mView = new GLSurfaceView(getApplication(), makeGLWorld(), this);
setContentView(mView);
mView.setClient(this);
mPrevFramerate = 0.0f;
}
@Override
protected void onResume()
{
super.onResume();
}
@Override
protected void onStop()
{
super.onStop();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_BACK:
return super.onKeyDown(keyCode, event);
}
setTitle("Kubench: " + mView.getFramerate() + " fps");
return true;
}
public void animate() {
// change our angle of view
mView.setAngle(mView.getAngle() + 1.2f);
if (mCurrentLayer == null) {
int layerID = mRandom.nextInt(9);
mCurrentLayer = mLayers[layerID];
mCurrentLayerPermutation = mLayerPermutations[layerID];
mCurrentLayer.startAnimation();
boolean direction = mRandom.nextBoolean();
int count = mRandom.nextInt(3) + 1;
count = 1;
direction = false;
mCurrentAngle = 0;
if (direction) {
mAngleIncrement = (float)Math.PI / 50;
mEndAngle = mCurrentAngle + ((float)Math.PI * count) / 2f;
} else {
mAngleIncrement = -(float)Math.PI / 50;
mEndAngle = mCurrentAngle - ((float)Math.PI * count) / 2f;
}
}
mCurrentAngle += mAngleIncrement;
if ((mAngleIncrement > 0f && mCurrentAngle >= mEndAngle) ||
(mAngleIncrement < 0f && mCurrentAngle <= mEndAngle)) {
mCurrentLayer.setAngle(mEndAngle);
mCurrentLayer.endAnimation();
mCurrentLayer = null;
// adjust mPermutation based on the completed layer rotation
int[] newPermutation = new int[27];
for (int i = 0; i < 27; i++) {
newPermutation[i] = mPermutation[mCurrentLayerPermutation[i]];
// newPermutation[i] = mCurrentLayerPermutation[mPermutation[i]];
}
mPermutation = newPermutation;
updateLayers();
} else {
mCurrentLayer.setAngle(mCurrentAngle);
}
if (mPrevFramerate != mView.getFramerate()) {
mPrevFramerate = mView.getFramerate();
// setTitle(mPrevFramerate + "fps");
//Log.v("Kubench", mPrevFramerate + "fps");
}
}
GLSurfaceView mView;
Cube[] mCubes = new Cube[27];
// a Layer for each possible move
Layer[] mLayers = new Layer[9];
// permutations corresponding to a pi/2 rotation of each layer about its axis
static int[][] mLayerPermutations = {
// permutation for UP layer
{ 2, 5, 8, 1, 4, 7, 0, 3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for DOWN layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 23, 26, 19, 22, 25, 18, 21, 24 },
// permutation for LEFT layer
{ 6, 1, 2, 15, 4, 5, 24, 7, 8, 3, 10, 11, 12, 13, 14, 21, 16, 17, 0, 19, 20, 9, 22, 23, 18, 25, 26 },
// permutation for RIGHT layer
{ 0, 1, 8, 3, 4, 17, 6, 7, 26, 9, 10, 5, 12, 13, 14, 15, 16, 23, 18, 19, 2, 21, 22, 11, 24, 25, 20 },
// permutation for FRONT layer
{ 0, 1, 2, 3, 4, 5, 24, 15, 6, 9, 10, 11, 12, 13, 14, 25, 16, 7, 18, 19, 20, 21, 22, 23, 26, 17, 8 },
// permutation for BACK layer
{ 18, 9, 0, 3, 4, 5, 6, 7, 8, 19, 10, 1, 12, 13, 14, 15, 16, 17, 20, 11, 2, 21, 22, 23, 24, 25, 26 },
// permutation for MIDDLE layer
{ 0, 7, 2, 3, 16, 5, 6, 25, 8, 9, 4, 11, 12, 13, 14, 15, 22, 17, 18, 1, 20, 21, 10, 23, 24, 19, 26 },
// permutation for EQUATOR layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 17, 10, 13, 16, 9, 12, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for SIDE layer
{ 0, 1, 2, 21, 12, 3, 6, 7, 8, 9, 10, 11, 22, 13, 4, 15, 16, 17, 18, 19, 20, 23, 14, 5, 24, 25, 26 }
};
// current permutation of starting position
int[] mPermutation;
// for random cube movements
Random mRandom = new Random(System.currentTimeMillis());
// currently turning layer
Layer mCurrentLayer = null;
// current and final angle for current Layer animation
float mCurrentAngle, mEndAngle;
// amount to increment angle
float mAngleIncrement;
int[] mCurrentLayerPermutation;
float mPrevFramerate;
// names for our 9 layers (based on notation from http://www.cubefreak.net/notation.html)
static final int kUp = 0;
static final int kDown = 1;
static final int kLeft = 2;
static final int kRight = 3;
static final int kFront = 4;
static final int kBack = 5;
static final int kMiddle = 6;
static final int kEquator = 7;
static final int kSide = 8;
}