Michael Jackson Pearl Jam Stevie Ray Vaughan Ozzy Osbourne Finntroll MP3 list A Fine Frenzy Capone Phil Collins Shakira Pink Floyd Keane

Tag Archive for 'Papervision Animation using TweenLite'

A Simple Papervision Coverflow

There are several great AS3 / Papervision Coverflows out there but today I set out to create one in it's simplest form. There are no bells and whistles, just a stripped down coverflow with it's core functionality. It's up to you to add an XML feed, Flickr feed, or setup your images in an array and load them the way you want to. This is only meant to be a clean jumping off point.

In the download I have included 2 versions. One with left / right buttons and one without. Both versions you can select the items in the coverflow to navigate.

The heart of this coverflow app is a lot like some of the others. We need to calculate the x and rotation of the center item, left items, and right items are, then animate accordingly. This is the same way that John Dyer animates his coverflow.

Actionscript:
  1. for (var i:int = 0; i <planes.length; i++)
  2. {
  3.     var plane:Plane = planes[i];
  4.    
  5.     //Each if statement will adjust these numbers as needed
  6.     var planeX:Number = 0;
  7.     var planeZ:Number = 20;
  8.     var planeRotationY:Number = 0
  9.  
  10.     //Place  & Animate Center Item
  11.     if (i == currentItem)
  12.     {
  13.         planeZ     = -300
  14.        
  15.         TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  16.     }
  17.    
  18.     //Place & Animate Right Items
  19.     if(i> currentItem) 
  20.     {
  21.         planeX     = (i - currentItem + 1) * 120;
  22.         planeRotationY   = angle + 10 * (i - currentItem);
  23.        
  24.         TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  25.     }
  26.    
  27.     //Place & Animate Left Items
  28.     if (i <currentItem)
  29.     {
  30.         planeX     = (currentItem - i + 1) * -120;
  31.         planeRotationY   = -angle - 10 * (currentItem - i);
  32.        
  33.         TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  34.     }
  35. }

For this simple version of coverflow you have two ways of navigating to items.

Selecting a plane to jump right to that item

Actionscript:
  1. plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onPlaneClick);
  2.  
  3. protected function onPlaneClick(evt:InteractiveScene3DEvent):void
  4. {
  5.     currentItem = evt.target.id;
  6.     animate();
  7. }

Or using left / right buttons to navigate one item at a time:

Actionscript:
  1. rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  2. leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  3.  
  4. protected function buttonClick(evt:MouseEvent):void
  5. {
  6.     switch (evt.target)
  7.     {
  8.         case rightBtn:
  9.         currentItem ++
  10.         break;
  11.        
  12.         case leftBtn:
  13.         currentItem --;
  14.         break;
  15.     }
  16.    
  17.     //Don't allow any number lower than 0 or past max so there
  18.     //is always a center item
  19.    
  20.     if (currentItem <0)
  21.     {
  22.         currentItem = 0;
  23.     }
  24.     if (currentItem> (planes.length - 1))
  25.     {
  26.         currentItem = planes.length - 1;
  27.     }
  28.    
  29.     //Call animation
  30.     animate();
  31. }

On to the full source code. This version includes the left / right buttons.

