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

Archive for the 'Papervision' Category

Papervision Isometric View & Pathfinding with as3isolib and A* (A Star)

View Example

This week's example / tutorial is how to mix Papervision with as3isolib and A* (pronounced A Star) for a nice 3D isometric pathfinding experience. The version of A* that I am using comes straight out of Keith Peters book AdvancedEd ActionScript 3.0 Animation. Anyone looking to cover advanced animation topics in Flash should buy a copy of this book. It is excellent.

This tutorial will not cover how to create the A* classes but rather show you how to blend 3 things together; Papervision, as3isolib, and A* (the Keith Peters version). If you're just getting started using as3IsoLib take a look at these great tutorials and download the code: http://code.google.com/p/as3isolib/w/list

We will cover a few of the things that you need to successfully merge the pathfinding and 3D experience.

First item is our camera setting. We are setting ortho to true because this actually gives us a true isometric camera feel.

Actionscript:
  1. camera.ortho = true;

Inside of our makeGrid function we are setting up the groundwork for our pathfinding and isometric world. This grid has no information about the cellsize, just which parts of it are walkable and not walkable.

Actionscript:
  1. protected function makeGrid():void
  2. {
  3.     pathGrid = new Grid(10, 10);
  4.     for(var i:int = 0; i <20; i++)
  5.     {
  6.         pathGrid.setWalkable(Math.floor(Math.random() * 8) + 2,
  7.                           Math.floor(Math.random() * 8)+ 2,
  8.                           false);
  9.     }
  10.     drawGrid();
  11. }

Next we move on to drawGrid() which begins to connect the pathfinding and as3isolib

One of the great thing about as3isolib which is similar to papervision is that it has native objects that you can skin, such as boxes and polygons.

Here inside of drawGrid we run through the columns and rows that we setup in our makeGrid function. From the information in these loops we can get back the node information of the grid and check if an item is walkable or not walkable. If it is walkable we create a standard size box with a height of 0, if it is not walkable we create that same standard box but with a height of 40 so we can start to define our available paths. If the box is walkable we also want to set a mouseEvent so that we can select it. Finally we add these items to our isoScene.

Actionscript:
  1. for(var i:int = 0; i <pathGrid.numCols; i++)
  2. {
  3.     for(var j:int = 0; j <pathGrid.numRows; j++)
  4.     {
  5.         var node:Node = pathGrid.getNode(i, j);
  6.         var box:IsoBox = new IsoBox();
  7.  
  8.         if (node.walkable)
  9.         {
  10.             box.setSize(cellSize, cellSize, 0);
  11.             box.addEventListener(MouseEvent.CLICK, onGridItemClick);
  12.         }
  13.         else
  14.         {
  15.             box.setSize(cellSize, cellSize, 40);
  16.         }
  17.        
  18.         box.moveTo(i * cellSize, j * cellSize, 0);
  19.         isoScene.addChild(box);
  20.     }
  21. }

Another item within the drawGrid function is our playerHelper. We are only using this playerHelper so that we can get it's coordinates to follow along in papervision. We set him to the same size as our box items.

Actionscript:
  1. playerHelper.setSize(cellSize, cellSize, 10);

The next important step is setting up a way to have our viewport inside of our isoScene. We first create a nice wrapper for our viewport which is a native IsoSprite object. We then associate our viewport as one of the sprites inside of our isoSprite.

Actionscript:
  1. isoSprite = new IsoSprite();
  2. isoSprite.sprites = [viewport];
  3. isoScene.addChild(isoSprite);

Notice that we add our sprites kind of like we add filters for a movieclip. We are passing it an array.

Actionscript:
  1. //isoSprite.sprites = [viewport,moreStuff] - pass in an array of objects

Now lets see what happens when a grid item is clicked. First we gather the information about where we want to go. We gather that by getting the item that was clicked and getting its x & y positions divided by the cellSize. Then we give pathGrid.setEndNode those coordinates. Next we gather the information about where our playerHelper currently is divided by the cellSize and pass that information to pathGrid.setStartNode.

Actionscript:
  1. protected function onGridItemClick(evt:ProxyEvent):void
  2.         {
  3.             var box:IsoBox = evt.target as IsoBox;
  4.            
  5.             //Get and set End Nodes (where are we going)
  6.             var xpos:int = (box.x)/cellSize
  7.             var ypos:int = Math.floor(box.y / cellSize)
  8.             pathGrid.setEndNode(xpos,ypos );
  9.  
  10.             //Get and set Start Node (where are we now)
  11.             xpos = Math.floor(playerHelper.x / cellSize);
  12.             ypos = Math.floor(playerHelper.y / cellSize);
  13.             pathGrid.setStartNode(xpos, ypos);
  14.  
  15.             //Find our path
  16.             findPath();
  17.         }

Finally we call findPath(). This is the fun part. First we create a new instance of AStar and gather the path information that we gathered when we ran the onGridItemClick function.

We can now run through that loop and get each x and y portion of that loop. We simply add a tween with a delay that is the same time as our speed. This will allow you to see each move and when it is complete it will start it's next move.

Actionscript:
  1. protected function findPath():void
  2. {
  3.     var astar:AStar = new AStar();
  4.     var speed:Number = .3;
  5.     if(astar.findPath(pathGrid))
  6.     {
  7.         path = astar.path;
  8.     }
  9.    
  10.     for (var i:int = 0; i <path.length; i++)
  11.     {
  12.         var targetX:Number = path[i].x * cellSize;
  13.         var targetY:Number = path[i].y * cellSize;
  14.        
  15.         Tweener.addTween(playerHelper, { x:targetX, y:targetY, delay:speed * i , time:speed, transition:"linear" } );
  16.     }
  17. }

