[Android Software Development] Metastable:
Build update

Let's get straight to it! I have finished the LED Mau5Head!

Now for the details of how it was built. The entire face is made up of 762 of my Led objects, manually arranged into position, handcrafted to give the best effect. At first I wasn't sure how many Leds, what the arrangement should be, etc. So, I went onto my trusty resource, Google, to look for some images to steer me into the right direction.

I had remembered watching a video some time ago of a guy interviewing Joel(DeadMau5) before a show and in the video series they show the Mau5Head turned on, on top of a box. I found the video but it wasn't the greatest amount of help in figuring out how many LEDs were being used, they never showed a full frontal view of it. Here's the video if your interested in seeing it, here.

With some further searching to see if there were any static images of the Mau5Head I came across something extremely helpful. This image:

A guy from UIProductions worked on a replica of the LED Mau5Head under commission, I suggest checking the awesome project out! I decided to use his LED layout as my basis for the Led array I was going to use.

With the LED face completed, I set out to create the backing of the face which would contain the actual ears and the blue glow strip around them. I first made a primitive circle with this piece of code I made up:

public Circle(float radius, int points) {
vertices = new float[points * 3 + 3];
indices = new short[points * 3];

float theta = (float)Math.PI * 2 / (points);
int length = vertices.length;

int index = 0;
for (int i = 0; i < points; i++) {
vertices[i * 3] = radius * (float)Math.cos(theta * i); //x
vertices[1 + i * 3] = radius * (float)Math.sin(theta * i); //y
vertices[2 + i * 3] = 0; //z

indices[index + 1] = (short)i;
indices[index] = (short)(points);
indices[index + 2] = (short)(i + 1);

index += 3;
}

vertices[length - 3] = 0f;
vertices[length - 2] = 0f;
vertices[length - 1] = 0f;

indices[indices.length - 1] = 0;
}

It may not be the best piece of coding, but it gets the job done. It gives you the vertices and the indices necessary to create a circle with the given radius and as many points as you would like, as long as points stays within the short data type size. The nice thing about this is that you can create any shape, starting from a triangle, to a square, to a pentagon, all the way to an actual circle.

After getting the approximate size of the circle I wanted I then proceeded to handcraft the right ear. Once I had a decent looking ear I mirrored the right ear by making the x coordinates negative and fixing the indices where the ear connects to the circle. Here's my pencil drawing of the backing that I used to help guide me:

With that done I created another short[] index array for the blue lines that outline the ears. This was simple because I can reuse the vertices used for the ears and all I have to do is match the indices that I need.

And that's how I created my own LED Mau5Head, which goes well with my personal Mau5Head I made for past Halloween:

At the moment the Led face just displays a static image that I made to test it out. I haven't decided what I want to display on it, perhaps some animations of him talking, and then switching over to an equalizer, who knows what I will put on it! The next step is to make the visuals on the cube and tubes in back to rotate between different visuals to make it a little more exciting.

Release is getting nearer! Stay tuned and feel free to drop some comments and/or suggestions.

Edit: I forgot to mention that I created invisible buttons around the screen so that I can move around and zoom in and out of the scene so better adjust the positions of objects. Here's the relevant code:

@Override
public void onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_MOVE) {
//Log.d(TAG, event.toString());
float x = event.getX();
float y = event.getY();

if (x < 50 && y < 50)
renderer.touchMovement(0, 0, 0, 0, 0, .01f);
if (x > renderer.width - 50 && y < 50)
renderer.touchMovement(0, 0, 0, 0, 0, -.01f);
if (x > renderer.width / 2 - 25 && x < renderer.width / 2 + 25 && y < 50)
renderer.touchMovement(-1f, 0, 0, 0, 0, 0);
if (x > renderer.width / 2 - 25 && x < renderer.width / 2 + 25 && y > renderer.height - 50)
renderer.touchMovement(1f, 0, 0, 0, 0, 0);
if (x < 50 && y > renderer.height / 2 - 25 && y < renderer.height / 2 + 25)
renderer.touchMovement(0, -1f, 0, 0, 0, 0);
if (x > renderer.width - 50 && y > renderer.height / 2 - 25 && y < renderer.height / 2 + 25)
renderer.touchMovement(0, 1f, 0, 0, 0, 0);
if (x < 50 && y > renderer.height - 50)
renderer.touchMovement(0, 0, 0, 0, -.01f, 0);
if (x > renderer.width - 50 && y > renderer.height - 50)
renderer.touchMovement(0, 0, 0, 0, .01f, 0);
}
super.onTouchEvent(event);
}