Actionscript:
  1. package
  2. {
  3.     import flash.display.DisplayObject;
  4.     import flash.display.Sprite;
  5.     import flash.events.Event;
  6.     import flash.events.MouseEvent;
  7.     import flash.filters.GlowFilter;
  8.     import gs.easing.Quint;
  9.     import gs.TweenLite;
  10.     import org.papervision3d.events.InteractiveScene3DEvent;
  11.     import org.papervision3d.materials.BitmapFileMaterial;
  12.     import org.papervision3d.objects.DisplayObject3D;
  13.     import org.papervision3d.objects.primitives.Plane;
  14.     import org.papervision3d.view.BasicView;
  15.    
  16.     /**
  17.      * ...
  18.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  19.      * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
  20.      */
  21.    
  22.     public class Main extends BasicView
  23.     {
  24.         protected var planes:Array = [];
  25.         protected var numItems:Number = 7;
  26.         protected var currentItem:Number = 3;
  27.         protected var angle:Number = 25;
  28.        
  29.         protected var mat:BitmapFileMaterial;
  30.         protected var rightBtn:Sprite;
  31.         protected var leftBtn:Sprite;
  32.        
  33.         public function Main():void
  34.         {
  35.             //Make sure that your scene is set to interactive
  36.             super(640, 480, true, true);
  37.            
  38.             init();
  39.         }
  40.         protected function init():void
  41.         {
  42.             createChildren();
  43.             createNavigation();
  44.             animate();
  45.             startRendering();
  46.         }
  47.         protected function createChildren():void
  48.         {
  49.             //Create Material
  50.             mat             = new BitmapFileMaterial("images/iPhone-back2.png");
  51.             mat.smooth   = true;
  52.             mat.interactive = true;
  53.             for (var i:int = 0; i <numItems; i++)
  54.             {
  55.                 var plane:Plane = new Plane(mat, 177, 334, 4, 4);
  56.                 planes.push(plane);
  57.                
  58.                 //Click straight to any plane
  59.                 plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onPlaneClick);
  60.                
  61.                 //Set an id to target current item
  62.                 plane.id = i;
  63.                
  64.                 //Add plane to the scene
  65.                 scene.addChild(plane);
  66.             }
  67.            
  68.             camera.zoom = 60;
  69.         }
  70.        
  71.         protected function onPlaneClick(evt:InteractiveScene3DEvent):void
  72.         {
  73.             currentItem = evt.target.id;
  74.             animate();
  75.         }
  76.        
  77.         //Animate the coverflow left / right based off of currentItems
  78.         protected function animate():void
  79.         {
  80.             for (var i:int = 0; i <planes.length; i++)
  81.             {
  82.                 var plane:Plane = planes[i];
  83.                
  84.                 //Each if statement will adjust these numbers as needed
  85.                 var planeX:Number = 0;
  86.                 var planeZ:Number = -50;
  87.                 var planeRotationY:Number = 0
  88.  
  89.                 //Place  & Animate Center Item
  90.                 if (i == currentItem)
  91.                 {
  92.                     planeZ     = -300
  93.                    
  94.                     TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  95.                 }
  96.                
  97.                 //Place & Animate Right Items
  98.                 if(i> currentItem) 
  99.                 {
  100.                     planeX     = (i - currentItem + 1) * 120;
  101.                     planeRotationY   = angle + 10 * (i - currentItem);
  102.                    
  103.                     TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  104.                 }
  105.                
  106.                 //Place & Animate Left Items
  107.                 if (i <currentItem)
  108.                 {
  109.                     planeX     = (currentItem - i + 1) * -120;
  110.                     planeRotationY   = -angle - 10 * (currentItem - i);
  111.                    
  112.                     TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
  113.                 }
  114.             }
  115.         }
  116.        
  117.         /*
  118.          * Everything below this point is just for creating the buttons and
  119.          * setting button events for controlling the coverflow.
  120.          */
  121.  
  122.         protected function createNavigation():void
  123.         {
  124.             //Create / Add Buttons
  125.             rightBtn = createButton();
  126.             leftBtn = createButton();
  127.                
  128.             addChild(leftBtn);
  129.             addChild(rightBtn);
  130.            
  131.             //Add button listeners
  132.             rightBtn.buttonMode = true;
  133.             leftBtn.buttonMode = true;
  134.             rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  135.             leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  136.                        
  137.             //Place buttons on stage
  138.             rightBtn.x    = stage.stageWidth - 20;
  139.             leftBtn.x       = 20;
  140.             rightBtn.y    =  stage.stageHeight / 2;
  141.             leftBtn.y       =  (stage.stageHeight / 2) + 20;
  142.             leftBtn.rotation    = 180;
  143.         }
  144.        
  145.         //Button actions
  146.         protected function buttonClick(evt:MouseEvent):void
  147.         {
  148.             switch (evt.target)
  149.             {
  150.                 case rightBtn:
  151.                 currentItem ++
  152.                 break;
  153.                
  154.                 case leftBtn:
  155.                 currentItem --;
  156.                 break;
  157.             }
  158.            
  159.             //Don't allow any number lower than 0 or past max so there
  160.             //is always a center item
  161.            
  162.             if (currentItem <0)
  163.             {
  164.                 currentItem = 0;
  165.             }
  166.             if (currentItem> (planes.length - 1))
  167.             {
  168.                 currentItem = planes.length - 1;
  169.             }
  170.            
  171.             //Call animation
  172.             animate();
  173.         }
  174.        
  175.         //Creates a simple arrow shape / returns the sprite
  176.         protected function createButton():Sprite
  177.         {
  178.             var btn:Sprite = new Sprite();
  179.            
  180.             btn.graphics.beginFill(0x333333);
  181.             btn.graphics.moveTo(0, 0);
  182.             btn.graphics.lineTo(0, 20);
  183.             btn.graphics.lineTo(10, 10);
  184.             btn.graphics.lineTo(0, 0);
  185.             btn.graphics.endFill();
  186.             btn.filters = [new GlowFilter(0xFFFFFF,1,10,10,3)]
  187.             return btn;
  188.         }
  189.     }
  190. }

That's it. This should provide a good base for you to build out your own unique coverflow.

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post

Papervision Explode Image / Rebuild