We now just need to look at how to sort the papervision with the as3isolib objects

Inside of our onRenderTick function which is an override from BasicView we use this to render our isoScene which is part of as3isolib and change the x,y coordinates of our sphere. We are basically following around the screenX and screenY of our playerHelper. The next and very important part of this is the depth sorting. We are pulling the depth at all times from the playerHelper object and assigning our isoSprite (which has our viewport in it) to that depth. Now we can watch as our 3D objects find their pretty little paths and sort without issue.

Actionscript:
  1. override protected function onRenderTick(event:Event = null):void
  2. {
  3.     super.onRenderTick(event);
  4.     isoScene.render();
  5.     sphere.x = playerHelper.screenX;
  6.     sphere.y = -playerHelper.screenY - 15;
  7.     isoScene.setChildIndex(isoSprite, isoScene.getChildIndex(playerHelper));
  8. }

Here is the full code:

Actionscript:
  1. package
  2. {
  3.     import as3isolib.display.IsoSprite;
  4.     import as3isolib.display.IsoView;
  5.     import as3isolib.display.primitive.IsoBox;
  6.     import as3isolib.display.primitive.IsoPrimitive;
  7.     import as3isolib.display.scene.IsoGrid;
  8.     import as3isolib.display.scene.IsoScene;
  9.     import bit101.AStar;
  10.     import bit101.Grid;
  11.     import bit101.Node;
  12.     import caurina.transitions.Tweener;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageScaleMode;
  15.     import flash.events.Event;
  16.  
  17.     import eDpLib.events.ProxyEvent;
  18.    
  19.     import flash.display.Sprite;
  20.     import flash.events.MouseEvent;
  21.    
  22.     import org.papervision3d.materials.WireframeMaterial;
  23.     import org.papervision3d.objects.primitives.Sphere;
  24.     import org.papervision3d.view.BasicView;
  25.  
  26.     public class Main extends BasicView
  27.     {
  28.         protected var cellSize:int = 50;
  29.         protected var pathGrid:Grid;
  30.         protected var playerHelper:IsoPrimitive;
  31.         protected var path:Array;
  32.         protected var isoSprite:IsoSprite;
  33.         protected var isoView:IsoView;
  34.         protected var isoScene:IsoScene;
  35.         protected var sphere:Sphere;
  36.        
  37.         public function Main()
  38.         {
  39.             super(800, 600, false);
  40.             stage.align = StageAlign.TOP_LEFT;
  41.             stage.scaleMode = StageScaleMode.NO_SCALE;
  42.            
  43.             create3D();
  44.             makeGrid();
  45.             startRendering();
  46.         }
  47.  
  48.         protected function create3D():void
  49.         {
  50.             sphere = new Sphere(new WireframeMaterial(),20);
  51.             scene.addChild(sphere);
  52.             camera.ortho = true;
  53.         }
  54.  
  55.         protected function makeGrid():void
  56.         {
  57.             pathGrid = new Grid(10, 10);
  58.             for(var i:int = 0; i <20; i++)
  59.             {
  60.                 pathGrid.setWalkable(Math.floor(Math.random() * 8) + 2,
  61.                                   Math.floor(Math.random() * 8)+ 2,
  62.                                   false);
  63.             }
  64.             drawGrid();
  65.         }
  66.        
  67.         protected function drawGrid():void
  68.         {
  69.             isoScene       = new IsoScene();
  70.             playerHelper    = new IsoPrimitive();
  71.             isoSprite     = new IsoSprite();
  72.             isoView         = new IsoView();
  73.  
  74.             for(var i:int = 0; i <pathGrid.numCols; i++)
  75.             {
  76.                 for(var j:int = 0; j <pathGrid.numRows; j++)
  77.                 {
  78.                     var node:Node = pathGrid.getNode(i, j);
  79.                     var box:IsoBox = new IsoBox();
  80.  
  81.                     if (node.walkable)
  82.                     {
  83.                         box.setSize(cellSize, cellSize, 0);
  84.                         box.addEventListener(MouseEvent.CLICK, onGridItemClick);
  85.                     }
  86.                     else
  87.                     {
  88.                         box.setSize(cellSize, cellSize, 40);
  89.                     }
  90.                    
  91.                     box.moveTo(i * cellSize, j * cellSize, 0);
  92.                     isoScene.addChild(box);
  93.                 }
  94.             }
  95.  
  96.             //Set properties for player helper
  97.             playerHelper.setSize(cellSize, cellSize, 10);
  98.            
  99.             //Set properties for isoView
  100.             isoView.setSize(stage.stageWidth, stage.stageHeight);
  101.            
  102.             //Set proper position for viewport
  103.             viewport.x = -stage.stageWidth / 2;
  104.             viewport.y = -stage.stageHeight / 2;
  105.  
  106.             //Add viewport to the isoSprite
  107.             isoSprite.sprites = [viewport];
  108.            
  109.             //Add the isoSprite and playerHelper to the isoScene
  110.             isoScene.addChild(isoSprite);
  111.             isoScene.addChild(playerHelper);
  112.            
  113.             //Add the isoScene to the isoView
  114.             isoView.addScene(isoScene);
  115.            
  116.             //Add the isoView to the stage
  117.             addChild(isoView);
  118.         }
  119.  
  120.         protected function onGridItemClick(evt:ProxyEvent):void
  121.         {
  122.             var box:IsoBox = evt.target as IsoBox;
  123.            
  124.             //Get and set End Nodes (where are we going)
  125.             var xpos:int = (box.x)/cellSize
  126.             var ypos:int = Math.floor(box.y / cellSize)
  127.             pathGrid.setEndNode(xpos,ypos );
  128.  
  129.             //Get and set Start Node (where are we now)
  130.             xpos = Math.floor(playerHelper.x / cellSize);
  131.             ypos = Math.floor(playerHelper.y / cellSize);
  132.             pathGrid.setStartNode(xpos, ypos);
  133.  
  134.             //Find our path
  135.             findPath();
  136.         }
  137.  
  138.         protected function findPath():void
  139.         {
  140.             var astar:AStar = new AStar();
  141.             var speed:Number = .3;
  142.             if(astar.findPath(pathGrid))
  143.             {
  144.                 path = astar.path;
  145.             }
  146.            
  147.             for (var i:int = 0; i <path.length; i++)
  148.             {
  149.                 var targetX:Number = path[i].x * cellSize;
  150.                 var targetY:Number = path[i].y * cellSize;
  151.                
  152.                 Tweener.addTween(playerHelper, { x:targetX, y:targetY, delay:speed * i , time:speed, transition:"linear" } );
  153.             }
  154.         }
  155.        
  156.         override protected function onRenderTick(event:Event = null):void
  157.         {
  158.             super.onRenderTick(event);
  159.            
  160.             //Render the isoScene
  161.             isoScene.render();
  162.            
  163.             //Place our 3D object at the correct location (following our playerHelper)
  164.             sphere.x = playerHelper.screenX;
  165.             sphere.y = -playerHelper.screenY - 15;
  166.            
  167.             /*
  168.            
  169.             Set the depth of our isoSprite which holds our viewport to the proper depth.
  170.            
  171.             NOTE: as3isolib objects - the depth sorting is done automatically,
  172.             we just need to tap into that
  173.            
  174.             */
  175.            
  176.             isoScene.setChildIndex(isoSprite, isoScene.getChildIndex(playerHelper));
  177.         }   
  178.     }
  179. }

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

