Setting up a Rubik’s Cube in Papervision

Intro

Well it’s Christmas, and you’re right, one of the kids got a Rubik’s cube. And we’ve spent the entire break figuring it out – right down to the smallest child, even baby Na. It was a Rubik’s Cube free-for-all. And if that wasn’t enough, we had to make it virtual.

In this post, we’re going to show you a trick you can use to set up a Rubik’s Cube in just 8 lines of code. It uses the same trick that Mr. Doob uses on his blog – geometry.vertices. Below is an image of the cube you will make. Click on it to run the application.

Rubik's Cube (set up in 8 lines of code)

Rubik's Cube (set up in 8 lines of code)

Web Stuff

Demo

Download Source

YouTube Video – Coming!

Discussion

Essentially what you want to do is create a single large cube and use its vertices to anchor the smaller cubes to create the Rubik’s cube .

Using geometry.vertices to add cubes

Using geometry.vertices to add cubes

Large Cube

Segmenting the large cube with 2, 2, 2 (as shown in the image above)creates the coordinates of the Rubik’s cube

cubeGrid = new Cube(myMaterialsList1, mySize, mySize, mySize,2,2,2);

Placing small cubes at each vertex of the large cube is done using the geometry.vertices method.

Small Cubes

The geometry.vertices method gives you the position of each large cube vertex which is stored in the vertices array and accessed using the geometry.vertices method as shown below:

for(var i:int = 0; i<cubeGrid.geometry.vertices.length; i++)
{
var myPart:Cube = new Cube(materialArray[i], mySize/2.1,mySize/2.1,mySize/2.1,2,2,2);

myPart.x=cubeGrid.geometry.vertices[i].x;
myPart.y=cubeGrid.geometry.vertices[i].y;
myPart.z=cubeGrid.geometry.vertices[i].z;

particleArray.push(myPart);
myGraphicsHolder.addChild(myPart);
}

That’s really all there is to it, the only other thing you need to do is to set the faces of the small cubes to the appropriate Rubiks’s Cube colors using a materials list array (materialArray). Just click the more button below to see the complete code listing.

Note: This only sets the cube up. In the book, I show you how to program a fully functioning Rubik’s Cube.

Rubik’s Cube Set Up Source