In early 2008 I wrote a blog article on how to explode an image and rebuild it again. Recently this effect has been used in some amazing ways. Site's like Audi have taken this concept much further with the rows of these tiny boxes swimming in formation.

Today I decided to re-create that simple effect using the latest papervision code and provide a much needed update.

Creating this effect is actually fairly simple. You take an image, use some code to break it into smaller bitmaps which then are used as the materials for your planes. Then you just place the planes in a grid to re-create your image.

Here is a sample of the code that get's our image blocks to be used for our materials:

Actionscript:
  1. //Creates a 30 x 18 bitmapData block
  2. var bitmap_data:BitmapData  = new BitmapData(cellWidth, cellHeight, true, 0x00FFFF);
  3.                
  4. //Create a new Matrix - A matrix is a rectangular array / table
  5. //of numbers with any number of rows / columns.
  6. var matrix:Matrix         = new Matrix();
  7.  
  8. //Get's our desired x / y location information where we will
  9. //pull a block of our image
  10. matrix.translate( -cellWidth * cellX, -cellHeight * cellY);
  11.  
  12. //Write the data to our bitmap data object with our source and
  13. //matrix / block info
  14. bitmap_data.draw(imageMC, matrix);

Once you've created your grid you just need to store the locations of all your x,y,z,rotation etc so that when you break apart the image you can easily piece it back together.

Actionscript:
  1. planeVO.origX         = pl.x;
  2. planeVO.origY            = pl.y;
  3. planeVO.origZ         = pl.z;
  4. planeVO.origRotationY      = pl.rotationY;
  5. planeVO.origRotationX      = pl.rotationX;
  6. planeVO.origRotationZ      = pl.rotationZ;
  7. planeVO.planeRef          = pl;

PlaneVO is nothing more than a simple value object. A value object gives us a nice strongly typed object to store the variables we want to access later.

PlaneVO.as

Actionscript:
  1. package
  2. {
  3.     import org.papervision3d.objects.primitives.Plane;
  4.     /**
  5.      * ...
  6.      * @author Charlie Schulze, Woven Interactive, LLC
  7.      */
  8.     public class PlaneVO
  9.     {
  10.         public var origX:Number;
  11.         public var origY:Number
  12.         public var origZ:Number
  13.         public var origRotationY:Number
  14.         public var origRotationX:Number
  15.         public var origRotationZ:Number
  16.         public var planeRef:Plane;
  17.     }
  18.    
  19. }

Now on to the full code. I have left comments throughout to explain what is happening. Try changing some of the math or swapping the image with your own. Once you mess with it for a little while you'll find it's easy to create some amazing effects.

Actionscript:
  1. package
  2. {
  3.     import br.com.stimuli.loading.BulkLoader;
  4.     import br.com.stimuli.loading.BulkProgressEvent;
  5.     import com.foomonger.utils.Later;
  6.     import flash.display.Bitmap;
  7.     import flash.display.BitmapData;
  8.     import flash.display.DisplayObject;
  9.     import flash.display.MovieClip;
  10.     import flash.geom.Matrix;
  11.     import gs.easing.Quint;
  12.     import gs.TweenMax;
  13.     import org.papervision3d.materials.MovieMaterial;
  14.     import org.papervision3d.objects.DisplayObject3D;
  15.     import org.papervision3d.objects.primitives.Plane;
  16.     import org.papervision3d.view.BasicView;
  17.    
  18.     /**
  19.      * ...
  20.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  21.      */
  22.    
  23.     public class Main extends BasicView
  24.     {
  25.         protected var bulkInstance:BulkLoader;
  26.         protected var imageMC:MovieClip;
  27.         protected var imageString:String
  28.         protected var planeVOs:Array = [];
  29.         protected var planesContainer:DisplayObject3D;
  30.        
  31.         public function Main():void
  32.         {
  33.             super();
  34.            
  35.             //Set the image we want to load
  36.             imageString  = "images/king.gif";
  37.            
  38.             //Load our image
  39.             loadImage();
  40.         }
  41.         protected function loadImage():void
  42.         {
  43.             //BulkLoader is complete overkill for this but thought it would be a
  44.             //nice extra for everyone to see in action. Extremely useful set of classes.
  45.            
  46.             //Create our unique bulkInstance / available anywhere in our app by
  47.             //that name "bulkImageLoader"
  48.             bulkInstance = new BulkLoader("bulkImageLoader");
  49.            
  50.             //Add our image
  51.             bulkInstance.add(imageString);
  52.            
  53.             //Add our listeners
  54.             bulkInstance.addEventListener(BulkProgressEvent.COMPLETE, onImageLoaded);
  55.            
  56.             //Start Loading
  57.             bulkInstance.start();
  58.         }
  59.         protected function onImageLoaded(evt:BulkProgressEvent):void
  60.         {
  61.             init();
  62.         }
  63.         protected function init():void
  64.         {
  65.             createChildren();
  66.             explode();
  67.             startRendering();
  68.         }
  69.        
  70.         protected function createChildren():void
  71.         {
  72.             //Create the clip we will be getting our bitmap data from
  73.             imageMC = new MovieClip();
  74.            
  75.             //add our bitmap
  76.             imageMC.addChild(bulkInstance.getBitmap(imageString));
  77.  
  78.             //Optional - Create a container to hold our planes
  79.             planesContainer = new DisplayObject3D();
  80.            
  81.             //Array to store our value objects
  82.             planeVOs = [];
  83.            
  84.             for (var i:int = 0; i <65; i++)
  85.             {
  86.                 /**
  87.                  * Here is how we get our loop / colunm / cellWidth / cellHeight numbers
  88.                  *
  89.                  * 5 columns * 13 rows = 65 (number of loops)
  90.                  * 5 columns divided by the width (150) of our image = 30 pixels
  91.                  * 13 rows  divided by the height (234) of our image = 18 pixels
  92.                  */
  93.  
  94.                 var columns:uint          = 5;
  95.                 var cellWidth:int       = 30;
  96.                 var cellHeight:int    = 18;
  97.                 var cellX:int         = (i % columns)
  98.                 var cellY:int         = Math.floor(i / columns);
  99.  
  100.                 //Creates a 30 x 18 bitmapData block
  101.                 var bitmap_data:BitmapData  = new BitmapData(cellWidth, cellHeight, true, 0x00FFFF);
  102.                
  103.                 //Create a new Matrix - A matrix is a rectangular array / table
  104.                 //of numbers with any number of rows / columns.
  105.                 var matrix:Matrix         = new Matrix();
  106.                
  107.                 //Get's our desired x / y location information where we will
  108.                 //pull a block of our image
  109.                 matrix.translate( -cellWidth * cellX, -cellHeight * cellY);
  110.                
  111.                 //Write the data to our bitmap data object with our source and
  112.                 //matrix / block info
  113.                 bitmap_data.draw(imageMC, matrix);
  114.                
  115.                 //Create a bitmap with our bitmapData and add it to a movieclip
  116.                 var bitmap:Bitmap       = new Bitmap(bitmap_data);
  117.                 var myMovie:MovieClip     = new MovieClip();
  118.                
  119.                 myMovie.addChild(bitmap);
  120.                
  121.                 //Use the movieclip with our bitmap inside as our movieMaterial
  122.                 //needs to be cast as a DisplayObject to work
  123.                 var movieMat:MovieMaterial  = new MovieMaterial(myMovie as DisplayObject, true);
  124.                 movieMat.smooth             = true;
  125.                
  126.                 //Create a plane with our moviemat the size of our cellWidth/Height
  127.                 var pl:Plane             = new Plane(movieMat, cellWidth, cellHeight, 0, 0);
  128.                
  129.                 //Create a value object to store our origianl infomation
  130.                 //for when we animate we can then rebuild easily
  131.                 var planeVO:PlaneVO         = new PlaneVO();
  132.  
  133.                 //We want to place the planes to re-create our original image
  134.                 pl.x                        = ((cellX * cellWidth) + cellWidth) -(imageMC.width / 2);
  135.                 pl.y                   = -((cellY * cellHeight) + cellHeight) +(imageMC.height / 2);
  136.                
  137.                 //Set the original properties of our value object
  138.                 planeVO.origX         = pl.x;
  139.                 planeVO.origY            = pl.y;
  140.                 planeVO.origZ         = pl.z;
  141.                 planeVO.origRotationY      = pl.rotationY;
  142.                 planeVO.origRotationX      = pl.rotationX;
  143.                 planeVO.origRotationZ      = pl.rotationZ;
  144.                 planeVO.planeRef          = pl;
  145.                
  146.                 //Add our planeVO to our array
  147.                 planeVOs.push(planeVO)
  148.                
  149.                 //Add planes to our container
  150.                 planesContainer.addChild(pl);            
  151.             }
  152.            
  153.             //Add our container to our scene
  154.             scene.addChild(planesContainer);
  155.            
  156.             camera.zoom = 100;
  157.            
  158.             //rotate our container for an skewed effect
  159.             planesContainer.rotationY = 30;
  160.             planesContainer.rotationX = 30;
  161.         }
  162.        
  163.         protected function explode():void
  164.         {
  165.             //Create a for loop of our plane objects set random numbers to explode our image
  166.            
  167.             for (var i:int = 0; i <planeVOs.length; i++)
  168.             {
  169.                 var planeVO:PlaneVO     = planeVOs[i];
  170.                 var plane:Plane         = planeVO.planeRef;
  171.                
  172.                 var ranNumber:Number = Math.round(Math.random() * 200 - 200);
  173.                 var delayAmount:Number = i * .05;
  174.                 var shortDelayAmount:Number = delayAmount * .6;
  175.                
  176.                 var randomX:Number = (Math.random() * 4000) - 6000;
  177.                 var randomY:Number = (Math.random() * 8000) - 1000;
  178.                 var randomZ:Number = (Math.random() * 1000) + 5000;
  179.  
  180.                 TweenMax.to(plane, 2, { x:planeVO.origX + randomX, delay:shortDelayAmount,
  181.                                         z:randomZ, y:150 + planeVO.origY + randomY,
  182.                                         rotationY:180,ease:Quint.easeInOut} );
  183.             }
  184.            
  185.             //In 3 seconds rebuild
  186.             Later.call(this, rebuild, 3000, true);
  187.         }
  188.        
  189.         protected function rebuild():void
  190.         {
  191.             //Rebuild our image with the locations we stored in our VO
  192.            
  193.             for (var i:int = 0; i <planeVOs.length; i++)
  194.             {
  195.                 var planeVO:PlaneVO     = planeVOs[i];
  196.                 var plane:Plane         = planeVO.planeRef;
  197.                 var delayAmount:Number  = i * .005;
  198.                 TweenMax.to(plane, 1.8, { x:planeVO.origX, delay:delayAmount,
  199.                                         z:planeVO.origZ, y:planeVO.origY,
  200.                                         rotationY:planeVO.origRotationY,ease:Quint.easeInOut} );
  201.             }
  202.            
  203.             //In 5 seconds explode the image again
  204.             Later.call(this, explode, 5000, true);
  205.         }
  206.     }
  207. }

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post

Advanced Interactivity

advancedinteractivity1

download-source

This is just another example of how to do some advanced interactivity in Papervision 3D. This tutorial is just a slightly updated version of the #10 : Advanced Interactivity tutorial from a while back.

Here is what has been updated:
1) Removed InteractiveScene3DEvent and replaced it with standard MouseEvents
2) Updated to use papervision's BasicView.as class

For a full description of what is going on please refer back to this link: #10 : Advanced Interactivity

Actionscript:
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.Event;
  5.     import flash.events.MouseEvent;
  6.     import flash.text.TextField;
  7.     import org.papervision3d.materials.ColorMaterial;
  8.     import org.papervision3d.materials.MovieMaterial;
  9.     import org.papervision3d.materials.utils.MaterialsList;
  10.     import org.papervision3d.objects.primitives.Cube;
  11.     import org.papervision3d.view.BasicView;
  12.    
  13.     /**
  14.      * ...
  15.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  16.      */
  17.    
  18.     public class Main extends BasicView
  19.     {
  20.         protected var cube:Cube;
  21.         protected var interactiveMats:Array;
  22.         protected var materialsList:MaterialsList;
  23.         protected var targetrotationX:Number;
  24.         protected var targetrotationY:Number;
  25.         protected var targetrotationZ:Number;
  26.         protected var tweening:Boolean;
  27.        
  28.         public function Main():void
  29.         {
  30.             super();
  31.             init();
  32.         }
  33.         protected function init():void
  34.         {
  35.             createChildren();
  36.             startRendering();
  37.         }
  38.         protected function createChildren():void
  39.         {
  40.             //Set the viewport to interactive
  41.             viewport.interactive = true;
  42.            
  43.             //Create Materials:
  44.             materialsList       = new MaterialsList();
  45.             interactiveMats         = ["front", "back", "left", "right", "bottom", "top"];
  46.             var colorsArray:Array   = [0x76b6f8, 0x4291e1, 0x1f73c8, 0xe77111, 0xe8914c, 0xfad2b2];
  47.            
  48.             for (var i:int = 0; i <interactiveMats.length; i++)
  49.             {
  50.                 //Create a color box so we can use our MouseEvents
  51.                 var colorBox:Sprite = new Sprite();
  52.                 colorBox.graphics.beginFill(colorsArray[i]);
  53.                 colorBox.graphics.drawRect(0, 0, 100, 100);
  54.                 colorBox.graphics.endFill();
  55.                 colorBox.name = interactiveMats[i];
  56.                
  57.                 //Add a textField for reference
  58.                 var textField:TextField = new TextField()
  59.                 colorBox.addChild(textField)
  60.                 textField.text = interactiveMats[i];
  61.                
  62.                 //Add a MouseEvent to the Sprite
  63.                 colorBox.mouseChildren = false;
  64.                 colorBox.addEventListener(MouseEvent.CLICK, onMovieMatClicked);
  65.                
  66.                 //Create the MovieMat
  67.                 var movieMat:MovieMaterial   = new MovieMaterial(colorBox, true, true);
  68.                 movieMat.interactive          = true;
  69.                 movieMat.smooth                 = true;
  70.                 materialsList.addMaterial(movieMat, interactiveMats[i]);
  71.             }
  72.            
  73.             //Create Cube
  74.             cube    = new Cube(materialsList, 100, 100, 100);
  75.            
  76.             //Add cube to the scene
  77.             scene.addChild(cube);
  78.         }
  79.        
  80.         protected function onMovieMatClicked(evt:MouseEvent):void
  81.         {
  82.             if (tweening)
  83.             {
  84.                 // Let it rotate again
  85.                 tweening = false;
  86.             }
  87.             else
  88.             {
  89.                 switch(evt.target.name) {
  90.                     case "front":
  91.                         targetrotationX = 0;
  92.                         targetrotationY = 180;
  93.                         targetrotationZ = 0;
  94.                         tweening = true;
  95.                     break;
  96.                     case "back":
  97.                         targetrotationX = 0;
  98.                         targetrotationY = 0;
  99.                         targetrotationZ = 0;
  100.                         tweening = true;
  101.                     break;
  102.                     case "left":
  103.                         targetrotationX = 0;
  104.                         targetrotationY = -90;
  105.                         targetrotationZ = 0;
  106.                         tweening = true;
  107.                     break;
  108.                     case "right":
  109.                         targetrotationX = 0;
  110.                         targetrotationY = 90;
  111.                         targetrotationZ = 0;
  112.                         tweening = true;
  113.                     break;
  114.                     case "top":
  115.                         targetrotationX = -90;
  116.                         targetrotationY = 0;
  117.                         targetrotationZ = 0;
  118.                         tweening = true;
  119.                     break;
  120.                     case "bottom":
  121.                         targetrotationX = 90;
  122.                         targetrotationY = 0;
  123.                         targetrotationZ = 180;
  124.                         tweening = true;
  125.                     break;
  126.                 }
  127.             }
  128.         }
  129.        
  130.         override protected function onRenderTick(event:Event = null):void
  131.         {
  132.             super.onRenderTick(event);
  133.            
  134.             if (tweening) {
  135.                 // If a face has been clicked
  136.                 if (camera.zoom <230) {
  137.                     // If the camera isn't zoomed enough then zoom in a bit more:
  138.                     camera.zoom += Math.sqrt(230-camera.zoom)/5;
  139.                 }
  140.                 // Test each rotation and rotate it towards the target rotation:
  141.                 // X axis:
  142.                 if (cube.rotationX <targetrotationX)
  143.                 {
  144.                     cube.rotationX += Math.sqrt(targetrotationX-cube.rotationX);
  145.                     cube.rotationX = Math.round(cube.rotationX);
  146.                 }
  147.                 else if (cube.rotationX> targetrotationX)
  148.                 {
  149.                     cube.rotationX -= Math.sqrt(cube.rotationX-targetrotationX);
  150.                     cube.rotationX = Math.round(cube.rotationX);
  151.                 }
  152.                
  153.                 // Y axis:
  154.                 if (cube.rotationY <targetrotationY)
  155.                 {
  156.                     cube.rotationY += Math.sqrt(targetrotationY-cube.rotationY);
  157.                     cube.rotationY = Math.round(cube.rotationY);
  158.                 }
  159.                 else if (cube.rotationY> targetrotationY)
  160.                 {
  161.                     cube.rotationY -= Math.sqrt(cube.rotationY-targetrotationY);
  162.                     cube.rotationY = Math.round(cube.rotationY);
  163.                 }
  164.                
  165.                 // Z axis:
  166.                 if (cube.rotationZ <targetrotationZ)
  167.                 {
  168.                     cube.rotationZ += Math.sqrt(targetrotationZ-cube.rotationZ);
  169.                     cube.rotationZ = Math.round(cube.rotationZ);
  170.                 }
  171.                 else if (cube.rotationZ> targetrotationZ)
  172.                 {
  173.                     cube.rotationZ -= Math.sqrt(cube.rotationZ-targetrotationZ);
  174.                     cube.rotationZ = Math.round(cube.rotationZ);
  175.                 }
  176.             }
  177.             else
  178.             {
  179.                 // If the camera is zoomed in, it shouldn't be now
  180.                 if (camera.zoom> 200)
  181.                 {
  182.                     // So zoom out a bit.
  183.                     camera.zoom -= Math.sqrt(camera.zoom-2)/5;
  184.                 }
  185.                 // Rotate the cube a bit:
  186.                 cube.rotationX += 2;
  187.                 cube.rotationY += 2;
  188.                 // Make sure that we dont "wind up" the rotation
  189.                 if (cube.rotationX>= 360) cube.rotationX = 0;
  190.                 if (cube.rotationY>= 360) cube.rotationY = 0;
  191.             }
  192.         }      
  193.     }
  194. }

