<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="http://feedproxy.google.com/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feedproxy.google.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The Tech Labs » 3D</title>
	
	<link>http://www.thetechlabs.com</link>
	<description>Adobe Air, Flash and Flex Tutorials</description>
	<pubDate>Thu, 23 Oct 2008 22:58:12 +0000</pubDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feedproxy.google.com/TheTechLabs_3d" type="application/rss+xml" /><item>
		<title>Simulating PicLens with Flex and Away3D – Part 3</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/7_m_KGon7n0/</link>
		<comments>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 22:57:17 +0000</pubDate>
		<dc:creator>Alejandro Santander</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[XML]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=121</guid>
		<description><![CDATA[<p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. You will make <a title="See the final Application" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<p><strong>Requirements:</strong></p>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Finished.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Finished.zip');" target="_blank">Source Files</a></li>
</ul>
<p><strong>Pre Requisites:</strong></p>
<ul>
<li>Having done Part 1 and 2 of this tutorial.</li>
<li>Intermediate programming skills.</li>
<li>Moderate knowledge of AS3.</li>
<li>Basic Familiarity with OOP.</li>
<li>Basic knowledge of Flash CS3.</li>
</ul>
<p style="text-align: center;"><img class="aligncenter" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0011.jpg" alt="Pic Lens" width="541" height="196" /></p>
<h3>Step 0:</h3>
<p>This is the last section of the tutorial we’ve been working on. We’re going to wrap up everything we’ve done so far and make our work a solid, working application, which we can use and even extend in the future. First, we will centralize all arbitrary parameters into what’s known as a model, then, we’re going to connect the photo gallery into an external xml so we can load images dynamically, and finally we’re going to enhance our graphics a little bit by adding a reflection effect to the 3D scene.</p>
<h3>Step 1 – Centralizing data:</h3>
<p>As I stated before, we will start by creating a place holder for all arbitrary variables used so far. With arbitrary variables I mean values that we’ve chosen such as the camera’s tween time in the “moveTo()” method within CameraController, or the Z position of the cameraTarget that can greatly affect the nature of the camera’s motion. All these will be placed in a class that will hold these static constants and will also be used to hold dynamic variables further on, so they can be accessed easily from anywhere in the application. So, go ahead and create a new folder next to “view” called “model”. In it, create a new Actionscript Class called “Model.as”.</p>
<p>Now, I need you to work alone for a while. The job to do is recognise all the values you have used so far throughout the application, that you think would be a good idea to name into a variable and control from this central class. Then, all these variables will be declared in Model.as as static constants. This is how my class looks after doing just that:</p>
<pre>package  com.li.photoviewer.model

{ 

     public class Model

     {

          public static const  CAMERA_Z:Number = -2000;

          public static const  CAMERA_Z_ZOOMED:Number = -1500;

          public static const  CAMERA_ZOOM_TIME:Number = 1;

          public static const  CAMERA_ZOOM_EASE:String = "easeoutexpo";

          public static const  CAMERATARGET_FRICTION:Number = 0.95;

          public static const  CAMERATARGET_BOUNCE_FACTOR:Number = 0.5;

          public static const  CAMERATARGET_DRAG_FACTOR:Number = 0.1;

          public static const CAMERATARGET_SPEED_FACTOR:Number  = 0.05;

          public static const  CAMERATARGET_Z:Number = -100;

          public static const  CAMERATARGET_MOVETO_TIME:Number = 1;

          public static const  CAMERATARGET_MOVETO_EASE:String = "easeoutexpo";

          public static const  PHOTO_PLANE_SEGMENTS:Number = 3;

          public static const  PHOTO_MATERIAL_SMOOTH:Boolean = true;

          public static const  PHOTO_FADEIN_TIME:Number = 0.25;

          public static const  PHOTO_SPACING:Number = 750;

          public static const  BG_COLOR1:uint = 0x222222;

          public static const  BG_COLOR2:uint = 0x000000;

          public static const  BG_COLOR_RATIO:uint = 80

          public function Model()

          {

          }

     }

}</pre>
<p>“public  static const” is a way to declare a variable that will be accessible from the  outside of the class, can be accessed without instantiating the holder class,  and will not change. If you don’t what Im talking about, you should see how we  are going to use these variables and then come back to what I’ve just said and  you should get it right away.</p>
<h3>Step 2 – Connecting to the centralized  data:</h3>
<p>So far all  this is completely useless unless we connect our classes to Model.as, so that  the constants can be used. This is done very easily; for instance to connect  the “0.05” value representing a camera velocity factor, we do as in the  following code:</p>
<pre>private function followTarget(evt:Event):void

{

     camera.lookAt(cameraTarget.position);

     var dX:Number = cameraTarget.x - camera.x;

     camera.x  += dX*0.05;

...</pre>
<p>Simply change  to:</p>
<pre>private function followTarget(evt:Event):void

{

     camera.lookAt(cameraTarget.position);

     var dX:Number = cameraTarget.x - camera.x;

     camera.x  += dX*Model.CAMERATARGET_SPEED_FACTOR;

     ...</pre>
<p>As long as the  model has been imported in CameraController of course:</p>
<pre>import com.li.photoviewer.model.Model;</pre>
<p>So this is  what you should do next. Import Model.as in all the view and controller  classes, and connect the values to it. If you’ve imported the model into a  class first, you should get useful codehints from Flex to help you complete  this task. When you’re done, you’ll have the power to very precisely tweak the entire  application from Model.as. You should play around with this to tune it to your  liking.</p>
<h3>Step 3 – Setting up an external XML:</h3>
<p>Now that  our model is set up and working, we will read data from an external xml, and  also use the model to store the data contained in the xml. We will trigger a  service that will read an xml and detail the images that will be loaded in our  application, and once this service is done, the 3D scene will build itself  based on this data. For this, lets start by designing our xml. Create a folder  named “data” and in it a new file named “data.xml”. The folder should be next  to “com” or  “away3d” folders. Then  design the xml structure of data.xml like this:</p>
<pre>&lt;?xml  version="1.0"?&gt;

&lt;imgs&gt;

     &lt;img name="testImage.jpg"/&gt;

     &lt;img  name="1.jpg"/&gt;

     &lt;img  name="2.jpg"/&gt;

     &lt;img  name="3.jpg"/&gt;

     &lt;img  name="4.jpg"/&gt;

     &lt;img  name="5.jpg"/&gt;

     &lt;img  name="6.jpg"/&gt;

     &lt;img  name="7.jpg"/&gt;

     &lt;img  name="8.jpg"/&gt;

     &lt;img  name="9.jpg"/&gt;

     &lt;img  name="10.jpg"/&gt;

&lt;/imgs&gt;</pre>
<p>The xml is extremely  simple, it just contains the name of each image.</p>
<h3>Step 4 – Creating an XML Reader:</h3>
<p>We should  continue by creating a folder called “services” next to “view” and in it a new  Actionscript Class called “XmlReader”, which will take care of extracting the  data from the xml. This class should have two variables in its constructor,  “xmlPath” as a string and “onComplete” as a function, It will also have a  “loader” variable as a URLoader:</p>
<pre>private var xmlPath:String;

private var onComplete:Function;

private var loader:URLLoader;

public function XmlReader(xmlPath:String,  onComplete:Function)

{

     this.xmlPath = xmlPath;

     this.onComplete = onComplete;

     loader = new URLLoader();

     loader.addEventListener(Event.COMPLETE,  completeHandler);

     loader.load(new URLRequest(xmlPath));

}</pre>
<p>The path of  the xml file is stored, (as well as “onComplete” which we will see in a  minute), then the loader is initialized and triggered. The function  “completeHandler()” will, as its name says, handle the loader once it’s done:</p>
<pre>private function completeHandler(evt:Event):void

{

     var xmlDocument:XMLDocument = new  XMLDocument();

     xmlDocument.ignoreWhite  = true;

     var xml:XML = new XML(evt.target.data);

     xmlDocument.parseXML(xml.toString());

     for(var i:uint; i&lt;xmlDocument.firstChild.childNodes.length;  i++)

          Model.data.push(xmlDocument.firstChild.childNodes[i].attributes.name);

     onComplete();

}</pre>
<p>The handler  parses all the data in the xml and injects it in the model. Of course, we need  to go back to Model.as and declare this “data” variable that we are referring  to. Just add it after all the constants:</p>
<pre>public static var data:Array = [];</pre>
<p>Finally  (referring again to the completeHandler method), “onComplete()” gets called as  soon as all the parsing is done. Remember that we designed this XmlReader to  receive a reference to this external function when it is instantiated. This  will simply be the function to be called when the reader has finished its job.</p>
<h3>Step 5 – Using the reader:</h3>
<p>Lets  implement this now in the application’s main class, PhotoViewer3D.as. Carefully  study these modifications:</p>
<pre>package

{

     import com.li.photoviewer.services.XmlReader;

     import com.li.photoviewer.view.PhotoScene;

     import flash.display.Sprite;

     import flash.display.StageAlign;

     import flash.display.StageScaleMode;

     [SWF(backgroundColor="0x000000", frameRate="30")]

     public class PhotoViewer3D extends Sprite

     {

          public function PhotoViewer3D()

          {

               stage.scaleMode  = StageScaleMode.NO_SCALE;

               stage.align  = StageAlign.TOP_LEFT;

               var reader:XmlReader = new XmlReader(&#8221;data/data.xml&#8221;, init);

          }

          private function init():void

          {

               var photoScene:PhotoScene = new PhotoScene();

               addChild(photoScene);

          }

     }

}</pre>
<p>I’ve just  instantiated an XmlReader, pointed it to the xml path, put the creation of the  scene in its own separate method, and also pointed the reader to this method so  its called as soon as its done.</p>
<h3>Step 6 – Loading the images:</h3>
<p>The next  step is pretty obvious. We now have the data array containing all the names of  our images, waiting for us in the model and we’ve also delayed the creation of  the 3D scene till after this data has been obtained. So we just need to alter  the “initObjects()” method of PhotoScene.as to read this data. It’s too simple  actually:</p>
<pre>private function initObjects():void

{

     for(var i:uint; i&lt;Model.data.length; i++)

     {

          var photo:PhotoLoader = new PhotoLoader("imgs/" + Model.data[i]);

          photo.x  = i*Model.PHOTO_SPACING;

          scene.addChild(photo);

          cameraController.maxX  = photo.x;

          photo.addOnMouseDown(photoClickHandler);

     }

}</pre>
<p>That’s it.  Test the application and see how it now loads all the corresponding different  images. We’re practically done now, I just want to add an additional effect to  the app…</p>
<h3>Step 7 – Adding a reflection:</h3>
<p>As it is  usual in many open source projects, many people share their code in classes  that can be very handy and easy to use. You can very often download a class  that does a particular thing, use it, and never know how it actually works. So  that’s what we’ll do, we will greatly enhance the look of our application by  downloading a class, and I will make my point of showing how great it is to use  other people’s classes, or even design classes yourself to be reusable in this  way.</p>
<p><a title="Download Reflection.as" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/reflection.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/reflection.zip');" target="_self">Download Reflection.as</a> and paste it  in the view folder.</p>
<p>The class  should be ready to work, except that its package path is all wrong. This is  pretty logical, since I’ve just used it for another project and it was placed  completely on a different place. Correct this path to the class’ current  location. You can also look into the class, now or later, to understand how it  works and maybe learn new things that could motivate you to other uses or even  new ideas with Away3D.</p>
<h3>Step 8 – Plugging in the reflection:</h3>
<p>Go back to  PhotoScene.as and declare the reflection instance (we don’t need to import  Reflection.as since it is in the same package as PhotoScene.as):</p>
<pre>private var  reflection:Reflection;</pre>
<p>Then, in the “initScene()” method, initialize  it and add it to the display list:</p>
<pre>reflection = new Reflection(scene, camera);
addChild(reflection);</pre>
<p>And  finally, in “renderScene()” add a call to the reflections rendering method:</p>
<pre>private function renderScene(evt:Event):void

{

reflection.render();

view.render();

}</pre>
<p>I also took  the time to connect the Reflection class to the model and drop its arbitrary  variables there. I even set up a USE_REFLECTION constant in the model and  applied this Boolean value in the initialization of the reflection in  “initScene()” and the “renderScene()” method too. All this allows you to, not  only tweak the app to look good, but also to consider performance issues. With  the values that you should have in the model after you do this, you can really  optimize the application.</p>
<pre>public static const USE_REFLECTION:Boolean = false;

public static const REFLECTION_OFFSET:Number = -525;

public static const REFLECTION_BLUR:Number = 8;

public static const REFLECTION_ALPHA:Number = 0.25;

public static const REFLECTION_SCALING:Number = 2;</pre>
<p>So, that’s  it! The application is flexible enough to be extended easily. Maybe a  horizontal scroller could be a good idea, for example… I leave that to your  creativity. I wanted to keep the MVC architecture as simple as I could by  avoiding custom events, singleton classes, etc, but those could be good things  to investigate for future projects. On the other hand, I really recommend  playing with the Away3D engine, the possibilities with it are endless!!</p>
<p>I hope  you’ve enjoyed the tutorial. I’m looking forward to make another one when I can  =)</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%203&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-3%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%203&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-3%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs_3d/~4/7_m_KGon7n0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/</feedburner:origLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 2</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/eDMVM1zmskY/</link>
		<comments>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 21:27:21 +0000</pubDate>
		<dc:creator>Alejandro Santander</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=120</guid>
		<description><![CDATA[<p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 2, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<p><span lang="EN-GB">Step by  step guide for creating a PicLens type 3D photo viewer with Flex and Away3d.  This is step 2, of a 3 part tutorial that will sweep many useful techniques  used in web application design, Flex, and Flash 3D design. </span></p>
<p>In the final the result will be <a title="See the Final Application Demo" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<p><strong>Requirements:</strong></p>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part2.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part2.zip');" target="_blank">Source Files</a></li>
</ul>
<p><span lang="EN-GB"> </span><strong><span lang="EN-GB">Pre Requisites:</span></strong></p>
<p><!--[if !supportLists]--></p>
<ul>
<li> <span lang="EN-GB">Having  done Part 1 of this tutorial</span></li>
<li> <span lang="EN-GB">Intermediate  programming skills</span></li>
<li> <span lang="EN-GB">Moderate  knowledge of AS3</span></li>
<li> <span lang="EN-GB">Basic  Familiarity with OOP</span></li>
<li><span lang="EN-GB">Basic  knowledge of Flash CS3</span></li>
</ul>
<p><strong><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0011.jpg" alt="" /></strong></p>
<h3><strong><span lang="EN-GB">Step</span></strong><strong><span lang="EN-GB"> 0</span></strong></h3>
<p><span lang="EN-GB">In this  part we’re going to use the PhotoLoader component we designed previously, and  set up the 3D scene showing multiple instances of it. Then, we’re going to  develop the interactivity of the user for that scene. This will be the most  intense part of the series, but hopefully the most fun.</span></p>
<h3><strong><span lang="EN-GB">Step 1 – Adapting the TestScene to the  official scene</span></strong></h3>
<p><span lang="EN-GB">So, the  first thing we have to do is rename our TestScene.as. Right click on the file,  choose Rename and select PhotoScene as the new name. Flex should have updated  the references to this class in your source, so that no errors are shown.  However, you should go to the main file, “PhotoViewer3D” and rename the  PhotoScene instance to “scene”, its not necessary, but its tidy. If any errors  are thrown, it’s a good time to get to know the Flex Console. It is a panel at  the bottom of Flex, in which errors are detected before compilation time. Its  very probable that you noticed it already, just making sure. If you double  click on one of the errors it shows you, Flex takes you directly to the source  of that error. I really don’t know any quicker way to debug errors in  Actionscript projects.</span></p>
<p><span lang="EN-GB"> </span></p>
<h3><strong><span lang="EN-GB">Step 2 – Multiple objects</span></strong></h3>
<p><span lang="EN-GB">Now, we’re  going to modify the “initObjects()” method in PhotoScene to create 10 instances  of PhotoLoader instead of just one, and arrange these instances horizontally.  Use this code:</span></p>
<pre><strong>private</strong> <strong>function</strong> initObjects():<strong>void</strong>
{
     <strong>for</strong>(<strong>var</strong> i:uint; i&lt;10; i++)
     {
          <strong>var</strong> photo:PhotoLoader = <strong>new</strong> PhotoLoader(<strong>&#8220;imgs/testImage.jpg&#8221;</strong>);
          photo.x  = i*700; &lt;
          scene.addChild(photo);
     }
}</pre>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0031.jpg" alt="" /></p>
<p><span>You should  now see more instances to the right of the first one, even though we cant see  all of them due to our limited camera control lines in the “renderScene()”  method.</span></p>
<h3><strong><span lang="EN-GB">Step 3 – Enhancing camera controls</span></strong></h3>
<p><span lang="EN-GB">That’s what  we’re going to do now; begin building a controller class that will provide more  advanced camera user control. This part is pretty fun, since we’ve reached the  level of complexity in which Away3D starts showing off its awesome  capabilities.</span></p>
<p><span lang="EN-GB">Delete  these lines in the “renderScene()” method in PhotoScene, we wont need them  anymore:</span></p>
<pre>camera.x = 3*(mouseX - stage.stageWidth/2);
camera.y = 3*(mouseY - stage.stageHeight/2);
camera.lookAt(<strong>new</strong> Number3D(0, 0, 0));</pre>
<p><span lang="EN-GB">The new  code that we will develop to achieve the enhanced camera motion will be more  complex, logically, so it will not reside in our PhotoScene class. It will be  in its own class, designed specifically for this, that is, camera motion  control. Create a new folder next to “view” and name it “controller”. In it,  create a new Actionscript Class named “CameraController”. Once done, make this  class extend Sprite.</span></p>
<p><span lang="EN-GB">Now, back  in PhotoScene.as, create a new variable named cameraController as:</span></p>
<pre><strong>private</strong> <strong>var </strong>cameraController:CameraController;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">After the  “initScene()” call in the “init()” method in PhotoScene, place a new call to  “initCameraController()”. And lets define this as follows:</span></p>
<pre><strong>private</strong> <strong>function</strong> initCameraController():<strong>void</strong>
{
    <strong>var</strong> cube:Cube = <strong>new</strong> Cube();
    cube.width  = cube.height = cube.depth = 10; 

     cube.z =  -100; 

     scene.addChild(cube); 

     cameraController  = <strong>new</strong> CameraController(camera, cube); 

     addChild(cameraController);</pre>
<p><span lang="EN-GB">Don’t  worry, I’ll explain. What we did is create a small cube and added it to the scene.  Then, we instantiated our new CameraController, passing it two parameters and  added it to the display. Why those two parameters? And what is the purpose of  that cube?! As you will fully understand later, the cube will be used as the  camera’s target, the camera will constantly be “looking” at it and trying to  follow it. This is a very interesting technique used in 3D, since it provides a  way to simulate natural and realistic camera motion effects.</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 4 – Building the CameraController</span></strong></h3>
<p><span lang="EN-GB">Great, now lets  go back to the controller and shape it up a little. In PhotoScene, when we  instantiated it, we passed it 2 parameters. Lets assimilate them in the  constructor and store these references. We’re also going to create an init  method that will be called once the instance has been added to the stage, as  we’ve done before:</span></p>
<pre><strong>private</strong> <strong>var</strong> camera:Camera3D; 

<strong>private</strong> <strong>var</strong> cameraTarget:Cube; 

<strong>public</strong> <strong>function</strong> CameraController(camera:Camera3D,  cameraTarget:Cube) 

{ 

     <strong>this</strong>.camera = camera; 

     <strong>this</strong>.cameraTarget = cameraTarget; 

     <strong>this</strong>.addEventListener(Event.ADDED_TO_STAGE, init, <strong>false</strong>, 0, <strong>true</strong>); 

} 

<strong>private</strong> <strong>function</strong> init(evt:Event):<strong>void</strong> 

{ 

     <strong>this</strong>.removeEventListener(Event.ADDED_TO_STAGE, init); 

}</pre>
<p><span lang="EN-GB">Add a new  event listener in the “init()” method to call a new “followTarget()” in  enterframe.</span></p>
<pre><strong>this</strong>.addEventListener(Event.ENTER_FRAME,  followTarget);</pre>
<p><span lang="EN-GB">And define  “followTarget()” as:</span></p>
<pre><strong>private</strong> <strong>function</strong> followTarget(evt:Event):<strong>void</strong> 

{ 

     cameraTarget.x  += 10; 

     camera.lookAt(cameraTarget.position); 

}</pre>
<p><span lang="EN-GB">Test it  out. You should be able to see the little cube starting next to the first photo  and then moving to the right. The camera will look at it as it goes away. Lets  extend it a bit further by telling the camera not just to look at it, but also to  try to keep up with it. Add these lines to the “followTarget()” method:</span></p>
<pre>var  dX:Number = cameraTarget.x - camera.x;

camera.x += dX*0.05;</pre>
<p><span>Test it  again… Im sure you can tell the different and understand the code with what  you see.</span></p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0051.jpg" alt="" /></p>
<p><span lang="EN-GB">Before we  go on, delete the first line in “followTarget()” that moves the camera target  to the right, it was just used for demonstration purposes. From now on, the  target wont move by its own, we are going to move it.</span></p>
<h3><strong><span lang="EN-GB">Step 5 – Setting up interactivity</span></strong></h3>
<p><span lang="EN-GB">That looks  good, but now lets make it more realistic, and most importantly, interactive.  In PhotoScene, we are going to modify the “initObjects()” method again to  register a click listener on the photos, and that method is going to call  another method in the camera controller, telling it to move the camera to that  photo. Don’t worry, you’ll be amazed by how simple this is going to be.</span></p>
<p><span lang="EN-GB">In the for  loop inside of “initObjects()” in PhotoScene, add this line at the end:</span></p>
<pre>photo.addOnMouseDown(photoClickHandler);</pre>
<p><span lang="EN-GB">And add a  couple of lines in the constructor of PhotoLoader to tell the cursor to show a  hand when we roll over the photos:</span></p>
<pre><strong>this</strong>.ownCanvas = <strong>true</strong>; 

<strong>this</strong>.useHandCursor = <strong>true</strong>;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">Then,  define the “photoClickHandler()” back in PhotoScene method as:</span></p>
<pre><strong>private</strong> <strong>function</strong> photoClickHandler(evt:MouseEvent3D):<strong>void</strong> 

{ 

     cameraController.moveTo(evt.object.x); 

}</pre>
<p><span lang="EN-GB">Yes, we  need to define the public “moveTo()” method in the CameraController, so lets do  it:</span></p>
<pre><strong>public</strong> <strong>function</strong> moveTo(X:Number):<strong>void</strong> 

{ 

Tweener.addTween(cameraTarget, {x:X,  time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

}</pre>
<p><span lang="EN-GB">It will  work as long as you import the Tweener class in CameraController. Test the  application and click on the images. That’s it!!</span></p>
<h3><strong><span lang="EN-GB">Step 6 – Setting up mouse drag</span></strong></h3>
<p><span lang="EN-GB">Next, the  app is going to have a pretty cool feature, which is the ability of the user to  click on the canvas and drag himself (the camera that is) around the scene.  We’ll manage this in 3 steps, so follow along.</span></p>
<p><span lang="EN-GB">First,  we’re going to need 2 clips that will capture the mouse down and mouse up for  the dragging. One will be behind the photos, and the other above them. Besides,  we will take advantage of the one behind to make the app look a bit better by  using it as a background as well. Modify “initScene()” in PhotoScene like this:</span></p>
<pre><strong>private</strong> <strong>function</strong> initScene():<strong>void</strong> 

{ 

     scene = <strong>new</strong> Scene3D(); 

     camera = <strong>new</strong> Camera3D(); 

     camera.zoom  = 10; 

     camera.focus  = 200; 

     camera.z =  -2000; 

     background  = <strong>new</strong> Sprite(); 

     <strong>var</strong> mat:Matrix = <strong>new</strong> Matrix(); 

     mat.rotate(-Math.PI/2); 

     background.graphics.beginGradientFill(GradientType.LINEAR,  [0x222222, 0x000000], [1, 1], [0, 80], mat); 

     background.graphics.drawRect(0,  0, stage.stageWidth, stage.stageHeight); 

     background.graphics.endFill(); 

     addChild(background); 

     background.addEventListener(MouseEvent.MOUSE_DOWN,  handleBackgroundMouseDown); 

     view = <strong>new</strong> View3D(); 

     view.camera  = camera; 

     view.scene  = scene; 

     view.x =  stage.stageWidth/2; 

     view.y =  stage.stageHeight/2; 

     view.clip  = <strong>new</strong> RectangleClipping(-stage.stageWidth/2,  -stage.stageHeight/2, stage.stageWidth/2, stage.stageHeight/2); 

     addChild(view); 

     foreground  = <strong>new</strong> Sprite(); 

     foreground.graphics.beginFill(0&#215;00FF00,  0.5); 

     foreground.graphics.drawRect(0,  0, stage.stageWidth, stage.stageHeight); 

     foreground.graphics.endFill(); 

     foreground.visible  = <strong>false</strong>; 

     addChild(foreground); 

     foreground.addEventListener(MouseEvent.MOUSE_UP,  handleForegroundMouseUp); 

     foreground.addEventListener(MouseEvent.MOUSE_OUT,  handleForegroundMouseUp); 

}</pre>
<p><span lang="EN-GB">And don’t  forget to declare background and foreground private variables at the beginning  of the class, plus import the GradientType class:</span></p>
<pre><strong>import</strong> flash.display.GradientType;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">What we  just did was add these two before and after the view. It was done in this order  to maintain the layering we talked about before. The background is simply a  sprite with a gradient, and the foreground is a semi transparent green clip  above everything. Comment the 3 listener lines we’ve just added, and “</span><em>foreground.visible = false</em><span lang="EN-GB">” and test the app. As you can see,  the sprites have been added to the display.</span></p>
<p><span lang="EN-GB">Now,  uncomment those lines and go ahead and define the handler methods as:</span></p>
<pre><strong>private</strong> <strong>function</strong> handleBackgroundMouseDown(evt:MouseEvent):<strong>void</strong> 

{ 

     foreground.visible  = <strong>true</strong>; 

} 

<strong>private</strong> <strong>function</strong> handleForegroundMouseUp(evt:MouseEvent):<strong>void</strong> 

{ 

     foreground.visible  = <strong>false</strong>; 

}</pre>
<p><span lang="EN-GB">If you test  the app again, you’ll see the idea behind all this. The background captures the  mouse down and shows the foreground, which is simply there to capture the mouse  up. Even though this might look confusing, its pretty practical. If it wasn’t  there and we had set up the background to capture the mouse up, it wouldn’t  work very well since we could press on the background and then, while the mouse  is still pressed, move over to a photo and release the mouse once we’re there…  The background wouldn’t have captured the mouse up, because the photo would  have captured it. So, what we’ve just done makes sure we don’t have to worry  about this kind of stuff. It’s solid, Im sure there might be other methods, but  Im comfortable with this one. Before we continue, set the foreground’s draw  alpha from 0.5 to 0 so we don’t see it anymore (it will do its job anyway).</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 7 – Designing the mouse drag</span></strong></h3>
<p><span lang="EN-GB">We need to  define the dragging now. On the handlers we’ve just created, add “</span>cameraController.startCameraDrag();<span lang="EN-GB">” for the mouse down handler, and “</span>cameraController.stopCameraDrag();<span lang="EN-GB">” for the mouse up handler. And of  course, we need to define those methods in the CameraController class. These  two methods will simply toggle a mouse move event listener that will  continuously call a dragCamera method while the mouse is pressed:</span></p>
<pre><strong>public</strong> <strong>function</strong> startCameraDrag():<strong>void</strong> 

{ 

lastMouseX = stage.mouseX; 

     stage.addEventListener(MouseEvent.MOUSE_MOVE,  dragCamera, <strong>false</strong>, 0 , <strong>true</strong>); 

} 

<strong>public</strong> <strong>function</strong> stopCameraDrag():<strong>void</strong> 

{ 

     stage.removeEventListener(MouseEvent.MOUSE_MOVE,  dragCamera); 

} 

<strong>private</strong> <strong>function</strong> dragCamera(evt:MouseEvent):<strong>void</strong> 

{ 

     <strong>var</strong> dX:Number = <span style="text-decoration: underline;">lastMouseX</span> - stage.mouseX; 

     cameraTargetVX  += dX*0.1; 

     lastMouseX  = stage.mouseX; 

}</pre>
<p><span lang="EN-GB">Of course,  you’re going to need to define “lastMouseX” and “cameraTargetVX” as private  variables at the top of the class. Make sure you set cameraTargetVX to zero  when you declare it. Ill explain what’s going on shortly, I want you to see it  working first…</span></p>
<p><span lang="EN-GB">To apply  what we’ve just done, add these lines to the “followTarget()” method:</span></p>
<pre>cameraTarget.x += <span style="text-decoration: underline;">cameraTargetVX</span>; 

cameraTargetVX *= 0.95;</pre>
<p><span lang="EN-GB">And to  correct incongruencies, add “</span>cameraTargetVX  = 0;<span lang="EN-GB">” in the “moveTo()”  method.</span></p>
<p><span lang="EN-GB">Check it  out by testing the app and clicking and dragging from the background. Its simple  code, with pretty impressive smooth results. So, as I said, let me explain a  little now. When a drag is started, the controller stores the current mouse  position and begins the continuous call to the drag method. In this method, the  first thing that happens is that the stored initial mouse position is compared  to the actual mouse position every time the mouse moves. This value is then  used to alter “cameratargetVX” which is just a variable that represents the  velocity of the camera, and the current mouse position is again stored. On the  mean time, in the “followTarget()” method, the velocity variable is constantly  being added to the cameraTarget’s position. This is the very basics of  simulating velocity physics on programming. In this method, the velocity value  is also dampened by 5% to simulate friction. Finally, the “stopCameraDrag()”  method unplugs the continuous call to “dragCamera()”.</span></p>
<h3><strong><span lang="EN-GB">Step 8 – Adding zoom</span></strong></h3>
<p><span lang="EN-GB">Next, we  will add a cool zoom effect, which is going to be really simple. Add this  methods in Camera Controller:</span></p>
<pre><strong>private</strong> <strong>function</strong> zoomIn():<strong>void</strong> 

{ 

     Tweener.addTween(camera,  {z:-1500, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

} 

<strong>private</strong> <strong>function</strong> zoomOut():<strong>void</strong> 

{ 

     Tweener.addTween(camera,  {z:-2000, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

}</pre>
<p><span lang="EN-GB">And add a  zoomIn() call in the “moveTo()” method, and a zoomOut() call in the  “startCameraDrag()” method. Test the app. It’s as simple as that, we now have a  little zoom effect working.</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 9 – Containing motion</span></strong></h3>
<p><span lang="EN-GB">Before we  finish this part of the tutorial, we need to face a little issue you might have  noticed: The user can drag himself far away from the photos, and we don’t want  this. We want to contain the camera in an area where the user will always see  the photos.</span></p>
<p><span lang="EN-GB">To define  the area that the user will move in, define two public variables in  CameraController. They’re public because, even though we define them in  CameraController, they will be filled up from the PhotoScene each time a new  photo is created:</span></p>
<pre><strong>public</strong> <strong>var</strong> minX:Number = 0; 

<strong>public</strong> <strong>var</strong> maxX:Number =  0;</pre>
<p><span lang="EN-GB">Now go to  PhotoScene and, in “initObjects()” add “</span>cameraController.maxX = photo.x;<span lang="EN-GB">” inside the end of for loop. This results in  that each time a photo is created, the scene reports the camera controller how  far the camera target should be able to move.</span></p>
<p><span lang="EN-GB">Now last,  but not least, add this containment code to the end of “followTarget()” in  cameraController:</span></p>
<pre><strong>if</strong>(cameraTarget.x  &gt; maxX) 

{ 

     cameraTarget.x  = maxX; 

     cameraTargetVX  *= -0.5; 

} 

<strong>else</strong> <strong>if</strong>(cameraTarget.x &lt; minX) 

{ 

     cameraTarget.x  = minX; 

     cameraTargetVX  *= -0.5; 

}</pre>
<p><span lang="EN-GB">This simply  checks if the target has exceeded the limits of the scene, and if so, docks the  target at one of the limits and inverts its velocity to make it “bounce”. You  may enhance this code by making it consider positions before a velocity value  is applied, etc. It would look better, but I wanted to keep things as simple as  possible here.</span></p>
<p><span lang="EN-GB">And that  does it for part 2 of the tutorial… To wrap things up go to PhotoScene and add  “cube.visible = false;” in “initCameraController()” so that the little cube is  hidden from the user.</span></p>
<h3><strong><span lang="EN-GB">Next</span></strong></h3>
<p><span lang="EN-GB">On part 3  we will give the application a closure by centralizing arbitrary variables,  enhancing graphics a bit, and connecting it to an external XML that will  indicate it what images to load.</span></p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%202&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-2%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%202&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-2%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs_3d/~4/eDMVM1zmskY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/</feedburner:origLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 1</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/HC3nPEmO0ww/</link>
		<comments>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 23:02:11 +0000</pubDate>
		<dc:creator>Alejandro Santander</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Effects]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=116</guid>
		<description><![CDATA[<p>This tutorial article is a Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 1, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<p>This tutorial article is a Step by  step guide for creating a PicLens type 3D photo viewer with Flex and Away3d.  This is step 1, of a 3 part tutorial that will sweep many useful techniques  used in web application design, Flex, and Flash 3D design.</p>
<p>In the final the result will be <a title="See the Final Application Demo" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<h3>Requirements</h3>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" target="_blank">Source Files</a></li>
</ul>
<h3>Pre Requisites</h3>
<ul>
<li>Intermediate  programming skills</li>
<li>Moderate  knowledge of AS3</li>
<li>Basic  Familiarity with OOP</li>
<li>Basic  knowledge of Flash CS3</li>
</ul>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image001.jpg" alt="" width="541" height="196" /></p>
<h3>Step 0</h3>
<p>In this  tutorial I will assume that you are familiar with the basics of building an  Actionscript Away3D project in Flex. If you haven’t used these two technologies  together before, it would be best if you go through my <a title="Setting up Away3d with Flex" href="http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/"  target="_self">previous tutorial</a> first. Due to the complexity of this  application, I will need to skip some things to go faster. So, if something is  not explained here, or suddenly a large chunk of code is dropped with no  descriptions, it has been covered (hopefully) in the mentioned tutorial.</p>
<h3>Step 1 – New Project</h3>
<p>Lets get  started. Create a new Actionscript Project in Flex and name it “PhotoViewer3D”.  Then, download the libraries I listed in the requirements and paste them in the  project’s folder.</p>
<p>Now, one of  the things that will be covered here is a very simplified application  architecture that could be a good starting point for any project you do that  implies a moderate level of complexity. For this, all code will be placed in a  folder structure, carefully separating functions between different classes, and  hence emulating the basics of a Model View Controller design pattern. You  should have a general grasp of it by the end of this series.</p>
<p>Right click  on the project’s folder in the Flex Navigator and choose New -&gt; Folder, then  type “com/li/photoviewer/view” and press Finish. Naming folders this way is  known as Reverse Domain Syntax, and is a good programming practice.</p>
<h3>Step 2 – Setting up the scene</h3>
<p>Go to  PhotoViewer3D.as and build a basic main class:</p>
<pre><strong>package</strong>
{
     <strong>import</strong> flash.display.Sprite;
     <strong>import</strong> flash.display.StageAlign;
     <strong>import</strong> flash.display.StageScaleMode;

     <strong>import</strong> com.li.photoviewer.view.TestScene;

[SWF(backgroundColor=<strong>"0x000000"</strong>, frameRate=<strong>"30"</strong>)] 

     <strong>public</strong> <strong>class</strong> <span lang="EN-GB">PhotoViewer3D</span><strong> extends</strong> Sprite
     {
          <strong>public</strong> <strong>function</strong> <span lang="EN-GB">PhotoViewer3D</span>()
          {
               stage.scaleMode  = StageScaleMode.NO_SCALE;
               stage.align  = StageAlign.TOP_LEFT;

               <strong>var</strong> testScene:TestScene = <strong>new</strong> TestScene();
               addChild(testScene);
          }
     }
}</pre>
<p>Line 7  imports an away3D holding class that we haven’t made yet, so we should create it  right away. Right click on the “view” folder and choose New -&gt; Actionscript  Class and name it “TestScene”. It should have the following code in it:</p>
<pre><strong>package</strong> com.li.photoviewer.view 

{ 

     <strong>import</strong> away3d.cameras.Camera3D;
     <strong>import</strong> away3d.containers.Scene3D;
     <strong>import</strong> away3d.containers.View3D;
     <strong>import</strong> away3d.core.clip.RectangleClipping;
     <strong>import</strong> away3d.core.math.Number3D; 

     <strong>import</strong> flash.display.Sprite;
     <strong>import</strong> flash.events.Event; 

     <strong>public</strong> <strong>class</strong> TestScene <strong>extends</strong> Sprite
     {
          <strong>private</strong> <strong>var</strong> scene:Scene3D;
          <strong>private</strong> <strong>var</strong> camera:Camera3D;
          <strong>private</strong> <strong>var</strong> view:View3D; 

          <strong>public</strong> <strong>function</strong> TestScene()
          {
               addEventListener(Event.ADDED_TO_STAGE,  init, <strong>false</strong>, 0, <strong>true</strong>);
          } 

          <strong>public</strong> <strong>function</strong> init(evt:Event):<strong>void</strong>
          {
               removeEventListener(Event.ADDED_TO_STAGE,  init); 

               initScene();
               initObjects();
               addEventListener(Event.ENTER_FRAME,  renderScene);
          } 

          <strong>private</strong> <strong>function</strong> initScene():<strong>void</strong>
          {
               scene  = <strong>new</strong> Scene3D(); 

               camera  = <strong>new</strong> Camera3D();
               camera.zoom  = 10;
               camera.focus  = 200;
               camera.z  = -2000; 

               view  = <strong>new</strong> View3D();
               view.camera  = camera;
               view.scene  = scene;
               view.x  = stage.stageWidth/2;
               view.y  = stage.stageHeight/2;
               view.clip  = <strong>new</strong> RectangleClipping(-stage.stageWidth/2,  -stage.stageHeight/2, stage.stageWidth/2, stage.stageHeight/2);
               addChild(view);
          } 

          <strong>private</strong> <strong>function</strong> initObjects():<strong>void</strong>
          {
               <strong> </strong>
          } 

          <strong>private</strong> <strong>function</strong> renderScene(evt:Event):<strong>void</strong>
          {
               camera.x  = 3*(mouseX - stage.stageWidth/2);
               camera.y  = 3*(mouseY - stage.stageHeight/2);
               camera.lookAt(<strong>new</strong> Number3D(0, 0, 0)); 

               view.render();
          }
     }
}</pre>
<p><strong>NOTE: </strong>If any  of this shocked you, it has all been explained in the tutorial mentioned in Step  0.</p>
<h3>Step 3 – Setting up our PhotoLoader  component</h3>
<p>Create a  new Actionscript Class in the view folder and name it “PhotoLoader”. These will  be our 3D photograph object. The class will extend Away3D’s Plane primitive,  with a few additional features, more particularly, the ability to load an  external image. So, lets start by setting up the plane:</p>
<pre><strong>package</strong> com.li.photoviewer.view
{
<strong>import</strong> away3d.primitives.Plane;

<strong>public</strong> <strong>class</strong> PhotoLoader <strong>extends</strong> Plane
     {
<strong>private</strong> <strong>var</strong> urlPath:String;

          <strong>public</strong> <strong>function</strong> PhotoLoader(urlPath:String)
          { 

               <strong>super</strong>();

               <strong>this</strong>.urlPath = urlPath;

               <strong>this</strong>.rotationX = 90;
               <strong>this</strong>.width = 640;
               <strong>this</strong>.height = 480;
               <strong>this</strong>.segmentsH = 4;
               <strong>this</strong>.segmentsW = 4;
          }
     }
}</pre>
<p>As you can  see, we’ve set up the constructor so that when we instantiate a PhotoLoader  object, we pass it the image name it has to load as a parameter. Now, go back  to TestScene, and in the “iniObjects()” method, make an instance of PhotoLoader  and add it to the scene:</p>
<pre><strong>var</strong> testPhoto:PhotoLoader = <strong>new</strong> PhotoLoader(<strong>&#8220;imgs/testImage.jpg&#8221;</strong>);

scene.addChild(testPhoto);</pre>
<p>The urlPath we passed this time will be irrelevant,  but we’ll pass it anyway so no errors are thrown. Go ahead and test the  application, you should see something like this:</p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image003.jpg" alt="" width="540" height="400" /></p>
<h3>Step 4 – Skinning the plane with Flash</h3>
<p>First of  all, we need to give the plane a skin or texture. Even though it will contain  an image, it needs to contain something else while it’s loading, and somehow  show progress for that load process. For this, we will design some graphics in  Flash, and bring them to Flex with what I find to be a very practical and  simple technique. We will use a fla file to generate a library.swf file that  will contain some graphics for our application, and then embed that swf in Flex  and extract the clips as we need them. This is a very useful technique, and I  definitely recommend it for any Flex projects that contain design based vector  graphics.</p>
<p>Open Flash,  create a new AS3 Flash File and save it in your project’s folder, next to  PhotoViewer3D.as. Once in it, select File -&gt; Publish Settings and type “assets/library.swf” for the swf output path (deselect  the html output). Now, create a new folder next to that fla called “assets”  either from your file explorer or by right clicking the project’s folder in the  Flex Navigator. Now, if you publish the fla you will see that library.swf shows  up in your newly created assets folder.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image005.jpg" alt="" width="283" height="312" /></p>
<h3>Step 5 – Creating and extracting the  graphics created in Flash</h3>
<p>Great, now  I wont be describing how to make the graphics in Flash since I believe you must  be very familiar with this. You should <a title="Download the fla file" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip');" target="_self"><strong>download the </strong></a><strong><a title="Download the fla file" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip');" target="_self">fla</a></strong> and overwrite the one you just made.  Sorry! Just wanted to make sure you understood what’s going on. Now, open the  downloaded fla. You will see a clip called “LoaderFront” made up of a gray box  and a progressBar clip which has in turn a sub clip. The important thing to  notice here is that LoaderFront has a Linkage and its Base Class was changed to  Sprite. Publish it again, go back to Flex, right click on library.swf in the  assets folder and choose Refresh.</p>
<p>This is the  only code you’ll need to pull those graphics from Flex, type it at the top of  the PhotoLoader class (inside Public class…):</p>
<pre>[<strong>Embed</strong>(source=<strong>"assets/library.swf"</strong>, symbol=<strong>"LoaderFront"</strong>)]
<strong>public</strong> <strong>var</strong> LoaderFront:Class;</pre>
<p>You’ve just  extracted the symbol from the swf’s library and assigned it to a LoaderFront  class. If you create a new instance of this class (and add it to the display  tree), you’ll have a graphics object that extends Sprite! And you can treat it  as any other sprite. Great isn’t it?</p>
<h3>Step 6 – Applying the graphics to the  plane</h3>
<p>Go back to  PhotoLoader.as and create these variables for the class:</p>
<pre><strong>private</strong> <strong>var</strong> materialSprite:Sprite;
<strong>private</strong> <strong>var</strong> progressBar:Sprite;
<strong>private</strong> <strong>var</strong> progressBarSubClip:Sprite;</pre>
<p>And then  this method:</p>
<pre><strong>private</strong> <strong>function</strong> initClips():<strong>void</strong>
{
     materialSprite  = <strong>new</strong> LoaderFront();

     progressBar  = Sprite(materialSprite.getChildByName(<strong>&#8220;progressBar&#8221;</strong>));
     progressBarSubClip  = Sprite(progressBar.getChildByName(<strong>&#8220;subClip&#8221;</strong>));
}</pre>
<p>Now we have references to all the clips that we  need. You have to add the “initClips()” call at the end of the constructor  class.</p>
<p>Next, type this new method under the last one  and also make sure you call it from the constructor:</p>
<pre><strong>private</strong> <strong>function</strong> initMaterial():<strong>void</strong>
{
     <strong>var</strong> material:MovieMaterial = <strong>new</strong> MovieMaterial(materialSprite);
     material.smooth  = <strong>true</strong>;

     <strong>this</strong>.<span style="text-decoration: underline;">material</span> = material;
}</pre>
<p>And Test the application. You should now see that the  plane has taken the graphics as its material. Your PhotoLoader class should  look like this so far:</p>
<pre><strong>package</strong> com.li.photoviewer.view
{
     <strong>import</strong> away3d.materials.MovieMaterial;
     <strong>import</strong> away3d.primitives.Plane;
     <strong>import</strong> flash.display.Sprite;
     <strong>public</strong> <strong>class</strong> PhotoLoader <strong>extends</strong> Plane
     {
         [<strong>Embed</strong>(source=<strong>"assets/library.swf"</strong>, symbol=<strong>"LoaderFront"</strong>)]
          <strong>public</strong> <strong>var</strong> LoaderFront:Class;
          <strong>private</strong> <strong>var</strong> urlPath:String;
          <strong>private</strong> <strong>var</strong> materialSprite:Sprite;
          <strong>private</strong> <strong>var</strong> progressBar:Sprite;
          <strong>private</strong> <strong>var</strong> progressBarSubClip:Sprite;
          <strong>public</strong> <strong>function</strong> PhotoLoader(urlPath:String)
          {
               <strong>super</strong>();
               <strong>this</strong>.urlPath = urlPath;
               <strong>this</strong>.rotationX = 90;
               <strong>this</strong>.width = 640;
               <strong>this</strong>.height = 480;
               <strong>this</strong>.segmentsH = 4;
               <strong>this</strong>.segmentsW = 4;
               initClips();
               initMaterial();
          }
          <strong>private</strong> <strong>function</strong> initClips():<strong>void</strong>
          {
               materialSprite  = <strong>new</strong> LoaderFront();
               progressBar  = Sprite(materialSprite.getChildByName(<strong>&#8220;progressBar&#8221;</strong>));
               progressBarSubClip  = Sprite(progressBar.getChildByName(<strong>&#8220;subClip&#8221;</strong>));
          }
          <strong>private</strong> <strong>function</strong> initMaterial():<strong>void</strong>
          {
               <strong>var</strong> material:MovieMaterial = <strong>new</strong> MovieMaterial(materialSprite);
               material.smooth  = <strong>true</strong>;
               <strong>this</strong>.material = material;
          }
     }
}</pre>
<h3>Step 7 – Loading images into the plane</h3>
<p>The final  thing to do for Part 1 of this tutorial, is implement all the image loading  features of our extended plane. For this, we will use a regular Loader instance  and add a few event listeners to check for progress and complete events.</p>
<p>Add the  loader variable next to the other class variables:</p>
<pre><strong>private</strong> <strong>var</strong> loader:Loader;</pre>
<p>And call a new method under the  “initMaterial()” call in the constructor as “initLoader()”, then build the  method:</p>
<pre><strong>private</strong> <strong>function</strong> initLoader():<strong>void</strong>
{
     loader = <strong>new</strong> Loader();
     loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,  progressHandler);
     loader.contentLoaderInfo.addEventListener(Event.INIT,  initHandler);
     materialSprite.addChild(loader);
     loader.alpha  = 0;
}</pre>
<p>The loader is initialized, two listeners are registered,  then the loader is injected to the plane’s material sprite completely  invisible. I’ve made it invisible because I&#8217;m going to make it fade in once the  image has been loaded into it.</p>
<p>Now, lets set up the handlers and a little  “setProgress()” utilitary method:</p>
<pre><strong>private</strong> <strong>function</strong> progressHandler(evt:ProgressEvent):<strong>void</strong>
{
     setProgress(evt.bytesLoaded/evt.bytesTotal);
}
<strong>private</strong> <strong>function</strong> initHandler(evt:Event):<strong>void</strong>
{
     Tweener.addTween(loader,  {alpha:1, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>});
}
<span lang="EN-GB"> </span>
<strong>private</strong> <strong>function</strong> setProgress(value:Number):<strong>void</strong>
{
     progressBarSubClip.scaleX  = value;
}</pre>
<p>Pretty  straight forward. As the image downloads, the progress handler calls the “setProgress()”  function which in turn sets the horizontal scale of the progress bar, and when  the download completes, or more precisely when the loaded content is  initialized, Tweener makes the loader fade in by animating its alpha. Don’t  forget to import Tweener for this:</p>
<pre><strong>import</strong> caurina.transitions.Tweener;</pre>
<h3>Step 8 – Triggering the load</h3>
<p>Next, lets  trigger the load by adding a “loadImage()” method as the last method called in  the constructor and defining it:</p>
<pre><strong>private</strong> <strong>function</strong> loadImage():<strong>void</strong>
{
     loader.unload();
     loader.alpha  = 0;
     setProgress(0);
     loader.load(<strong>new</strong> URLRequest(urlPath));
}</pre>
<p>Finally,  create the imgs folder in the project, download <a title="Download the images" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/imgs.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/imgs.zip');" target="_self">THESE</a> images and paste them in it. Test  the app, you should see the image loaded on the plane:</p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image007.jpg" alt="" width="540" height="400" /></p>
<p>Watch the Demo <a title="The the Part 1 Demo" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Part1"  target="_blank">HERE</a>.</p>
<address><strong>NOTE:</strong> </address>
<address>If  you have any security issues at this point you should disable the compilers  network for now. Do this by right clicking the projects folder, choosing  properties, then clicking on the Actionscript Compiler tab and in the  Additional Compiler Settings, type “-use-network=false”. Don’t forget to  disable this when you go online… This is something anyone using Flex gets to  know one way or the other for quickly getting over any sandbox issues.</address>
<p>Next:</p>
<p>On the next  part we will continue to develop our application by using multiple instances of  this PhotoLoader object, developing advanced camera motion and interactivity.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%201&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-1%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%201&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-1%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs_3d/~4/HC3nPEmO0ww" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/</feedburner:origLink></item>
		<item>
		<title>Setting up Away3d with Flex</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/0nfazOb2w54/</link>
		<comments>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 23:15:19 +0000</pubDate>
		<dc:creator>Alejandro Santander</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[3D Engine]]></category>

		<category><![CDATA[animation]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[cubes]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[object]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=92</guid>
		<description><![CDATA[<p>In this tutorial I will show you how to set up a simple away3d scene, taking advantage of FlexBuilder&#8217;s enhanced programming interface. I will also take advantage of the tutorial to introduce Flex to Flash developers who have never used it.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<p>In  this tutorial I will show you how to set up a simple away3d scene, taking  advantage of FlexBuilder&#8217;s enhanced programming interface. I will also take  advantage of the tutorial to introduce Flex to Flash developers who have never  used it.</p>
<p>The  result is <a title="See the Demo" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/Setting%20up%20away3d%20with%20Flex/Demo/"  target="_blank">THIS</a> and you can download the  source <a title="Download the source files" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/Setting up away3d with Flex/source_files.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/Setting up away3d with Flex/source_files.zip');" target="_blank">HERE</a>.</p>
<h3>Requirements:</h3>
<p><strong>Flex 3</strong></p>
<p><a title="Try/Buy" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Try/Buy</a></p>
<h3>Pre Requisites:</h3>
<p>-  Intermediate programming skills.</p>
<p>-  Some knowledge and understanding of the Actionscript 3 language.</p>
<p>-  Basic principles of OOP (Object Oriented Programming).</p>
<h3>Step 0</h3>
<p>NOTE: you may skip this if you&#8217;re already  familiar with Flex, and know what away3d is.</p>
<p>This  tutorial deals with 2 technologies. Away3d and Flex. Before we start, let me  say a few words about them:</p>
<p>Away3d  is an open source 3d engine designed to boost flash based applications with  powerful 3d capabilities. There are a few other3d engines out there, such as  Papervision3d, Sandy3d, Alternativa3d and more, each with its pros and cons. I  personally useAway3d, because I think its the most apt engine at this time.</p>
<p>Flex  is something most developers that come from the Flash arena fear pretty badly.  What is it?? Well, the thing is that Flex can be used in complement with Flash  for Actionscript projects very easily, providing them with powerful programming  tools.Let me list a few:</p>
<p>-  When you create a new variable and introduce the &#8220;:&#8221; character, Flex  lists all available object types, and if you press enter after you found the  appropriate type, flex automatically creates the import statements for you.  This is extremely handy, since you don’t need to remember what package an  object belongs to, nor consult the API reference to write the appropriate import  statement.</p>
<p>-  Flex detects errors while you code! That is, you don’t need to compile your  project to see if you made mistakes. This is simple magical.</p>
<p>-  By pressing F1 over an object type, Flex takes you to the help section for that  type, and if you press F3, it takes you right to the definition of that object.  This dramatically accelerates the learning process of any given API.</p>
<p>Well,  enough, lets get started. I just wanted to emphasize on the great help that Flex  provides when dealing with AS3 development. Personally, once I got over the  scary, &#8220;what the hell is flex&#8221; phase, I cant imagine working without  it now.</p>
<h3>Step 1</h3>
<p>Download  the FlexBuilder 3 fully functional 60 day trial from adobe and install it. You  just need to create an Adobe account and download the trial from this <a title="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" onclick="javascript:pageTracker._trackPageview('oclicks/https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex');" target="_blank">link</a>.</p>
<p>Then  download the latest <a title="Away3D API" href="http://away3d.com/downloads" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/downloads');" target="_blank">Away3d API</a>.</p>
<h3>Step 2</h3>
<p>Create  a folder somewhere in your hard drive that will work as your workspace for  initial Away3d experimentation. This folder will be able to hold many flex  projects.</p>
<p>Open  flex, select file -&gt; switch workspace, and point flex to the folder you just  created.</p>
<p>Now,  right click on the Flex Navigator panel, and select new “Actionscript Project”.</p>
<p><img class="aligncenter size-full wp-image-93" title="Figure 1" src="http://www.thetechlabs.com/wp-content/uploads/2008/08/img1.jpg" alt="Figure 1" width="500" height="500" /></p>
<p>Once  the dialog shows up, enter Away3dProject as the project name and click finish.</p>
<p>If  you go back to your HD file browser and see the folder you created initially,  you can notice that flex created an inner folder for this project. The Flex  Navigator pretty much works like a regular file browser, listing the projects  you have on that workspace and the files that conform them.</p>
<h3>Step 3</h3>
<p>Go  to your away3d download in your file browser and copy the folder in it named  away3d. Come back to the flex navigator, right click on the Away3dProjectfolder  icon and paste.</p>
<p><img class="aligncenter size-full wp-image-94" title="Figure 2" src="http://www.thetechlabs.com/wp-content/uploads/2008/08/img2.jpg" alt="Figure 2" width="500" height="500" /></p>
<p>That’s  it! Flex is ready to work with the Away3d engine.</p>
<h3>Step 4</h3>
<p>Its  time to code. Right click the Away3dProject folder icon in the Flex Navigator  again, and choose new “Actionscript  class”, name itAway3dScene and click finish. This should automatically open  the file in the coding area, to the right of the Flex Navigator.</p>
<p>The  class should extend Sprite, since this class will contain all away3d stuff and  be treated as any other graphic object. Start by placing this code in it:</p>
<pre>package
{
     import flash.display.Sprite;

     public class Away3dScene extends Sprite
     {
           public function Away3dScene()
           {
                graphics.beginFill(0xFF0000);
                graphics.drawRect(0, 0, 100,  100);
                graphics.endFill();
           }
     }
}</pre>
<h3>Step 5</h3>
<p>Double  click the other .as file in the navigator named Away3dProject.as. Notice that  this one has a little green triangle attached to its icon. This simply states  that when you compile the application, this is the base class, what’s known in  Flash as the Document class.</p>
<p>Place  this code in it:</p>
<pre>package
{
     import flash.display.Sprite;
     import flash.display.StageScaleMode;
     import flash.display.StageAlign;

     public class Away3dProject extends Sprite
     {
           public function Away3dProject()
           {
                stage.scaleMode =  StageScaleMode.NO_SCALE;
                stage.align =  StageAlign.TOP_LEFT;

                var scene:Sprite = new  Away3dScene();
                addChild(scene);
           }
     }
}</pre>
<p>Lines  11 to 12 simply set a couple of stage properties that allow us to be in control  of how the stage is scaled and positioned in the browser, and lines 4 to 5  provide the appropriate import statements for this.</p>
<p>Lines  14 to 15, create an instance of the Away3dScene (which is a Sprite!) and add it  to the stage.</p>
<h3>Step 6</h3>
<p>Above  the Flex Navigator is a little green button with a white play icon in it. This  is what you press to compile the application.Go ahead and compile it. Flex will  open your default web browser and run the demo in it.</p>
<p>Once  you compiled, you should simply see a red square, at the top left corner of the  browser.</p>
<p><img class="aligncenter size-full wp-image-96" title="Figure 3" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/img3.jpg" alt="Figure 3" width="500" height="500" /></p>
<p>Hmm…  What? Well, I just wanted to show you how a class that will be holding all the  3d content can be a Sprite itself, and you can treat it as such, 100%.Alright,  delete lines 9 through 11 of Away3dScene.as and lets get started with the 3d  stuff.</p>
<h3>Step 7</h3>
<p>Now,  lets create an event listener on the constructor that will call the  initialization of the scene when the instance of Away3dScene  is added to the stage. The initialization will be a method called “init()”,  consisting of two sub methods and an event  listener registration for enterframe events.</p>
<p>In  Away3dScene.as, modify the constructor and add the other methods under it as  follows:</p>
<pre>public  function Away3dScene()
{
     addEventListener(Event.ADDED_TO_STAGE,  init, false, 0, true);
}

private  function init(evt:Event):void
{
     removeEventListener(Event.ADDED_TO_STAGE,  init);

     init3dScene();
     init3dObjects();
     addEventListener(Event.ENTER_FRAME,  renderScene);
}

private  function init3dScene():void
{

}

private  function init3dObjects():void
{

}

private  function renderScene(evt:Event):void
{

}</pre>
<p>Make  sure that as you type &#8220;evt:Eve&#8230;&#8221;, press enter when the flex  auto complete dialogue box shows “Event”on one of the function declaration  parameters of “init()” or “renderScene()”. Doing this will ensure that Flex  creates the appropriate import statements automatically.</p>
<p><img class="aligncenter size-full wp-image-97" title="Figure 4" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/img4.jpg" alt="Figure 4" width="500" height="500" /></p>
<p>Now,  why wait until the instance is added to the stage to call the “init()” method?  Its a simple matter actually: In “init3dScene()” we will set up the core of the  3d environment, and when doing this, we need to know the dimensions of the  stage&#8230; and we wouldn’t be able to know this if the sprite (or  Away3dScene instance) wasn’t yet added to the stage! In “init3dObjects()”, as  the name of the method makes it pretty obvious, we will create a bunch of  objects and place them inside the 3d environment.</p>
<h3>Step 8</h3>
<p>The  3d scene will have 3 main elements: a Scene3D object, a Camera3D object, and View3D.  These are all very important classes within the Away3d API. Declare instances  of these as private variables in Away3dScene.as:</p>
<pre>private  var scene:Scene3D;
private  var camera:Camera3D;
private  var view:View3D;</pre>
<p>Make  sure you rewrite this and not just paste it to make sure that Flex imports the  correct classes. Don’t worry, you’ll get used to this ;D</p>
<h3>Step 9</h3>
<p>Lets  build the 3d environment. Place the following code within the “init3dScene()”  method:</p>
<pre>scene  = new Scene3D();

camera  = new Camera3D();
camera.zoom  = 10;
camera.focus  = 200;
camera.z  = -3000;
camera.lookAt(new  Number3D(0, 0, 0));

view  = new View3D();
view.scene  = scene;
view.camera  = camera;
view.clip  = new RectangleClipping(-stage.stageWidth/2, -stage.stageHeight/2,  stage.stageWidth/2, stage.stageHeight/2);
view.x  = stage.stageWidth/2;
view.y  = stage.stageHeight/2;
addChild(view);</pre>
<p>Now,  lets go over those lines slowly. First, we created &#8220;scene&#8221;, an instance  of Scene3D. This is actually the container of all the objects of the 3d  environment. Those of you who are familiar with 3D, it is the main node of the  environment. Then, we create a camera as an instance of Camera3D. This is pretty  intuitive; its the object we will move around and that will represent us, the  spectator, inside the 3denvironment. Notice the parameters of the camera that  are set immediately after its initialization. If you type &#8220;camera.&#8221;,  Flex will automatically bring up the auto complete dialogue box and show you all  available methods and parameters that you can use for this object, so, if you  want to see if the camera has a &#8220;y&#8221; property, type “camera.” And see  if it shows up&#8230; Its pretty handy, and we&#8217;ve never looked at the API reference  yet.</p>
<p>Finally,  we create an instance of View3D. The view will represent the graphical output  of the situation of our camera looking at our scene or environment. It is an  object that extends sprite, and that represents what we see.The first 2  parameters of the view are the scene and the camera. What we are doing here is  just telling it what camera and what scene</p>
<p>It  will refer to.</p>
<p>Then,  we clip and position the view. The clipping part is telling the view which are  its limits in x, y, width and height, and hence setting the center of  coordinates. The positioning part just places the view as if it were a normal  sprite.</p>
<p>Oh,  and of course, the view is added to the display, since it is a graphical  element after all.</p>
<p>Note:  To avoid confusion, Away3dScene (our class) and View3D both extend Sprite,  Scene3D doesn’t! Away3dScene is just a class that we are using to place all the  3d stuff in, it has nothing to do with Scene3D. Sorry about that, I don’t know  why but I see I got used to naming things this way.</p>
<h3>Step 10</h3>
<p>So,  the 3d environment is set. Lets put some stuff in it. I’ve decided to make a  little nested loop structure, in order to make this tutorial a little fancier,  but don’t mind this, what really matters is the creation of the 3d objects:</p>
<pre>var i:uint;
var j:uint;
var  k:uint;
var  spacing:Number = 250;
var  quantity:uint = 3;
var  offset:Number = (quantity-1)*spacing/2;
for(i  = 0; i&lt;quantity; i++)
{
     for(j = 0; j&lt;quantity; j++)
     {
           for(k = 0; k&lt;quantity; k++)
           {
                var cube:Cube = new Cube();
                cube.x = i*spacing - offset;
                cube.y = j*spacing - offset;
                cube.z = k*spacing - offset;
                scene.addChild(cube);
           }
     }
}</pre>
<p>We  are creating the cube instance and then adjusting its parameters the same way  as we created the scene and camera before. To see what kind of primitives you  can create with Away3d, bookmark the away API reference <a href="http://away3d.com/livedocs/" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/livedocs/');">http://away3d.com/livedocs/</a>, check out the primitives package and have the API  handy for future experiments.</p>
<h3>Step 11</h3>
<p>So,  what’s left?</p>
<p>We  just need to implement on more thing and were done. Add this line at the end of  the “init()” method:</p>
<pre>addEventListener(Event.ENTER_FRAME,  renderScene);</pre>
<p>&#8230;and  add this method at the end of the class</p>
<pre>private  function renderScene(evt:Event):void
{
     camera.x = 3*(mouseX - stage.stageWidth/2);
     camera.y = 3*(mouseY -  stage.stageHeight/2);
     camera.lookAt(new Number3D(0, 0, 0));

     view.render();
}</pre>
<p>We’ve  just indicated that after initializing the scene, and then the objects in it, the  application should call the “renderScene()” method on enterframe, that is every  frame of course.</p>
<p>In  “renderScene()”, we will position the camera according to the position of the  mouse over the stage, and of course, render the view.</p>
<p>The  render() method of a View3D object is what calls all the 3d transformation  algorithms of the away3d engine and show us the display output in a view Sprite.</p>
<p>Now  compile… and voila!! That’s it.</p>
<p>Final words.</p>
<p>Pretty  nice huh? If you like it, there are some obvious steps you can take from here.  You can look on the <a title="Away3D Blog" href="http://away3d.com/" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/');" target="_blank">Away3d Blog</a> for lots of info, samples and</p>
<p>Tutorials,  or you could sign up to the mailing list to see a vivid community learning and  expanding the away3d.Away3d can do pretty advanced stuff, specially when you  are ready to play with materials on your objects, or importing 3d models from  external programs. Ill  be writing more tutorials about this when I can.</p>
<p>Hope  its helpful…</p>
<p>Enjoy!</p>
<h3>Complete Code</h3>
<p><strong>Away3dProject.as</strong></p>
<pre>package
{
     import flash.display.Sprite;
     import flash.display.StageScaleMode;
     import flash.display.StageAlign;

     publicclass Away3dProject extends Sprite
     {
           publicfunction Away3dProject()
           {
                stage.scaleMode =  StageScaleMode.NO_SCALE;
                stage.align =  StageAlign.TOP_LEFT;

                var scene:Away3dScene = new Away3dScene();
                addChild(scene);
           }
     }
}</pre>
<p><strong>Away3dScene.as</strong></p>
<pre>package
{
     import away3d.cameras.Camera3D;
     import away3d.containers.Scene3D;
     import away3d.containers.View3D;
     import away3d.core.math.Number3D;
     import away3d.core.render.RectangleClipping;
     import away3d.primitives.Cube;

     import flash.display.Sprite;
     import flash.events.Event;

     publicclass Away3dScene extends Sprite
     {
           privatevar scene:Scene3D;
           privatevar camera:Camera3D;
           privatevar view:View3D;

           publicfunction Away3dScene()
           {
                addEventListener(Event.ADDED_TO_STAGE,  init, false, 0, true);
           }

           privatefunction init(evt:Event):void
           {
                removeEventListener(Event.ADDED_TO_STAGE,  init);

                init3dScene();
                init3dObjects();
                addEventListener(Event.ENTER_FRAME,  renderScene);
           }

           privatefunction init3dScene():void
           {
                scene = new Scene3D();

                camera = new Camera3D();
                camera.zoom = 10;
                camera.focus = 200;
                camera.z = -3000;
                camera.lookAt(new Number3D(0, 0, 0));

                view = new View3D();
                view.scene = scene;
                view.camera =  camera;
                view.clip = new RectangleClipping(-stage.stageWidth/2, -stage.stageHeight/2,  stage.stageWidth/2, stage.stageHeight/2);
                view.x =  stage.stageWidth/2;
                view.y =  stage.stageHeight/2;
                addChild(view);
           }

           privatefunction init3dObjects():void
           {
                var i:uint;
                var j:uint;
                var k:uint;
                var spacing:Number = 250;
                var quantity:uint = 3;
                var offset:Number = (quantity-1)*spacing/2;
                for(i = 0; i&lt;quantity; i++)
                {
                     for(j = 0; j&lt;quantity; j++)
                     {
                           for(k = 0; k&lt;quantity; k++)
                           {
                                var cube:Cube = new Cube();
                                cube.x  = i*spacing - offset;
                                cube.y  = j*spacing - offset;
                                cube.z  = k*spacing - offset;
                                scene.addChild(cube);
                           }
                     }
                }
           }

           privatefunction renderScene(evt:Event):void
           {
                camera.x =  3*(mouseX - stage.stageWidth/2);
                camera.y =  3*(mouseY - stage.stageHeight/2);
                camera.lookAt(new Number3D(0, 0, 0));

                view.render();
           }
     }
}</pre>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Setting%20up%20Away3d%20with%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsetting-up-away3d-with-flex%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Setting%20up%20Away3d%20with%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsetting-up-away3d-with-flex%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs_3d/~4/0nfazOb2w54" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/</feedburner:origLink></item>
		<item>
		<title>Building a 3D album with FIVe3D and TweenLite</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/6Ow6tW68efM/</link>
		<comments>http://www.thetechlabs.com/3d/building-a-3d-album-with-five3d-and-tweenlite/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 21:06:49 +0000</pubDate>
		<dc:creator>Bartek Drozdz</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[five3d]]></category>

		<category><![CDATA[gallery]]></category>

		<category><![CDATA[tweenlite]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=62</guid>
		<description><![CDATA[<p>In this tutorial I will show you how to build a simple 3D photo album in AS3. We will build an application similar to this one.</p>
<p>I will use two AS3 libraries: FIVe3D and TweenLite, both open source. Five3D is a lightweight 3D library written by Mathieu Badimon. TweenLite is one of the many libraries available for script based animation in AS3. It was created by Jack Doyle from Greensock. It&#8217;s principal characteristic is that it&#8217;s small (hence it&#8217;s name) and simple to use. FIVe3D and TweenLite work very well together!</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Bartek Drozdz <a href="http://www.thetechlabs.com/3d/building-a-3d-album-with-five3d-and-tweenlite/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>In this tutorial I will show you how to build a simple 3D photo album in AS3. We will build an application <a title="Open Demo" href="http://www.thetechlabs.com/tutorials/files/flash/bartek/index.html"  target="_blank">similar to this one</a>.</p>
<p>I will use two AS3 libraries: FIVe3D and TweenLite, both open source. Five3D is a lightweight 3D library written by Mathieu Badimon. TweenLite is one of the many libraries available for script based animation in AS3. It was created by Jack Doyle from Greensock. It&#8217;s principal characteristic is that it&#8217;s small (hence it&#8217;s name) and simple to use. FIVe3D and TweenLite work very well together!</p>
<p>Please visit the homepages of both these libraries - <a href="http://five3d.mathieu-badimon.com/" onclick="javascript:pageTracker._trackPageview('oclicks/http://five3d.mathieu-badimon.com/');" target="_blank">FIve3D</a>, <a href="http://blog.greensock.com/tweenliteas3/" onclick="javascript:pageTracker._trackPageview('oclicks/http://blog.greensock.com/tweenliteas3/');" target="_blank">TweenLite</a> - to learn more. You do not have to download them however - they are already included in the tutorial files. I used FIVe3D v2.1 and TweenLite v6.31 (both latest ones at the time I was writing this).</p>
<p>The pictures of Stockholm used in this tutorial are from my private collection.</p>
<h3>1. Setting up the workspace</h3>
<p>Start by downloading the tutorial files - <a title="Download Source Files" href="/tutorials/files/flash/bartek/3dalbum.zip" target="_self">here</a>. Unpack the ZIP file into a folder on your disk. Inside the package you will find a folder called &#8216;work&#8217;. This folder contains a FLA file and all the classes you need to build the album. Open the &#8216;album.fla&#8217; file you will find in there.</p>
<p>You do not have to modify anything in the &#8216;album.fla&#8217;, but let&#8217;s just take a look what&#8217;s in there. The document class should be set to &#8216;Main&#8217;, the AS3 classpath in the &#8216;Publish settings&#8217; - to &#8216;./src&#8217;. Finally, the export path in the should point to &#8216;../album.swf&#8217;.</p>
<p>Now open the &#8217;src/Main.as&#8217; with your favourite AS3 editor. This is our document class. It doesn&#8217;t do anything for the moment, but you can notice that is extends the &#8216;Sprite&#8217; class, sets the scaling and alignment properties of the &#8217;stage&#8217; object and traces a short message. Test &#8216;album.fla&#8217; using Ctrl+Enter in the Flash IDE. You should see a black screen and a message in the output window saying &#8216;Ready to go!&#8217;. If you see this message, then in fact we ARE ready to go!</p>
<p>Quick note: The folder &#8216;full&#8217; contains complete source files of the finished application. Use it for reference, if you have problems or bugs. The folder &#8216;pictures&#8217; contains the pictures used in this example.</p>
<h3>2. Loading pictures</h3>
<p><img class="alignnone size-full wp-image-64" title="Loading" src="http://www.thetechlabs.com/wp-content/uploads/2008/07/loading.jpg" alt="" width="500" height="50" /></p>
<p>Now that you have both files open - all the work will consist of editing the &#8216;Main.as&#8217; file and testing it by exporting the &#8216;album.fla&#8217; file.</p>
<p>The first step is to load all the pictures we will be using in our album. They are located in the &#8216;photos&#8217; folder, and since the &#8217;swf&#8217; file is exported to the root folder, the path to the pictures in our application will look like this: &#8216;photos/photoName.jpg&#8217;.</p>
<p>Let&#8217;s start by adding some import statements that we will need at this stage:</p>
<pre>import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;</pre>
<p>Now, let&#8217;s declare some objects we will be using. Variables should always be declared just below the class declaration line, and in that case it should look like that:</p>
<pre>public class Main extends Sprite {

 private var numPicture:int = 9;
 private var picturePath:String = "photos/photo0";
 private var pictureExtensiton:String = ".jpg";
 private var loadingIndex:int = 1;
 private var loadingInfo:TextField;
 private var pictures:Array;
 private var pictureLoader:Loader;</pre>
<p>The variable &#8216;numPictures&#8217; holds the total number of pictures, and &#8216;picturePath&#8217; and &#8216;pictureExtensiton&#8217; will be used to construct a correct path to each picture.</p>
<p><em>In a real world solution you would probably load an XML file containing all the paths to all the pictures, the total number and maybe even a title and a description for each one. Loading and parsing XML files goes beyond the scope of this tutorial however, so for the sake of simplicity all those values are hard coded. If you want, after you complete the tutorial, you can modify the code so that it uses an XML file. This would be a great exercise!</em></p>
<p>The &#8216;loadingIndex&#8217; property will helps us keep track of how many pictures are already loaded. We will display this information to the user - this is what the &#8216;loadingInfo&#8217; text field is for. All the loaded pictures will be put into the &#8216;pictures&#8217; array. Finally, to load the pictures, we will use a Loader object, that I called the &#8216;pictureLoader&#8217; (obvious name, isn&#8217;t it?).</p>
<p>At this moment, we can add some actual code. In the constructor function you can remove the line with the &#8216;trace&#8217; command and replace it with this:</p>
<pre>loadingInfo = new TextField();
loadingInfo.defaultTextFormat = new TextFormat("Verdana", 10, 0xffffff);
loadingInfo.autoSize = TextFieldAutoSize.LEFT;
loadingInfo.text = "Loading picture " + loadingIndex + " of " + numPicture;
loadingInfo.x = stage.stageWidth/2 - loadingInfo.textWidth/2;
loadingInfo.y = stage.stageHeight/2 - loadingInfo.textHeight/2;
addChild(loadingInfo);
pictures = new Array();
loadPicture();</pre>
<p>The first 7 (out of 9!) lines are needed to create and position a text field that we will use to display a preloading information. I heard people complaining that in AS3 you have to write lots of code to do a simple thing. Sometimes it&#8217;s true <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Apart from adding the text field, we also initialize the &#8216;pictures&#8217; array and we call the &#8216;loadPicture&#8217; function. If you try to export your fla at this point, you will get an error, since this function is not yet there. Let&#8217;s add it after right after the constructor:</p>
<pre>private function loadPicture() {
  pictureLoader = new Loader();
  pictureLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onPicture);
  pictureLoader.load(new URLRequest(picturePath + loadingIndex + pictureExtensiton));
  loadingIndex++;
}

private function onPicture(e:Event):void {
  var picture:BitmapData = (e.target.content as Bitmap).bitmapData;
  pictures.push(picture);
  if (loadingIndex &lt;= numPicture) {
    loadingInfo.text = "Loading picture " + loadingIndex + " of " + numPicture;
    loadPicture();
  } else {
    removeChild(loadingInfo);
    buildAlbum();
  }
}

private function buildAlbum():void {
  trace("Pictures loaded!");
}</pre>
<p>I know, it is 3 function instead of just one! They are all needed for to complete the loading operation, that&#8217;s why they are here.</p>
<p>The function &#8216;loadPicture&#8217; load a single picture and increments the &#8216;loadingIndex&#8217; variable by 1.</p>
<p>Since I add an event listener to the loader, when the picture is loaded the &#8216;onPicture&#8217; function is invoked. At this point I check if the &#8216;loadingIndex&#8217; is still less then the total number of pictures. If this is true - I call loadPicture again to load the next one. If not, it means that all the pictures are there. In that case I can remove the loading information text field and call a function to build the album. Export your fla and you should see the text &#8216;Pictures loaded!&#8217; in the output window after a short while.</p>
<p>Take a look a the first line of code in the &#8216;onPicture&#8217; method. When external images are loaded, whether it is a jpg, gif or a png, Flash will wrap it into a object of type &#8216;Bitmap&#8217;. A Bitmap is a DisplayObject, so it can be added to the display list and thus be display on the screen. However, in our case we do not want to display the pictures directly. We will use them as 3D textures instead, so we do not need the Bitmap object, but a BitmapData objects instead. Fortunately they are easily accessible from Bitmap.bitmapData, and this is what the first line in that function does. In the next line I store the BitmapData in the &#8216;pictures&#8217; array for later use.</p>
<h3>3. Building 3D album</h3>
<p><img class="alignnone size-full wp-image-65" title="Flat" src="http://www.thetechlabs.com/wp-content/uploads/2008/07/flat.jpg" alt="" width="500" height="192" /></p>
<p>If you tested the application so far, you should get the &#8216;Pictures loaded!&#8217; message in the output window. Now let&#8217;s display them!</p>
<p>First, we will need to import some more classes. Add this in the import section at the top of the class:</p>
<pre>import five3D.display.Scene3D;
import five3D.display.Bitmap3D;
import five3D.display.Sprite3D;
import flash.geom.ColorTransform;</pre>
<p>These are the all the 3D classes from the FIVe3D library we will be need (yes, only 3!). The ColorTransform class will be used for rollover/rollout effects.</p>
<p>Next, we need to declare some more variables. Right after the previous declarations, enter the following code lines:</p>
<pre>private var scene:Scene3D;
private var album:Sprite3D;
private var padding:Number = 60;
private var fullViewZ:Number = 2400;
private var darker:ColorTransform = new ColorTransform(.8, .8, .8, 1, 0, 0, 0, 0);
private var lighter:ColorTransform = new ColorTransform(1, 1, 1, 1, 0, 0, 0, 0);</pre>
<p>All 3D content in FIVe3Dmust be put inside a Scene3D. We&#8217;ll use the scene variable to store a reference to this object. Our album will be a Sprite3D, and this is what we declare next. The &#8216;padding&#8217; is the distance between pictures in the album, so that they do not stick one to another. The &#8216;fullViewZ&#8217; property is the z-distance of the album from the screen. The bigger the z value the further in depth the object appears. 2400 is a value big enough to allow us to see all the pictures in the same time, not cropped.</p>
<p>The &#8216;darker&#8217; an &#8216;lighter&#8217; ColorTransform object will be used for rollover effects. When applied to a Sprite, the &#8216;darker&#8217; makes it slightly&#8230; darker. The &#8216;lighter&#8217; restores the sprites original colors. One of the coolest things in FIVe3D is that a Sprite3D actually extends a regular Sprite and most of the operations that can be done on a Sprite can also be done on a Sprite3D. That includes the changing transform.colorTransform property that we are going to use here.</p>
<p>The real fun begins now! We will start to build a 3D view of the album. Replace the trace command in the &#8216;buildAlbum&#8217; function with this:</p>
<pre>scene = new Scene3D();
scene.x = Math.round(stage.stageWidth/2);
scene.y = Math.round(stage.stageHeight / 2);
addChild(scene);</pre>
<p>This code will create the indispensable Scene3D, position it in the middle of the screen and add it to the display list. And that&#8217;s it, the 3D stage is ready! Now, we can create the album. Continue by adding this:</p>
<pre>album = new Sprite3D();

for (var i:int = 0;  i &lt; pictures.length; i++) {
  var bitmap3d:Bitmap3D = new Bitmap3D(pictures[i] as BitmapData);
  var picture3d:Sprite3D = new Sprite3D();

  bitmap3d.x = bitmap3d.bitmapData.width / -2;
  bitmap3d.y = bitmap3d.bitmapData.height / -2;
  picture3d.addChild(bitmap3d);

  var row:Number = Math.floor(i / 3) - 1;
  var col:Number = i % 3 - 1;
  var pw:Number = bitmap3d.bitmapData.width + padding;
  var ph:Number = bitmap3d.bitmapData.height + padding;
  picture3d.x = row * pw;
  picture3d.y = col * ph;

  picture3d.transform.colorTransform = darker;
  picture3d.buttonMode = true;
  album.addChild(picture3d);
}

album.z = fullViewZ;
scene.addChild(album);</pre>
<p>This code is a bit more complicated, but still very simple to understand. First, we create the album Sprite3D. This one will be a holder for all the pictures.</p>
<p>Next, in a for loop, we traverse the pictures array (remember that one?) It holds a collection of objects of type BitmapData, each one representing a picture. To display the picture in 3D we must wrap it into a Bitmap3D object, and this is what we do first.</p>
<p>Each picture must be clickable. Unfortunately a Bitmap3D does not extend Sprite3D so it doesn&#8217;t support interactivity - this is the same situation as with Sprite vs. Bitmap in regular AS3. To make the pictures interactive we need to wrap each Bitmap3D into a Sprite3D.</p>
<p>When a child is added its top-left corner is always positioned a 0,0 coordinates of its parent. It works so in AS3, and FIVe3D correctly follows this behavior. What we need here is to position the Bitmap3D inside the Sprite3D in a way that its center is at 0,0 coordinates not its top-left corner. That is why offset the x and y coordinates of the bitma3d by half its width and half its height respectively.</p>
<p>Next, using some simple math we distribute the Sprite3Ds in a 3&#215;3 pattern.</p>
<p>Finally we apply a dark color transform to each Sprite3D, we set their &#8216;buttonMode&#8217; property to true and we add it as a child to the &#8216;album&#8217; Sprite3D. The final code after the loop positions the album on a correct z distance (while x and y are set 0 by default). And, once the album is ready, we add it to the scene object as a child.</p>
<p>You can test the application now. You should see all 9 pictures as small thumbnails laid out in a 3&#215;3 pattern in the middle of the screen. Not very interesting, huh? Yep! And it won&#8217;t get any better until we add some interactivity!</p>
<h3>4. Adding interactivity</h3>
<p>Interactivity in the album will consist of handling some mouse events and using TweenLite to animate objects. Before we move on let&#8217;s add a final set of imports:</p>
<pre>import gs.TweenLite;
import fl.motion.easing.Sine;
import flash.events.MouseEvent;</pre>
<p>TweenLite is just one class. To define the easing of animations is uses the classes from the standard fl.motion.easing package - we will use the Sine. At the end, we need the MouseEvent to handle mouse interaction of course.</p>
<p>We also need to declare two more variables:</p>
<pre>private var zoomMode:Boolean = false;
private var zoomedPicture:Sprite3D;</pre>
<p>The boolean value &#8216;zoomMode&#8217; will inform us whether the album is in full view or if one of the pictures is zoomed. &#8216;zoomedPicture&#8217; will be use to hold a reference to the currently zoomed picture. This behavior will be added in the last step of the tutorial, but we need these variable already now.</p>
<p>Now let&#8217;s get back to the &#8216;buildAlbum&#8217;. Right after the last line, where the album is added to the scene, let&#8217;s enter some listeners:</p>
<pre>album.addEventListener(MouseEvent.ROLL_OVER, onOver, true);
album.addEventListener(MouseEvent.ROLL_OUT, onOut, true);
stage.addEventListener(Event.RESIZE, onResize);
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveAlbum);</pre>
<p>The first two lines need special attention. What I do here is add a rollover and a rollout listeners to the container that holds the pictures. Now, of course, I do not want to listen to the rollover/out event on the container, but I&#8217;d rather do that on each picture. That is what the third argument does. This argument is called &#8216;useCapture&#8217; and if it is set to &#8216;true&#8217; it will notify the parent display object - the album in this case - of any event of that type dispatched by any of is children (or any of its descendants to be exact). So whenever a Sprite3D containing a single picture is rolled over or out, the album, its parent, is notified. It is a very powerful technique of the AS3 event system!</p>
<p>Now we can add the functions to handle the rollover/rollout events. Notice how I get a reference to the object that dispatched the event using the &#8216;target&#8217; property of the event object:</p>
<pre>private function onOver(me:MouseEvent):void {
  if (me.target is Sprite3D &amp;&amp; !zoomMode) {
    (me.target as Sprite3D).transform.colorTransform = lighter;
  }
}

private function onOut(me:MouseEvent):void {
  if (me.target is Sprite3D &amp;&amp; !zoomMode) {
    (me.target as Sprite3D).transform.colorTransform = darker;
  }
}</pre>
<p>The next listener will be called whenever the stage is resized. That happens, for example, when the user resizes his browser window. If that happens we will center the Scene3D on the screen. Such feature is always nice to have, and the code is simple:</p>
<pre>private function onResize(e:Event):void {
  scene.x = Math.round(stage.stageWidth/2);
  scene.y = Math.round(stage.stageHeight / 2);
}</pre>
<p>Of course, I left the best for the end. Here&#8217;s the function that handles the 3D movement of the album based on the mouse pointer position:</p>
<pre>private function moveAlbum(me:MouseEvent):void {
  if (zoomMode) return; 

  var mouseXPos:Number = (me.stageX - stage.stageWidth/2) / (stage.stageWidth / 2);
  var mouseYPos:Number = (me.stageY - stage.stageHeight/2) / (stage.stageHeight / 2);

  TweenLite.killTweensOf(album);
  var props:Object = new Object();
  props.rotationY = 45 * mouseXPos;
  props.rotationX = -15 * mouseYPos;
  props.x = 400 * mouseXPos;
  props.y = 300 * mouseYPos;
  props.ease = Sine.easeOut;
  TweenLite.to(album, .3, props);
}</pre>
<p>I introduced the zoomMode flag here, because all the mouse interaction, as well as rollover/out interaction will be disabled when one picture is zoomed. We will add this functionality in the next part of the tutorial.</p>
<p>After this basic check, I divide the mouse position by the stage width in a way to get a value between -1 and 1, where -1 means the mouse is on the left edge of the screen, and 1 means it is on the right.</p>
<p>Next, I call the &#8216;killTweensOf&#8217; method to make sure any animation that might be going on now will be terminated. Now I can setup and start a new animation.</p>
<p>I assemble the properties of the new animation in the props object. They are all based on the mouse position and have some maximal values. For example, rotationY can have a minimum value of -45 and a maximum value of 45 degrees. Once the animation properties are ready, I must add a last one, called &#8216;ease&#8217; which specifies the type of movement and easing to use. In the last line I call TweenLite and pass the object to be animated - the album, a time for the animation expressed in seconds - 0.3 seconds in this case, and the target properties for the animation.</p>
<p>Try the application now. The 3&#215;3 album should be responding to the mouse movement by rotating and moving sideways. Each picture should become slightly lighter on rollover and darker again on rollout. Finally, if you resize the window, the album will always be centered vertically and horizontally.</p>
<p>You&#8217;d better start enjoying 3D flash applications by now. Because you&#8217;re in one!</p>
<h3>5. Zooming pictures</h3>
<p><img class="alignnone size-full wp-image-66" title="Zoom" src="http://www.thetechlabs.com/wp-content/uploads/2008/07/zoom.jpg" alt="" width="500" height="273" /></p>
<p>Before we finish we need to add one more important feature: the ability to zoom pictures. We do not need any new import statements, nor do we need to declare any more variables. What we need to do is to add another listener. In &#8216;buildAlbum&#8217; function add a last line:</p>
<pre>stage.addEventListener(MouseEvent.CLICK, onClick);</pre>
<p>And here is the &#8216;onClick&#8217; function.</p>
<pre>private function onClick(me:MouseEvent):void {
  var props:Object;

  if (me.target is Sprite3D &amp;&amp; !zoomMode) {
    TweenLite.killTweensOf(album);
    props = new Object();
    props.z = 0;
    props.rotationX = 0;
    props.rotationY = 0;
    props.x = 0 - me.target.x;
    props.y = 0 - me.target.y;
    props.ease = Sine.easeInOut;
    TweenLite.to(album, .6, props);

    zoomedPicture = me.target as Sprite3D;
    zoomMode = true;
  } else if (zoomMode) {
    zoomedPicture.transform.colorTransform = darker;

    TweenLite.killTweensOf(album);
    props = new Object();
    props.z = fullViewZ;
    props.x = 0;
    props.y = 0;
    props.ease = Sine.easeOut;
    props.onComplete = onBackToFull;
    TweenLite.to(album, .3, props);
  }
}</pre>
<p>In that case we are listening to a mouse click event on the stage object. That means that any click anywhere on the stage will result in calling this function. That is why what we need to know what was clicked and what is the state of the application, before we can take any action. We will use the &#8216;target&#8217; property of the event object and the &#8216;zoomMode&#8217; flag to figure this out.</p>
<p>First possibility: a picture was clicked. That means the target is a Sprite3D and the zoomMode is off. This is the situation handled by the first part of the &#8216;if&#8217; statement. In that case we start a tween with all the rotation properties set to 0 - we want the picture to face the screen. For the x and y, we also set them to 0 and we subtract the position of the picture inside the album - this way the zoomed picture will always be positioned in the middle of the screen.</p>
<p>The z property for the album is also set to 0, but in that case 0 has a special meaning. In FIVe3D, if you keep the default settings for the Scene3D object (as I do here) and set an objects &#8216;z&#8217; property to 0 it will be scaled 1:1 to it&#8217;s original size. This way we make sure the pictures will have the best possible quality when zoomed in.</p>
<p>Finally we keep a reference to the clicked picture in the &#8216;zoomedPicture&#8217; variable and set the &#8216;zoomMode&#8217; flag to true.</p>
<p>The next possibility is that a click event occurred when &#8216;zoomMode&#8217; in on. In this situation we &#8216;un-zoom&#8217; the album no matter what was clicked.</p>
<p>The second part of the &#8216;if&#8217; statement does pretty much the opposite of the first one as long as the animation is concerned. What is worth noting is that the &#8216;zoomMode&#8217; is not being reset. Instead I create a new property for the TweenLite called &#8216;onComplete&#8217;. It takes a function as argument. That function will be called when the animation is over. Here&#8217;s the code:</p>
<pre>private function onBackToFull():void {
  zoomMode = false;
}</pre>
<p>I reset the &#8216;zoomMode&#8217; property after the animation is over, because if it was reset before, the animation caused by the movement of the mouse pointer could interfere with the zoom out, possibly causing an unpredictable behavior.</p>
<h3>Conclusion</h3>
<p>If you take a look at the swf you will notice that it is around 16KB in total. The Main class consists of less then 200 lines of code. It means that you just made yourself a 3D photo album application that loads in less then a second and with virtually no coding at all (200 lines, come on!). Isn&#8217;t it awesome?</p>
<p>Now it is your turn to take this application to the next level:</p>
<ul>
<li>Load the album information from an XML file</li>
<li>Add a title and a description for each picture</li>
<li>Use 3D to dislpay them - FIVe3D is particularly good at handling 3D text</li>
<li>Make it work with any number of pictures of different size and aspect ratios</li>
<li>Load the pictures from your flickr account using the Flickr API</li>
<li>A nice tweak would be to add reflections for the pictures in the bottom row</li>
<li>In the zoom mode, the other pictures could be accessible without having to zoom out first</li>
<li>or&#8230; anything else you want <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Hope you enjoyed the tutorial. Have fun!</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Building%20a%203D%20album%20with%20FIVe3D%20and%20TweenLite&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fbuilding-a-3d-album-with-five3d-and-tweenlite%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Building%20a%203D%20album%20with%20FIVe3D%20and%20TweenLite&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fbuilding-a-3d-album-with-five3d-and-tweenlite%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs_3d/~4/6Ow6tW68efM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/building-a-3d-album-with-five3d-and-tweenlite/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/3d/building-a-3d-album-with-five3d-and-tweenlite/</feedburner:origLink></item>
		<item>
		<title>Create a AS3 MP3 Player with papervision3d spectrum display</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_3d/~3/dXzgeRvapZs/</link>
		<comments>http://www.thetechlabs.com/3d/create-a-as3-mp3-player-with-papervision3d-spectrum-display/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 00:22:06 +0000</pubDate>
		<dc:creator>Rafael Nuenlist</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Sound]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[mp3 player]]></category>

		<category><![CDATA[papervision 3d]]></category>

		<category><![CDATA[spectrum]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=58</guid>
		<description><![CDATA[<p>As we&#8217;ve already promised you, here&#8217;s the tutorial about how to create a 3d spectrum display from a sound file with papervision3d and flash.<br />
On this tutorial, we&#8217;ll focus on the 3d part. If you&#8217;re not comfortable with the SoundMixer.computeSpectrum method then you should read the previous tutorial.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Rafael Nuenlist <a href="http://www.thetechlabs.com/3d/create-a-as3-mp3-player-with-papervision3d-spectrum-display/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[<p>As we&#8217;ve already promised you, here&#8217;s the tutorial about how to create a 3d spectrum display from a sound file with papervision3d and flash.<br />
On this tutorial, we&#8217;ll focus on the 3d part. If you&#8217;re not comfortable with the SoundMixer.computeSpectrum method then you should read the <a title="Create a AS3 / Flash 9 MP3 Player with spectrum display" href="http://www.thetechlabs.com/sound/create-a-as3-flash-9-mp3-player-with-spectrum-display/"  target="_blank">previous tutorial</a>.<br />
So, let&#8217;s start with the fun.</p>
<h3>Requirements</h3>
<p><strong>Adobe Flash CS3</strong></p>
<p><a title="Try / buy" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Try / Buy</a></p>
<p><strong>Source Files</strong></p>
<p><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('/downloads/tutorials/files/flash/fcarrera/flickrsearchengine/flickrsearchengine_sfiles.zip');" href="http://www.thetechlabs.com/tutorials/files/flash/rnunlist/pv3d-spectrum.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flash/rnunlist/pv3d-spectrum.zip');" target="_self">Download</a></p>
<h3>Getting Started</h3>
<p>For this demo application, we&#8217;ve used the latest version of papervision3d with the code name GreatWhite.<br />
First of all, we need to include the papervision3d stuff.</p>
<pre>import org.papervision3d.cameras.Camera3D;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.utils.MaterialsList;
</pre>
<p align="justify">These are all the classes we need for our application. The Camera3D class enables you to focus on a 3d object and zoom to it. Scene3D is a container that holds all 3d objects. The Viewport will be added to the main stage and is like a video screen that shows the result. Another important class is the BasicRenderEngine which renders all the objects from the scene with the current camera settings and outputs the result to the viewport. Papervision comes with different types of objects, but for our example we&#8217;ll only need the cube. And finally there are the materials which can be set to the objects. This is how papervision basically works.</p>
<p>Then we to set some constants for the sound channel</p>
<pre>const CHANNELS_PER_DIRECTION:int= 256;
const CUBES_PER_CHANNEL:int		= 8;
const CHANNEL_STEPS:int			= Math.floor(CHANNELS_PER_DIRECTION / CUBES_PER_CHANNEL);
</pre>
<p>Next thing to do is to set the papervision variables</p>
<pre>var viewport:Viewport3D;
var scene:Scene3D;
var camera:Camera3D;
var cube:Cube;
var renderer:BasicRenderEngine;
</pre>
<p>To keep a reference of each cube, we need to create 2 arrays. For each sound channel (left, right)</p>
<pre>var cubesLeftChannel:Array		= new Array();
var cubesRightChannel:Array		= new Array();
</pre>
<p>At the end, we want to swing our camera from left to right and	vice versa. To know in which direction we&#8217;re currently moving, we need to set a flag:</p>
<pre>var bolAnimationForward:Boolean 	= true;
</pre>
<p>The next part is the same as in the previous tutorial. We create a new sound object and a url request for requesting the mp3 file. SndBytes will hold the current spectrum data.</p>
<pre>var sndObject:Sound			= new Sound();
var reqObject:URLRequest 		= new URLRequest("so-deep.ram2000.mp3");
var sndBytes:Byte