package
{
//Flash imports
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;

import org.papervision3d.materials.*;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.view.BasicView;

//Create WirePlane class
public class RubiksCube extends BasicView
{
//Instantiate plane and wireframe material

private var cubeMaterial:WireframeMaterial;
private var myMaterialsList:MaterialsList;

private var myMaterialsList1:MaterialsList;
private var myMaterialsList2:MaterialsList;
private var myMaterialsList3:MaterialsList;
private var myMaterialsList4:MaterialsList;
private var myMaterialsList5:MaterialsList;
private var myMaterialsList6:MaterialsList;
private var myMaterialsList7:MaterialsList;
private var myMaterialsList8:MaterialsList;
private var myMaterialsList9:MaterialsList;
private var myMaterialsList10:MaterialsList;
private var myMaterialsList11:MaterialsList;
private var myMaterialsList12:MaterialsList;
private var myMaterialsList13:MaterialsList;
private var myMaterialsList14:MaterialsList;
private var myMaterialsList15:MaterialsList;
private var myMaterialsList16:MaterialsList;
private var myMaterialsList17:MaterialsList;
private var myMaterialsList18:MaterialsList;
private var myMaterialsList19:MaterialsList;
private var myMaterialsList20:MaterialsList;
private var myMaterialsList21:MaterialsList;
private var myMaterialsList22:MaterialsList;
private var myMaterialsList23:MaterialsList;
private var myMaterialsList24:MaterialsList;
private var myMaterialsList25:MaterialsList;
private var myMaterialsList26:MaterialsList;
private var myMaterialsList27:MaterialsList;

private var myGraphicsHolder:DisplayObject3D = new DisplayObject3D();
private var cubeGrid:Cube;

private var particleArray:Array = new Array();
private var materialArray:Array = new Array();

private var mySize:Number=100;

private var doRatate:Boolean=false;

private var oldMouseX:Number;
private var oldMouseY:Number;

private var oldRotX:Number=0;
private var oldRotY:Number=0;

public function RubiksCube()
{
//Call super
super(1, 1, true, false);
initPV3D();
startRendering();
}

//
protected function initPV3D():void
{
//Set Stage
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//Set the background to black
opaqueBackground = 0x5555ff;

// Create a wireframe material for the plane
cubeMaterial = new WireframeMaterial(0xFFFFFF);

//Add Material List
myMaterialsList1 = new MaterialsList();
myMaterialsList1.addMaterial( new ColorMaterial(0xffff00), “front” );
myMaterialsList1.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList1.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList1.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList1.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList1.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList2 = new MaterialsList();
myMaterialsList2.addMaterial( new ColorMaterial(0xffff00), “front” );
myMaterialsList2.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList2.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList2.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList2.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList2.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList3 = new MaterialsList();
myMaterialsList3.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList3.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList3.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList3.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList3.addMaterial( new ColorMaterial(0xff0000), “top” );
myMaterialsList3.addMaterial( new ColorMaterial(0×000000), “bottom” );

myMaterialsList4 = new MaterialsList();
myMaterialsList4.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList4.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList4.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList4.addMaterial( new ColorMaterial(0×000000), “right” );
myMaterialsList4.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList4.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList5 = new MaterialsList();
myMaterialsList5.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList5.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList5.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList5.addMaterial( new ColorMaterial(0×000000), “right” );
myMaterialsList5.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList5.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList6 = new MaterialsList();
myMaterialsList6.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList6.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList6.addMaterial(new ColorMaterial(0×000000), “left” );
myMaterialsList6.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList6.addMaterial(new ColorMaterial(0xff0000), “top” );
myMaterialsList6.addMaterial( new ColorMaterial(0×000000), “bottom” );

myMaterialsList7 = new MaterialsList();
myMaterialsList7.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList7.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList7.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList7.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList7.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList7.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList8 = new MaterialsList();
myMaterialsList8.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList8.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList8.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList8.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList8.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList8.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList9 = new MaterialsList();
myMaterialsList9.addMaterial(new ColorMaterial(0xffff00), “front” );
myMaterialsList9.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList9.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList9.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList9.addMaterial(new ColorMaterial(0xff0000), “top” );
myMaterialsList9.addMaterial( new ColorMaterial(0×000000), “bottom” );

myMaterialsList10 = new MaterialsList();
myMaterialsList10.addMaterial( new ColorMaterial(0×000000),”front” );
myMaterialsList10.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList10.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList10.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList10.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList10.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList11 = new MaterialsList();
myMaterialsList11.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList11.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList11.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList11.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList11.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList11.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList12 = new MaterialsList();
myMaterialsList12.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList12.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList12.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList12.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList12.addMaterial(new ColorMaterial(0xff0000), “top” );
myMaterialsList12.addMaterial( new ColorMaterial(0×000000), “bottom” );

myMaterialsList13 = new MaterialsList();
myMaterialsList13.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList13.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList13.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList13.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList13.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList13.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList14 = new MaterialsList();
myMaterialsList14.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList14.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList14.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList14.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList14.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList14.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList15 = new MaterialsList();
myMaterialsList15.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList15.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList15.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList15.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList15.addMaterial( new ColorMaterial(0xff0000), “top” );
myMaterialsList15.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList16 = new MaterialsList();
myMaterialsList16.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList16.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList16.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList16.addMaterial( new ColorMaterial(0x00ff00), “right” );
myMaterialsList16.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList16.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList17 = new MaterialsList();
myMaterialsList17.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList17.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList17.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList17.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList17.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList17.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList18 = new MaterialsList();
myMaterialsList18.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList18.addMaterial( new ColorMaterial(0xffffff) , “back” );
myMaterialsList18.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList18.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList18.addMaterial( new ColorMaterial(0xff0000), “top” );
myMaterialsList18.addMaterial( new ColorMaterial(0×000000), “bottom” );

myMaterialsList19 = new MaterialsList();
myMaterialsList19.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList19.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList19.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList19.addMaterial( new ColorMaterial(0x00ff00), “right” );
myMaterialsList19.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList19.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList20 = new MaterialsList();
myMaterialsList20.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList20.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList20.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList20.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList20.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList20.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList21 = new MaterialsList();
myMaterialsList21.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList21.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList21.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList21.addMaterial(new ColorMaterial(0x00ff00), “right” );
myMaterialsList21.addMaterial( new ColorMaterial(0xff0000), “top” );
myMaterialsList21.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList22 = new MaterialsList();
myMaterialsList22.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList22.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList22.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList22.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList22.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList22.addMaterial(new ColorMaterial(0xff6600), “bottom” );

myMaterialsList23 = new MaterialsList();
myMaterialsList23.addMaterial( new ColorMaterial(0×000000), “front” );
myMaterialsList23.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList23.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList23.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList23.addMaterial( new ColorMaterial(0×000000), “top” );
myMaterialsList23.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList24 = new MaterialsList();
myMaterialsList24.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList24.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList24.addMaterial( new ColorMaterial(0x0000ff), “left” );
myMaterialsList24.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList24.addMaterial(new ColorMaterial(0xff0000), “top” );
myMaterialsList24.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList25 = new MaterialsList();
myMaterialsList25.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList25.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList25.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList25.addMaterial(new ColorMaterial(0×000000), “right” );
myMaterialsList25.addMaterial(new ColorMaterial(0xff0000), “top” );
myMaterialsList25.addMaterial(new ColorMaterial(0×000000), “bottom” );

myMaterialsList26 = new MaterialsList();
myMaterialsList26.addMaterial(new ColorMaterial(0×000000), “front” );
myMaterialsList26.addMaterial( new ColorMaterial(0×000000) , “back” );
myMaterialsList26.addMaterial( new ColorMaterial(0×000000), “left” );
myMaterialsList26.addMaterial( new ColorMaterial(0×000000), “right” );
myMaterialsList26.addMaterial(new ColorMaterial(0×000000), “top” );
myMaterialsList26.addMaterial(new ColorMaterial(0xff6600), “bottom” );

materialArray=[myMaterialsList1, myMaterialsList2, myMaterialsList3,myMaterialsList4, myMaterialsList5, myMaterialsList6, myMaterialsList7, myMaterialsList8, myMaterialsList9, myMaterialsList10, myMaterialsList11, myMaterialsList12, myMaterialsList13, myMaterialsList14, myMaterialsList15, myMaterialsList16, myMaterialsList17, myMaterialsList18, myMaterialsList19, myMaterialsList20, myMaterialsList21, myMaterialsList22, myMaterialsList23, myMaterialsList24, myMaterialsList25, myMaterialsList26];

cubeMaterial.doubleSided=true;
//Add your wireframe to the scene

cubeGrid = new Cube(myMaterialsList1, mySize, mySize, mySize,2,2,2);

for(var i:int = 0; i<cubeGrid.geometry.vertices.length; i++)
{

var myPart:Cube = new Cube(materialArray[i], mySize/2.1,mySize/2.1,mySize/2.1,2,2,2);

myPart.x=cubeGrid.geometry.vertices[i].x;
myPart.y=cubeGrid.geometry.vertices[i].y;
myPart.z=cubeGrid.geometry.vertices[i].z;

particleArray.push(myPart);
myGraphicsHolder.addChild(myPart);
}
// myGraphicsHolder.addChild(cubeGrid);

camera.focus=40;
camera.zoom=50;

scene.addChild(myGraphicsHolder);
stage.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent):void {doRatate=true;
oldMouseX=mouseX;
oldMouseY=mouseY;
});

stage.addEventListener(MouseEvent.MOUSE_UP,function(e:MouseEvent):void {doRatate=false;
oldRotX=myGraphicsHolder.rotationX;
oldRotY=myGraphicsHolder.rotationY;

});

}