A Simple Papervision Carousel

Papervision 3D Carousel

download-source

This week I set out to create a Papervision Carousel in it's simplest form. At the heart of this carousel is a simple "for" loop / math which places the items in a circle in 3D space

Actionscript:
  1. for (var i:int = 0; i <planes.length; i++)
  2. {
  3.     var angle:Number    = Math.PI * 2 / numItems * i;
  4.     var plane:Plane     = planes[i];
  5.     plane.x             = Math.cos(angle) * radius;
  6.     plane.z             = Math.sin(angle) * radius;
  7.     plane.rotationY     = -360 / numItems * i - 90;
  8. }

Then to rotate our carousel we apply some similar math

Actionscript:
  1. var rotateTo:Number = (-360 / numItems) * currentItem + 90;
  2. TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );

This code allows us to just increment currentItem and rotate our carousel. Another easy add-on would be to setup a navigation along the bottom where you could control and change the currentItem to a specific number to rotate right to that section of the carousel.

It's also very easy to customize the number of items and radius of the carousel by adjusting these numbers.

Actionscript:
  1. protected var numItems:Number = 20;
  2. protected var radius:Number = 500;

Here is the full code.

Actionscript:
  1. package
  2. {
  3.     import flash.display.DisplayObject;
  4.     import flash.display.MovieClip;
  5.     import flash.display.Sprite;
  6.     import flash.events.Event;
  7.     import flash.events.MouseEvent;
  8.     import gs.easing.Quint;
  9.     import gs.TweenLite;
  10.     import org.papervision3d.materials.BitmapFileMaterial;
  11.     import org.papervision3d.objects.DisplayObject3D;
  12.     import org.papervision3d.objects.primitives.Plane;
  13.     import org.papervision3d.view.BasicView;
  14.    
  15.     /**
  16.      * ...
  17.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  18.      */
  19.    
  20.     public class Main extends BasicView
  21.     {
  22.         protected var planes:Array = [];
  23.         protected var numItems:Number = 20;
  24.         protected var radius:Number = 500;
  25.         protected var currentItem:Number = 0;
  26.        
  27.         protected var mat:BitmapFileMaterial;
  28.         protected var planesHolder:DisplayObject3D;
  29.         protected var rightBtn:Sprite;
  30.         protected var leftBtn:Sprite;
  31.        
  32.         public function Main():void
  33.         {
  34.             super();
  35.             init();
  36.         }
  37.         protected function init():void
  38.         {
  39.             createChildren();
  40.             createButtons();
  41.             commitProperties();
  42.             startRendering();
  43.         }
  44.         protected function createChildren():void
  45.         {
  46.            
  47.             planesHolder = new DisplayObject3D();
  48.            
  49.             //Create Material
  50.             mat             = new BitmapFileMaterial("images/queen.gif");
  51.             mat.smooth   = true;
  52.             mat.doubleSided = true;
  53.            
  54.             for (var i:int = 0; i <numItems; i++)
  55.             {
  56.                 var plane:Plane = new Plane(mat, 150, 234);
  57.                 planes.push(plane);
  58.                
  59.                 //Add plane to the scene
  60.                 planesHolder.addChild(plane);
  61.             }
  62.             scene.addChild(planesHolder);
  63.         }
  64.        
  65.         protected function commitProperties():void
  66.         {
  67.             //Set properties of our planes
  68.             for (var i:int = 0; i <planes.length; i++)
  69.             {
  70.                 var angle:Number    = Math.PI * 2 / numItems * i;
  71.                 var plane:Plane     = planes[i];
  72.                 plane.x             = Math.cos(angle) * radius;
  73.                 plane.z             = Math.sin(angle) * radius;
  74.                 plane.rotationY     = -360 / numItems * i - 90;
  75.             }
  76.            
  77.             //Adjust camera
  78.             camera.y = 200;
  79.            
  80.             //Rotate once
  81.             rotate();
  82.         }
  83.  
  84.         //Rotates the carousel
  85.         protected function rotate():void
  86.         {
  87.             var rotateTo:Number = (-360 / numItems) * currentItem + 90;
  88.             TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );
  89.         }
  90.        
  91.         /*
  92.          * Everything below this point is just for creating the buttons and
  93.          * setting button events for controlling the carousel.
  94.          */
  95.  
  96.         protected function createButtons():void
  97.         {
  98.             //Create Buttons
  99.             rightBtn = createButton();
  100.             leftBtn = createButton();
  101.                
  102.             addChild(leftBtn);
  103.             addChild(rightBtn);
  104.            
  105.             //Add button listeners
  106.             rightBtn.buttonMode = true;
  107.             leftBtn.buttonMode = true;
  108.             rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  109.             leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  110.                        
  111.             //Place buttons on stage
  112.             rightBtn.x    = stage.stageWidth - 120;
  113.             leftBtn.x       = 100;
  114.             rightBtn.y    =  stage.stageHeight / 2;
  115.             leftBtn.y       =  (stage.stageHeight / 2) + 20;
  116.             leftBtn.rotation    = 180;
  117.         }
  118.        
  119.         //Button actions
  120.         protected function buttonClick(evt:MouseEvent):void
  121.         {
  122.             switch (evt.target)
  123.             {
  124.                 case rightBtn:
  125.                 currentItem --;
  126.                 break;
  127.                
  128.                 case leftBtn:
  129.                 currentItem ++;
  130.                 break;
  131.             }
  132.             rotate();
  133.         }
  134.        
  135.         //Creates a simple arrow shape / returns the sprite
  136.         protected function createButton():Sprite
  137.         {
  138.             var btn:Sprite = new Sprite();
  139.            
  140.             btn.graphics.beginFill(0x333333);
  141.             btn.graphics.moveTo(0, 0);
  142.             btn.graphics.lineTo(0, 20);
  143.             btn.graphics.lineTo(10, 10);
  144.             btn.graphics.lineTo(0, 0);
  145.             btn.graphics.endFill();
  146.             return btn;
  147.         }
  148.     }
  149. }

Feel free to post links to ways you expand upon this file.

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

Basic Texturing (v2)

basic-texturing
download-source

Even if you had a chance to look at Getting started using BasicView.as this tutorial provides another example of basic texturing in Papervision.

In Papervision for the most part you have objects (planes, cubes, cones, 3D Models, etc) and then you have the textures or materials that you add to these objects. Think of it as getting a brand new iPhone and then buying a case or skin for that iPhone. We are essentially doing the same thing in principle - we have our object a cone (iPhone) and a material a bitmapMaterial (iPhone skin).

Actionscript:
  1. package 
  2. {
  3.     import flash.events.Event;
  4.     import org.papervision3d.view.BasicView;
  5.     import org.papervision3d.objects.primitives.Cone;
  6.     import org.papervision3d.materials.BitmapFileMaterial;
  7.    
  8.     public class Main extends BasicView
  9.     {
  10.         protected var cone:Cone
  11.         protected var bitmapMaterial:BitmapFileMaterial;
  12.        
  13.         public function Main()
  14.         {
  15.             super();
  16.             createChildren();
  17.             startRendering();
  18.         }
  19.         public function createChildren():void
  20.         {
  21.             //Create a new 3D object
  22.             bitmapMaterial = new BitmapFileMaterial("images/ourtex.jpg")
  23.             cone = new Cone(bitmapMaterial, 20, 200);
  24.            
  25.             //Set some properties
  26.             cone.scale = 4;
  27.             cone.pitch( -10);
  28.            
  29.             //Add to scene
  30.             scene.addChild(cone);
  31.         }
  32.        
  33.         override protected function onRenderTick(event:Event = null):void
  34.         {
  35.             super.onRenderTick(event);
  36.  
  37.             //Rotate
  38.             cone.yaw(3);
  39.         }
  40.     }
  41. }

As you can see from the code above we have a cone and a bitmap texture.

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

Getting started using BasicView.as

basicview-image

download-source

In a previous tutorial (Creating a Papervision Base Template) we created a base Papervision template that we could re-use. Now however Papervision includes a form of this base template called BasicView.as

With just a few lines of code you're up and running. Here is the very simple / basic use of BasicView.as:

Actionscript:
  1. package
  2. {
  3.     import flash.events.Event;
  4.     import org.papervision3d.materials.ColorMaterial;
  5.     import org.papervision3d.objects.primitives.Plane;
  6.     import org.papervision3d.view.BasicView;
  7.    
  8.     /**
  9.      * ...
  10.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  11.      */
  12.    
  13.     public class Main extends BasicView
  14.     {
  15.         protected var plane:Plane;
  16.         protected var colorMaterial:ColorMaterial;
  17.        
  18.         public function Main():void
  19.         {
  20.             super();
  21.            
  22.             //Create one material and make it doublesided
  23.             colorMaterial = new ColorMaterial(0xFF0000, .5);
  24.             colorMaterial.doubleSided = true;
  25.            
  26.             //Create a plane using the colorMaterial
  27.             plane = new Plane(colorMaterial, 100, 100);
  28.             scene.addChild(plane);
  29.            
  30.             //Start the rendering
  31.             startRendering();
  32.         }
  33.        
  34.         override protected function onRenderTick(event:Event = null):void
  35.         {
  36.             super.onRenderTick(event);
  37.            
  38.             //Rotate the plane
  39.             plane.yaw(2);
  40.         }
  41.     }
  42. }

This very simple example you will just see a single light red plane rotating.

That is all you need to do to get started in Papervision. Test it out. Don't forget to add your 3D objects to the scene.

Actionscript:
  1. scene.addChild(plane);

Here is what the BasicView.as class looks like:

Actionscript:
  1. package org.papervision3d.view
  2. {
  3.     import org.papervision3d.cameras.SpringCamera3D;   
  4.     import org.papervision3d.cameras.Camera3D;
  5.     import org.papervision3d.cameras.CameraType;
  6.     import org.papervision3d.cameras.DebugCamera3D;
  7.     import org.papervision3d.core.view.IView;
  8.     import org.papervision3d.objects.DisplayObject3D;
  9.     import org.papervision3d.render.BasicRenderEngine;
  10.     import org.papervision3d.scenes.Scene3D;
  11.  
  12.     /**
  13.      * <p>
  14.      * BasicView provides a simple template for quickly setting up
  15.      * basic Papervision3D projects by creating a viewport, scene,
  16.      * camera, and renderer for you. Because BasicView is a subclass of
  17.      * Sprite, it can be added to any DisplayObject.
  18.      *
  19.      * </p>
  20.      *
  21.      * <p>
  22.      * <p>
  23.      * Example:
  24.      * </p>
  25.      * <pre><code>
  26.      * var width:Number = 640;
  27.      * var heigth:Number = 480;
  28.      * var scaleToStage:Boolean = true;
  29.      * var interactive:Boolean = true;
  30.      * var cameraType:String = Camera3D.TYPE;
  31.      *
  32.      * var myBasicView:BasicView = new BasicView(width, height, scaleToStage, interactive, cameraType);
  33.      * myDisplayObject.addChild(myBasicView);
  34.      * </code></pre>
  35.      * </p>
  36.      * @author Ralph Hauwert
  37.      */
  38.     public class BasicView extends AbstractView implements IView
  39.     {
  40.         /**
  41.          * @param viewportWidth  Width of the viewport
  42.          * @param viewportHeight    Height of the viewport
  43.          * @param scaleToStage    Whether you viewport should scale with the stage
  44.          * @param interactive      Whether your scene should be interactive
  45.          * @param cameraType        A String for the type of camera. @see org.papervision3d.cameras.CameraType
  46.          *
  47.          */ 
  48.         public function BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
  49.         {
  50.             super();
  51.            
  52.             scene = new Scene3D();
  53.             viewport = new Viewport3D(viewportWidth, viewportHeight, scaleToStage, interactive);
  54.             addChild(viewport);
  55.             renderer = new BasicRenderEngine();
  56.            
  57.             switch(cameraType)
  58.             {
  59.                 case CameraType.DEBUG:
  60.                     _camera = new DebugCamera3D(viewport);
  61.                     break;
  62.                 case CameraType.TARGET:
  63.                     _camera = new Camera3D(60);
  64.                     _camera.target = DisplayObject3D.ZERO;
  65.                     break;
  66.                 case CameraType.SPRING:
  67.                     _camera = new SpringCamera3D();
  68.                     _camera.target = DisplayObject3D.ZERO;   
  69.                     break;     
  70.                 case CameraType.FREE:
  71.                 default:
  72.                     _camera = new Camera3D(60);
  73.                     break;
  74.             }
  75.            
  76.             cameraAsCamera3D.update(viewport.sizeRectangle);
  77.         }
  78.        
  79.         /**
  80.          * Exposes the camera as a <code>Camera3D</code>
  81.          */
  82.         public function get cameraAsCamera3D():Camera3D
  83.         {
  84.                 return _camera as Camera3D;
  85.         }
  86.        
  87.         /**
  88.          * Exposes the camera as a <code>DebugCamera3D</code>
  89.          */
  90.         public function get cameraAsDebugCamera3D():DebugCamera3D
  91.         {
  92.                 return _camera as DebugCamera3D;
  93.         }
  94.     }
  95. }

Since BasicView.as extends AbstractView.as you can see a few more of the methods available to you just by extending BasicView.as

Actionscript:
  1. package org.papervision3d.view
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.Event;
  5.    
  6.     import org.papervision3d.core.proto.CameraObject3D;
  7.     import org.papervision3d.core.view.IView;
  8.     import org.papervision3d.render.BasicRenderEngine;
  9.     import org.papervision3d.scenes.Scene3D;
  10.    
  11.     /**
  12.      * @Author Ralph Hauwert
  13.      */
  14.     public class AbstractView extends Sprite implements IView
  15.     {
  16.         protected var _camera:CameraObject3D;
  17.         protected var _height:Number;
  18.         protected var _width:Number;
  19.        
  20.         public var scene:Scene3D;
  21.         public var viewport:Viewport3D;
  22.         public var renderer:BasicRenderEngine;
  23.        
  24.         public function AbstractView()
  25.         {
  26.             super();
  27.         }
  28.        
  29.         public function startRendering():void
  30.         {
  31.             addEventListener(Event.ENTER_FRAME, onRenderTick);
  32.             viewport.containerSprite.cacheAsBitmap = false;
  33.         }
  34.        
  35.         public function stopRendering(reRender:Boolean = false, cacheAsBitmap:Boolean = false):void
  36.         {
  37.             removeEventListener(Event.ENTER_FRAME, onRenderTick);
  38.             if(reRender){
  39.                 onRenderTick()
  40.             }
  41.             if(cacheAsBitmap){
  42.                 viewport.containerSprite.cacheAsBitmap = true;
  43.             }else{
  44.                 viewport.containerSprite.cacheAsBitmap = false;
  45.             }
  46.         }
  47.        
  48.         public function singleRender():void
  49.         {
  50.             onRenderTick();
  51.         }
  52.        
  53.         protected function onRenderTick(event:Event = null):void
  54.         {
  55.             renderer.renderScene(scene, _camera, viewport);
  56.         }
  57.        
  58.         public function get camera():CameraObject3D
  59.         {
  60.             return _camera;
  61.         }
  62.        
  63.         public function set viewportWidth(width:Number):void
  64.         {
  65.             _width = width;
  66.             viewport.width = width;
  67.         }
  68.        
  69.         public function get viewportWidth():Number
  70.         {
  71.             return _width;
  72.         }
  73.        
  74.         public function set viewportHeight(height:Number):void
  75.         {
  76.             _height = height;
  77.             viewport.height = height;
  78.         }
  79.        
  80.         public function get viewportHeight():Number
  81.         {
  82.             return _height;
  83.         }
  84.        
  85.     }
  86. }

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

Papervision 3D Controlling Top and Bottom Cylinder Materials

custom-materials-cylinder
While working on a project this morning I came across the need to have a different material applied to a primitive cylinder. After digging through the Cylinder source code I came across these lines

Actionscript:
  1. if (fBottomFace) aFace.push( new Triangle3D(this, [aP1, aP3, aP2], matInstance, [aP1uv, aP3uv, aP2uv]) );
  2.  
  3. //and
  4.  
  5. if (fTopFace) aFace.push( new Triangle3D(this, [aP1, aP2, aP3], matInstance, [aP1uv, aP2uv, aP3uv]));

Since matInstance is just a material it can easily be replaced. I was in a hurry so I decided to just directly modified the class; not the greatest idea but it worked.

Actionscript:
  1. if (j == 0) {
  2.     if(bottomMat)
  3.     {
  4.         if (fBottomFace) aFace.push( new Triangle3D(this, [aP1, aP3, aP2], bottomMat, [aP1uv, aP3uv, aP2uv]) );
  5.     }
  6.     else
  7.     {
  8.         if (fBottomFace) aFace.push( new Triangle3D(this, [aP1, aP3, aP2], matInstance, [aP1uv, aP3uv, aP2uv]) );
  9.     }
  10.    
  11. }
  12. else
  13. {
  14.    
  15.     if(topMat)
  16.     {
  17.         if (fTopFace) aFace.push( new Triangle3D(this, [aP1, aP2, aP3], topMat, [aP1uv, aP2uv, aP3uv]));
  18.    
  19.     }
  20.     else
  21.     {
  22.         if (fTopFace) aFace.push( new Triangle3D(this, [aP1, aP2, aP3], matInstance, [aP1uv, aP2uv, aP3uv]));
  23.     }
  24. }

Here is the new way to create the Cylinder:

Actionscript:
  1. var cyl:Cylinder = new Cylinder(new ColorMaterial(0x000000),200,900,5,20,200,true,true,new ColorMaterial(0x8ad51f),new ColorMaterial(0x00FF00));

Here is the full modified Papervision Cylinder.as class:

Actionscript:
  1. package org.papervision3d.objects.primitives {
  2.     import org.papervision3d.Papervision3D;
  3.     import org.papervision3d.core.geom.*;
  4.     import org.papervision3d.core.geom.renderables.Triangle3D;
  5.     import org.papervision3d.core.geom.renderables.Vertex3D;
  6.     import org.papervision3d.core.math.NumberUV;
  7.     import org.papervision3d.core.proto.*; 
  8.  
  9.     /**
  10.     * The Cylinder class lets you create and display Cylinders.
  11.     * <p/>
  12.     * The Cylinder is divided in vertical and horizontal segment, the smallest combination is two vertical and three horizontal segments.
  13.     */
  14.     public class Cylinder extends TriangleMesh3D
  15.     {
  16.         /**
  17.         * Number of segments horizontally. Defaults to 8.
  18.         */
  19.         public var segmentsW :Number;
  20.    
  21.         /**
  22.         * Number of segments vertically. Defaults to 6.
  23.         */
  24.         public var segmentsH :Number;
  25.    
  26.         /**
  27.         * Default radius of Cylinder if not defined.
  28.         */
  29.         static public const DEFAULT_RADIUS :Number = 100;
  30.    
  31.         /**
  32.         * Default height if not defined.
  33.         */
  34.         static public const DEFAULT_HEIGHT :Number = 100;
  35.    
  36.         /**
  37.         * Default scale of Cylinder texture if not defined.
  38.         */
  39.         static public const DEFAULT_SCALE :Number = 1;
  40.    
  41.         /**
  42.         * Default value of gridX if not defined.
  43.         */
  44.         static public const DEFAULT_SEGMENTSW :Number = 8;
  45.    
  46.         /**
  47.         * Default value of gridY if not defined.
  48.         */
  49.         static public const DEFAULT_SEGMENTSH :Number = 6;
  50.    
  51.         /**
  52.         * Minimum value of gridX.
  53.         */
  54.         static public const MIN_SEGMENTSW :Number = 3;
  55.    
  56.         /**
  57.         * Minimum value of gridY.
  58.         */
  59.         static public const MIN_SEGMENTSH :Number = 1;
  60.    
  61.         public var topFace
  62.         // ___________________________________________________________________________________________________
  63.         //                                                                                               N E W
  64.         // NN  NN EEEEEE WW    WW
  65.         // NNN NN EE     WW WW WW
  66.         // NNNNNN EEEE   WWWWWWWW
  67.         // NN NNN EE     WWW  WWW
  68.         // NN  NN EEEEEE WW    WW
  69.    
  70.         /**
  71.         * Create a new Cylinder object.
  72.         * <p/>
  73.         * @param    material    A MaterialObject3D object that contains the material properties of the object.
  74.         * <p/>
  75.         * @param    radius    [optional] - Desired radius.
  76.         * <p/>
  77.         * @param    segmentsW   [optional] - Number of segments horizontally. Defaults to 8.
  78.         * <p/>
  79.         * @param    segmentsH   [optional] - Number of segments vertically. Defaults to 6.
  80.         * <p/>
  81.         * @param    topRadius   [optional] - An optional parameter for con- or diverging cylinders.
  82.         * <p/>
  83.         * @param    topFace  [optional] - An optional parameter specifying if the top face of the cylinder should be drawn.
  84.         * <p/>
  85.         * @param    bottomFace  [optional] - An optional parameter specifying if the bottom face of the cylinder should be drawn.
  86.         * <p/>
  87.         */
  88.         public function Cylinder( material:MaterialObject3D=null, radius:Number=100, height:Number=100, segmentsW:int=8, segmentsH:int=6, topRadius:Number=-1, topFace:Boolean=true, bottomFace:Boolean=true,topMat:MaterialObject3D = null ,bottomMat:MaterialObject3D = null)
  89.         {
  90.             super( material, new Array(), new Array(), null );
  91.    
  92.             this.segmentsW = Math.max( MIN_SEGMENTSW, segmentsW || DEFAULT_SEGMENTSW); // Defaults to 8
  93.             this.segmentsH = Math.max( MIN_SEGMENTSH, segmentsH || DEFAULT_SEGMENTSH); // Defaults to 6
  94.             if (radius==0) radius = DEFAULT_RADIUS; // Defaults to 100
  95.             if (height==0) height = DEFAULT_HEIGHT; // Defaults to 100
  96.             if (topRadius==-1) topRadius = radius;
  97.    
  98.             var scale :Number = DEFAULT_SCALE;
  99.    
  100.             buildCylinder( radius, height, topRadius, topFace, bottomFace,topMat,bottomMat );
  101.         }
  102.    
  103.         private function buildCylinder( fRadius:Number, fHeight:Number, fTopRadius:Number, fTopFace:Boolean, fBottomFace:Boolean ,topMat:MaterialObject3D,bottomMat:MaterialObject3D):void
  104.         {
  105.             var matInstance:MaterialObject3D = material;
  106.            
  107.             var i:Number, j:Number, k:Number;
  108.    
  109.             var iHor:Number = Math.max(MIN_SEGMENTSW, this.segmentsW);
  110.             var iVer:Number = Math.max(MIN_SEGMENTSH, this.segmentsH);
  111.             var aVertice:Array = this.geometry.vertices;
  112.             var aFace:Array = this.geometry.faces;
  113.             var aVtc:Array = new Array();
  114.             for (j=0;j<(iVer+1);j++) { // vertical
  115.                 var fRad1:Number = Number(j/iVer);
  116.                 var fZ:Number = fHeight*(j/(iVer+0))-fHeight/2;//-fRadius*Math.cos(fRad1*Math.PI);
  117.                 var fRds:Number = fTopRadius+(fRadius-fTopRadius)*(1-j/(iVer));//*Math.sin(fRad1*Math.PI);
  118.                 var aRow:Array = new Array();
  119.                 var oVtx:Vertex3D;
  120.                 for (i=0;i<iHor;i++) { // horizontal
  121.                     var fRad2:Number = Number(2*i/iHor);
  122.                     var fX:Number = fRds*Math.sin(fRad2*Math.PI);
  123.                     var fY:Number = fRds*Math.cos(fRad2*Math.PI);
  124.                     //if (!((j==0||j==iVer)&&i>0)) { // top||bottom = 1 vertex
  125.                     oVtx = new Vertex3D(fY,fZ,fX);
  126.                     aVertice.push(oVtx);
  127.                     //}
  128.                     aRow.push(oVtx);
  129.                 }
  130.                 aVtc.push(aRow);
  131.             }
  132.             var iVerNum:int = aVtc.length;
  133.    
  134.             var aP4uv:NumberUV, aP1uv:NumberUV, aP2uv:NumberUV, aP3uv:NumberUV;
  135.             var aP1:Vertex3D, aP2:Vertex3D, aP3:Vertex3D, aP4:Vertex3D;
  136.    
  137.             for (j=0;j<iVerNum;j++) {
  138.                 var iHorNum:int = aVtc[j].length;
  139.                 for (i=0;i<iHorNum;i++) {
  140.                     if (j>0&&i>=0) {
  141.                         // select vertices
  142.                         var bEnd:Boolean = i==(iHorNum-0);
  143.                         aP1 = aVtc[j][bEnd?0:i];
  144.                         aP2 = aVtc[j][(i==0?iHorNum:i)-1];
  145.                         aP3 = aVtc[j-1][(i==0?iHorNum:i)-1];
  146.                         aP4 = aVtc[j-1][bEnd?0:i];
  147.                         // uv
  148.                         var fJ0:Number = j    / iVerNum;
  149.                         var fJ1:Number = (j-1)  / iVerNum;
  150.                         var fI0:Number = (i+1)  / iHorNum;
  151.                         var fI1:Number = i    / iHorNum;
  152.                         aP4uv = new NumberUV(fI0,fJ1);
  153.                         aP1uv = new NumberUV(fI0,fJ0);
  154.                         aP2uv = new NumberUV(fI1,fJ0);
  155.                         aP3uv = new NumberUV(fI1,fJ1);
  156.                         // 2 faces
  157.                         aFace.push( new Triangle3D(this, [aP1,aP2,aP3], matInstance, [aP1uv,aP2uv,aP3uv]) );
  158.                         aFace.push( new Triangle3D(this, [aP1,aP3,aP4], matInstance, [aP1uv,aP3uv,aP4uv]) );
  159.                     }
  160.                 }
  161.                 if (j==0||j==(iVerNum-1)) {
  162.                     for (i=0;i<(iHorNum-2);i++) {
  163.                         // uv
  164.                         var iI:int = Math.floor(i/2);
  165.                         aP1 = aVtc[j][iI];
  166.                         aP2 = (i%2==0)? (aVtc[j][iHorNum-2-iI]) : (aVtc[j][iI+1]);
  167.                         aP3 = (i%2==0)? (aVtc[j][iHorNum-1-iI]) : (aVtc[j][iHorNum-2-iI]);
  168.    
  169.                         var bTop:Boolean = j==0;
  170.                         aP1uv = new NumberUV( (bTop?1:0)+(bTop?-1:1)*(aP1.x/fRadius/2+.5), aP1.z/fRadius/2+.5 );
  171.                         aP2uv = new NumberUV( (bTop?1:0)+(bTop?-1:1)*(aP2.x/fRadius/2+.5), aP2.z/fRadius/2+.5 );
  172.                         aP3uv = new NumberUV( (bTop?1:0)+(bTop?-1:1)*(aP3.x/fRadius/2+.5), aP3.z/fRadius/2+.5 );
  173.    
  174.                         // face
  175.                         if (j == 0) {
  176.                             if(bottomMat)
  177.                             {
  178.                                 if (fBottomFace) aFace.push( new Triangle3D(this, [aP1, aP3, aP2], bottomMat, [aP1uv, aP3uv, aP2uv]) );
  179.                             }
  180.                             else
  181.                             {
  182.                                 if (fBottomFace) aFace.push( new Triangle3D(this, [aP1, aP3, aP2], matInstance, [aP1uv, aP3uv, aP2uv]) );
  183.                             }
  184.                            
  185.                         }
  186.                         else {
  187.                            
  188.                             if(topMat)
  189.                             {
  190.                                 if (fTopFace) aFace.push( new Triangle3D(this, [aP1, aP2, aP3], topMat, [aP1uv, aP2uv, aP3uv]));
  191.                            
  192.                             }
  193.                             else
  194.                             {
  195.                                 if (fTopFace) aFace.push( new Triangle3D(this, [aP1, aP2, aP3], matInstance, [aP1uv, aP2uv, aP3uv]));
  196.                             }
  197.                            
  198.                            
  199.                         }
  200.                     }
  201.                 }
  202.             }
  203.             this.geometry.ready = true;
  204.            
  205.             if(Papervision3D.useRIGHTHANDED)
  206.                 this.geometry.flipFaces();
  207.         }
  208.     }
  209. }

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