download-source

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post

Advanced Interactivity (Without InteractiveScene3DEvent)

advancedinteractivity3

download-source

There are multiple ways of accomplishing any task. With papervision that statement holds true. When you want to interact with 3D objects one way we have found works very well is to apply the MouseEvent's to the textureFile and bypass the InteractiveScene3DEvent all together.

Here are a few things to remember when working with anything interactive in Papervision

1) Always set your ViewPort to interactive
2) Always set your Material to interactive
3) Set your Material animation to "true" if you want to see the material update
4) Be sure that your render is running so you can see your material update

Here is some sample code that shows the basic building blocks of an animated / interactive papervision object:

Actionscript:
  1. //Viewport set to interactive
  2. viewport.interactive                      = true;
  3.  
  4. //Create your symbol - can be a class or MovieClip exported in your library
  5. var textureMC:TextureSymbol     = new TextureSymbol();
  6. textureMC.id                = i;
  7. textureMC.clickButton.addEventListener(MouseEvent.CLICK, onMovieMatClicked);
  8.  
  9. //Create your movie Material - animated / interactive set to true
  10. var movieMat:MovieMaterial   = new MovieMaterial(textureMC, true, true);
  11. movieMat.doubleSided            = true;
  12. movieMat.interactive          = true;
  13. movieMat.smooth             = true;