// override onRenderTick so you can execute code
override protected function onRenderTick(event:Event=null):void
{

if(doRatate){

myGraphicsHolder.rotationY = (oldMouseX-mouseX+oldRotY);
myGraphicsHolder.rotationX = (oldMouseY-mouseY+oldRotX);

}

//Call the super.onRenderTick function
super.onRenderTick(event);
}

}
}

About these ads

14 Responses to Setting up a Rubik’s Cube in Papervision

  1. [...] positions of the planes can be positioned using the geometry.vertices method demonstrated in the previous blog post. But just using square planes looks a little disjointed as shown on the left of the image below. [...]

  2. Mike Lively says:

    Thanks for your reply – cubes not planes are positioned, but there is an artifact that arises at certain angles (around 30 degrees) due to the low segment number I am using for the cubes.

    There are a million solutions to this, but I’ve been concentrating on the math more.

    I used the cubes since I could more easily push them into an array and treat the whole thing as a particle system. Which greatly simplifies the math.

    Thanks again for the comment.

  3. [...] > Setting up a Rubik’s Cube in Papervision « Professional Papervision3D Book [...]

  4. Sami says:

    Hi, I’ve tried the codes, I have to say that this is brilliant! Im quite a newbie on papervision. I managed to make it work, and play around with the material face, etc. I’ve searched in Amazon for your book, and apparently its not published yet. I got this project to make this rubix stuff, is there any way you can give me an insight how to recognize each small cube, and group rotate them? Thanks before, two thumbs up for the code!

  5. Mike Lively says:

    You are in luck, I’m building this project out this weekend and will post the rest of the code – Monday or Tuesady…

  6. Sami says:

    Wow, brilliant mate, I’m having no luck how to group the cubes, and adding a MouseEvent on them. Still searching for the light of enlightenment on papervision :) . Hopefully you can finish out the project on weekend, really appreciate for the respond. Cheers.

  7. Sami says:

    Hi Mike, did you manage to sort out the rubix movement in the end? Cheers.

    • Mike Lively says:

      I’m on it, had a little delay (had to teach a seminar and get a chapter finished). It’s being programmed now-thanks for asking-it should be up this week. It’s in the chapter on particle systems (which I’m doing now), and I’m really excited about completing it!

  8. Sami says:

    thats kool Mike, I managed to do the mouseEvent combining codes from http://flashenabledblog.com/2008/03/24/papervision3d-20-interactive-cube/ .. I made an arrow button on each cube relevant to their position .. but still getting a wrong angle movement of the group of cubes … will happily waiting for your updates mate .. cheers

  9. Sami says:

    Mike, sorry to keep bothering, have any luck finishing the codes mate? Cant wait for your book! cheers

    • Mike Lively says:

      Yes, I worked with the cube and set up the interactive materials, and I was not that happy with all the work it took to get there. I’m considering doing the entire thing in CS4 as opposed to Papervision3D.

      CS4′s display objects are well behaved (where PV3D’s are not always that way)…I’m working on it and will post some code soon. Once you set it up in CS4 then its just a matter of keeping track of your cubes and rotating them based on matrix transformations.

      However, it may turn out that I may do a hybrid of both PV3D and CS4…thanks for your comment…I’m rushing to finish a chapter of the book, but should have something done this weekend. Sorry about the delay…

  10. Sami says:

    yeah I have problem with the rotationX, rotationY, rotationX on the PV3D. There is a position of the cubes that I want that cannot be done using those rotations. And the entire codes get really ugly and long just to do an automated rotation. I’ve also not quite understand on how to do the matrix transformation. Thank you for the reply, will be waiting faithfully for the codes and the book :). Cheers.

  11. Sami says:

    Hi Mike, is everything working alright?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: