
Now that your environment is set up to play with Away3D, let's create something! In my previous post, I concluded that you can now experiment, and so I did too. It turned out that there are some little intricacies about putting a simple image on a simple cube. Let's take a look.
Create a cube
This part has got to be the simplest, thanks to the nice API that the guys from Away3D built.
ActionScript 3.0:
package { import away3d.containers.View3D; import away3d.materials.ColorMaterial; import away3d.primitives.Cube; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; [SWF(frameRate="60", backgroundColor="#ffffff", width="640", height="360")] public class Main extends Sprite { // + ---------------------------------------- // [ VARS ] // + ---------------------------------------- private var _view3D :View3D; private var _cube :Cube; // + ---------------------------------------- // [ CONSTRUCTOR ] // + ---------------------------------------- public function Main() { super(); initStage(); addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); } // + ---------------------------------------- // [ PRIVATE METHODS ] // + ---------------------------------------- private function initStage():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; } private function init():void { // it is necessary to add a texture to the shape so it is visible var material:ColorMaterial = new ColorMaterial(0xffffff); // I personally prefer to set vars for repetitive values var cubeSize:uint = 240; _cube = new Cube(material, cubeSize, cubeSize, cubeSize); // add the 3D elements to the stage _view3D = new View3D(); _view3D.scene.addChild(_cube); addChild(_view3D); // add a listener so it becomes possible to render the 3D world addEventListener(Event.ENTER_FRAME, enterFrameHandler); } // + ---------------------------------------- // [ PRIVATE METHODS ] // + ---------------------------------------- private function addedToStageHandler(event:Event):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); init(); } private function enterFrameHandler(event:Event):void { // render the 3D world _view3D.render(); } } }
With this code, this is what you should get as a result:

Not exactly exciting. For one, a ColorMaterial is really a flat color, so the best way to make it live a bit is adding light elements, which we will not see in this post (and that's also because I have not learned that yet). Also, we only see once face of the cube, quite boring.
To at least view that this object is in 3D, simply update the enterFrameHandler function.
ActionScript 3.0:
private function enterFrameHandler(event:Event):void { // increment the cube's rotation values to see its different sides _cube.rotationX++; _cube.rotationY++; _cube.rotationZ++; // render the 3D world _view3D.render(); }
Apply an image texture
Most probably, you would like to add your own textures to your 3D elements. This is where it gets fun!
As suggested by a lot of users on the Away3D forums, it may be better to have a 3D artist create objects in Blender or 3ds Max (I do not know if Unity3D can be used, although I hope it can). Once those objects are created, there is a way to import/load them into Away3D.
But in this case, since I do not know 3D software and because there is no need yet to get into complicated texture mapping, we are looking at something super simple: put an image on a cube. Most of what follows is a comprehensive summary of a thread that followed my question on Away3D's forum.
First things first: let's create an image. There are specifications to follow when creating an image for a BitmapMaterial.
A texture does not need to be square, however the dimensions have to be a power of two. What this means, is a texture can be 512 x 512 pixels, or 256 x 1024 pixels, etc. I worked with 2048 x 1024 pixels in this case.
Keep in mind that if you image is not square, it will not mipmap. Not fully convinced I understand what it means, as I do now know 3D vocabulary that much, but suffice to say you simply need to set BitmapMaterial.mipmap to false to make it work.
In the case of a cube, you need to cover all six sides. In order to do so, split your image into a 3 x 2 grid, like so:

Do you notice that each part of the image that represents a side of the cube is not square? It does not matter really, since Away3D will map it as a square onto the cube. As long as you respect the grid in your design, it will be good.
Rather than loading the image and in order to make things quicker, I simply embedded it in the code.
ActionScript 3.0:
package { import away3d.containers.View3D; import away3d.materials.BitmapMaterial; import away3d.primitives.Cube; import flash.display.Bitmap; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; [SWF(frameRate="60", backgroundColor="#ffffff", width="640", height="360")] public class Main extends Sprite { // + ---------------------------------------- // [ CONSTANTS ] // + ---------------------------------------- [Embed(source="../assets/images/dice-texture-2048x1024.png")] private var ImageClass:Class; // + ---------------------------------------- // [ VARS ] // + ---------------------------------------- private var _view3D :View3D; private var _cube :Cube; // + ---------------------------------------- // [ CONSTRUCTOR ] // + ---------------------------------------- public function Main() { super(); initStage(); addEventListener(Event.ADDED_TO_STAGE, addedToStageHangler); } // + ---------------------------------------- // [ PRIVATE METHODS ] // + ---------------------------------------- private function initStage():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; } private function init():void { // create a Bitmap from the embedded image var image:Bitmap = new ImageClass() as Bitmap; // create the BitmapMaterial var material:BitmapMaterial = new BitmapMaterial(image.bitmapData); material.smooth = true; // little trick: you do not need to care if the image is square, // simply evaluate if the sides are even material.mipmap = (image.width == image.height); // create the cube var cubeSize:uint = 240; _cube = new Cube(material, cubeSize, cubeSize, cubeSize); // add the 3D elements to the stage _view3D = new View3D(); _view3D.scene.addChild(_cube); addChild(_view3D); // add a listener so it becomes possible to render the 3D world addEventListener(Event.ENTER_FRAME, enterFrameHandler); } // + ---------------------------------------- // [ PRIVATE METHODS ] // + ---------------------------------------- private function addedToStageHandler(event:Event):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); init(); } private function enterFrameHandler(event:Event):void { // increment the cube's rotation values to see its different sides _cube.rotationX++; _cube.rotationY++; _cube.rotationZ++; // render the 3D world _view3D.render(); } } }
Fix the Away3D sources
Now, I ran into an issue when I originally tested this (Flash Player 11+ needed, click and drag to move the cube):

Some sides were repeated or not applied properly. That is actually what prompted me to ask my question on the forum, as I thought I had done everything proper.
I actually did, but here also, there was a correction needed in the Away3D sources. Away3d forum member 80prozent posted a fix.
Look at the function Cube.buildUVs() into the away3d.primitives.Cube class and replace this part:
ActionScript 3.0:
for(i = 0; i <= _segmentsW; i++) { outer_uv = u_tile_step + u_tile_dim * (i / _segmentsW); for(j = 0; j <= _segmentsD; j++) { uvData[uidx++] = outer_uv; uvData[uidx++] = 1 - v_tile_dim * (j / _segmentsD); uvData[uidx++] = outer_uv; uvData[uidx++] = v_tile_step + v_tile_dim * (j / _segmentsD); } } for(i = 0; i <= _segmentsH; i++) { outer_uv = v_tile_step + v_tile_dim * (i / _segmentsW); for(j = 0; j <= _segmentsD; j++) { uvData[uidx++] = (u_tile_dim * ((_segmentsD - j) / _segmentsD)); uvData[uidx++] = 1 - outer_uv; uvData[uidx++] = 1 - (u_tile_dim * ((_segmentsD - j) / _segmentsD)); uvData[uidx++] = v_tile_step + v_tile_dim * ((_segmentsW - i) / _segmentsW); } } target.updateUVData(uvData);
with this part:
ActionScript 3.0:
for(i = 0; i <= _segmentsW; i++) { outer_uv = u_tile_step + u_tile_dim * (i / _segmentsW); for(j = 0; j <= _segmentsD; j++) { uvData[uidx++] = outer_uv; uvData[uidx++] = 1 - v_tile_dim * (j / _segmentsD); uvData[uidx++] = 1 - outer_uv; uvData[uidx++] = 1 - (v_tile_step + v_tile_dim * (j / _segmentsD)); } } for(i = 0; i <= _segmentsH; i++) { outer_uv = v_tile_step + v_tile_dim * (i / _segmentsW); for(j = 0; j <= _segmentsD; j++) { uvData[uidx++] = (u_tile_dim * ((_segmentsD - j) / _segmentsD)); uvData[uidx++] = 1 - outer_uv; uvData[uidx++] = 1 - (u_tile_dim * ((_segmentsD - j) / _segmentsD)); uvData[uidx++] = v_tile_step + v_tile_dim * ((_segmentsW - i) / _segmentsW); } } target.updateUVData(uvData);
His fix corrects the way the image is applied to the cube. I guess this will be eventually fixed, but at the time of writing this post, the sources provided by Away3D still need that correction.
And there you go! From then you can have an awesomely decorated cube with the texture of your choice!
Nice and simple thanks. Need more samples to get you going on the new Away3D 4.