This approach is nice because you can deal with native Flash events.

Here is the full class:

Actionscript:
  1. package
  2. {
  3.     import flash.events.Event;
  4.     import flash.events.MouseEvent;
  5.     import gs.easing.Quint;
  6.     import gs.TweenLite;
  7.     import org.papervision3d.materials.MovieMaterial;
  8.     import org.papervision3d.materials.utils.MaterialsList;
  9.     import org.papervision3d.objects.primitives.Cube;
  10.  
  11.     import org.papervision3d.view.BasicView;
  12.     import TextureSymbol;
  13.    
  14.     /**
  15.      * ...
  16.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  17.      */
  18.    
  19.     public class Main extends BasicView
  20.     {
  21.         protected var cube:Cube;
  22.         protected var interactiveMats:Array;
  23.         protected var materialsList:MaterialsList;
  24.        
  25.         public function Main():void
  26.         {
  27.             super();
  28.             init();
  29.         }
  30.         protected function init():void
  31.         {
  32.             createChildren();
  33.             commitProperties();
  34.             startRendering();
  35.         }
  36.         protected function createChildren():void
  37.         {
  38.             //Set the viewport to interactive
  39.             viewport.interactive = true;
  40.            
  41.             //Create Materials:
  42.             materialsList = new MaterialsList();
  43.             interactiveMats = ["front", "back", "top", "bottom", "left", "right"];
  44.            
  45.             for (var i:int = 0; i <interactiveMats.length; i++)
  46.             {
  47.                 //Create the texture symbol from the library
  48.                 var textureMC:TextureSymbol     = new TextureSymbol();
  49.                 textureMC.id                    = i;
  50.                 textureMC.clickButton.addEventListener(MouseEvent.CLICK, onMovieMatClicked);
  51.                
  52.                 //Create the MovieMat
  53.                 var movieMat:MovieMaterial   = new MovieMaterial(textureMC, true, true);
  54.                 movieMat.doubleSided            = true;
  55.                 movieMat.interactive          = true;
  56.                 movieMat.smooth                 = true;
  57.                
  58.                 materialsList.addMaterial(movieMat, interactiveMats[i]);
  59.             }
  60.            
  61.             //Create Cube
  62.             cube    = new Cube(materialsList, 100, 100, 100);
  63.            
  64.             //Add cube to the scene
  65.             scene.addChild(cube);
  66.         }
  67.        
  68.         protected function onMovieMatClicked(evt:MouseEvent):void
  69.         {
  70.             var randomX:Number = Math.random() * 600 - 300;
  71.             var randomY:Number = Math.random() * 200 - 100;
  72.             TweenLite.to(cube, 1, { x:randomX, y:randomY, ease:Quint.easeInOut});
  73.         }
  74.        
  75.         protected function commitProperties():void
  76.         {
  77.             //Set the properties of our camera
  78.             camera.zoom = 200;
  79.             camera.y    = 1000;
  80.         }
  81.         override protected function onRenderTick(event:Event = null):void
  82.         {
  83.             super.onRenderTick(event);
  84.             cube.yaw(2);
  85.         }
  86.     }
  87. }