Code / Programs it’s hard to live without

p_package_custom_built

Here is a quick list of Classes / Packages and programs that seem to make life just that much easier. This is a list based off of things we use daily for quick development of agency type Flash sites. This is in no way a complete list but anyone just wanting to increase their productivity can start here.

Programs:

1) FlashDevelop (PC only - or via VMWare) :/

Use this and easily literally shave days off your coding time. If you don't use this go with FlexBuilder.

2) Charles (Mac or PC)

Find the root of the real issues when you load dynamic content.

3) Smart FTP (PC only) :/

Quick uploads

Code:

1) Foomonger (Later)

Call a method / function a second later or a frame later. Also has a LoadWatcher for loadProgress

2) Tweener

Some use TweenLite I like Tweener. It always seems to yield the best results. I could be wrong but that's my opinion.

2) I was wrong - TweenLite/Max

The results speak for themselves - TweenLite/Max vs other Tween Engines

3) BulkLoader (unless you're using Gaia - see below)

The hotness for loading multiple files and having access to them across your whole project.

4) Papervision

Of course. :-D

* Added from Comments *

5)SWFObject

Frameworks:

1) Gaia

Steven Sacks has created one of the best frameworks that is to be used on agency style Flash sites. You can have an entire simple flash site up in about 5 minutes or less. (not joking). Site scaffolding, asset loading, browser navigation, page loading, SEO, a place for your transitions (code or timeline) and much more. AS2 and AS3 supported. Check it out!

Are there any programs or code bases you can't live without?

Let us know.

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