download-source

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post

Animation Using TweenLite

In this tutorial we're going to use TweenLite to move a cube around. This will teach you basics of animation, and how to use TweenLite.

download-source

animating-using-tweenlite

In this example our solid red cube is trying to stay inside our green wireframe cube. Every time the red cube gets itself positioned completely inside the green cube, the green cube moves.

TweenLite is the package which is smoothly moving the red cube around. The TweenLite package is also firing the event to move the green cube when the tween is complete.

1: To start off, you'll need TweenLite. You can download it here if you don't already have it (also included in the source download "gs" folder): http://blog.greensock.com/tweenlite/

2: Import tweener - Add this line to your imports:

Actionscript:
  1. import gs.TweenLite;

3: Add a Tween. You can add tweens to any parameter of any object. The TweenLite package will gradually change any parameter in your code to a new value over time, so only numeric values will work nicely.

To add a tween, we use the code:

Actionscript:
  1. //TweenLite.to(objectToAnimate, time, { property:newValue, property:newValue, ease:Quint.easeInOut, onComplete:functionToCall} );
  2.  
  3. //Your code will end up looking something like this
  4. TweenLite.to(cube, 2, { x:xp, z:yp, ease:Quint.easeInOut, onComplete:randomize } );

The line above will add a tween. This tween will change the values "x" and "y" on the object "cube" to 1000 and 500 respectively. It will smoothly change the values over a period of 2 seconds and once the tween is complete and the cube.x is 1000 and cube.y is 500, it will trigger the "randomize" function.

Experiment with more ways to tween your objects. You can apply tweens to anything, including cameras, lights, rotations, sizes and camera zooms. Any numerical value you can think of.

Actionscript:
  1. package
  2. {
  3.     import gs.easing.Quint;
  4.     import gs.TweenLite;
  5.     import org.papervision3d.lights.PointLight3D;
  6.     import org.papervision3d.materials.ColorMaterial;
  7.     import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  8.     import org.papervision3d.materials.utils.MaterialsList;
  9.     import org.papervision3d.materials.WireframeMaterial;
  10.     import org.papervision3d.objects.primitives.Cube;
  11.     import org.papervision3d.objects.primitives.Plane;
  12.     import org.papervision3d.view.BasicView;
  13.    
  14.     /**
  15.      * ...
  16.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  17.      */
  18.    
  19.     public class Main extends BasicView
  20.     {
  21.         protected var cube:Cube;
  22.         protected var cube2:Cube;
  23.         protected var mat:FlatShadeMaterial;
  24.         protected var mat2:WireframeMaterial;
  25.         protected var plane:Plane;
  26.        
  27.         public function Main():void
  28.         {
  29.             super();
  30.             init();
  31.         }
  32.         protected function init():void
  33.         {
  34.             createChildren();
  35.             commitProperties();
  36.             randomize();
  37.             startRendering();
  38.         }
  39.         protected function createChildren():void
  40.         {
  41.             //Create Materials:
  42.             mat     = new FlatShadeMaterial(new PointLight3D(), 0xFFFFFF, 0xFF0000);
  43.             mat2    = new WireframeMaterial(0x00FF00);
  44.            
  45.             //Create 3D Objects
  46.             plane   = new Plane(null, 2000, 2000, 10, 10);
  47.             cube    = new Cube(new MaterialsList( { all: mat } ), 100, 100, 100);
  48.             cube2   = new Cube(new MaterialsList( { all: mat2 } ), 100, 100, 100);
  49.            
  50.             //Add objects to the scene
  51.             scene.addChild(plane);
  52.             scene.addChild(cube);
  53.             scene.addChild(cube2);
  54.         }
  55.         protected function commitProperties():void
  56.         {
  57.             //Set properties of our plane
  58.             plane.material.lineColor = 0x777777;
  59.             plane.material.doubleSided = true;
  60.             plane.pitch(90);
  61.             plane.y     = -50;
  62.            
  63.             //Set the properties of our camera
  64.             camera.x    = 0;
  65.             camera.z    = 1000;
  66.             camera.y    = 1000;
  67.         }
  68.        
  69.         public function randomize():void
  70.         {
  71.             var xp:Number   = (Math.random() * 2000) - 1000;
  72.             var yp:Number   = (Math.random() * 2000) - 1000;
  73.             cube2.x         = xp;
  74.             cube2.z         = yp;
  75.            
  76.             //When complete it calls this method again
  77.             TweenLite.to(cube, 2, { x:xp, z:yp, ease:Quint.easeInOut, onComplete:randomize } );
  78.         }
  79.     }
  80. }

download-source

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post


Follow WovenCharlie on Twitter

Flash and the City banner
2010 Flash And The City Speaker

RSS Feed