Papervision3D, FlashDevelop template

Flashdevelop Here’s a simple FlashDevelop template to speed up the creation of a 3D render in Papervision3D 2.0. Download the template from here or copy the code below and save it as View3D.as.fdt.

In FlashDevelop go to Tools –> Application files. This will open your Explorer: Now go into the folder Templates > ProjectFiles > AS3Project and drop the template in there.

You will now if you left click on your src package and go to Add > see the option ‘BasicView’ in the menu that pops up.

The custom arguments available for template creation are listed at http://www.flashdevelop.org/community/viewtopic.php?t=1521

Here’s the template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package $(Package) $(CSLB){

   import flash.events.Event;
   import org.papervision3d.view.BasicView;

   public class $(FileName) extends BasicView {
      $(EntryPoint)
      /**
      * $(FileName)
      */

     
      public function $(FileName)():void {
         init();
         startRendering();
      }

      private function init():void {
      }
     
      override protected function onRenderTick(e:Event=null):void{
         super.onRenderTick();
      }
   
   }
}

Lastly, a good set of templates can be found over at http://www.actionscriptdeveloper.co.uk/puremvc-first-thoughts-flashdevelop-templates/

Papervision3D, interactive material

It’s easy to create an interactive papervision 3D primitive such as this Cube (click on it’s sides):


Get Adobe Flash player

The cube uses the BitmapMaterial class (the sides are embedded jpg’s) and all we need to do to make them interactive is to remember to set interactive to true:

1
2
bitmapMaterial6.name = "6";
bitmapMaterial6.interactive = true;

Once we created our cube the last bit is just to add the event listener to the InteractiveScene3DEvent which is dispatched by the Cube. And we can use the event property evt.face3d.material.name of the current material side clicked to retrieve the name of the same:

1
2
3
4
5
6
7
// create a cube based on the list
primitive = new Cube(materiallist, 400, 400, 400, 3, 3, 3);
primitive.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, handleClick);
//.../
private function handleClick (evt:InteractiveScene3DEvent) :void {
testText.text = "__side clicked : " +evt.face3d.material.name;
}

The InteractiveScene3DEvent is not limited to click events however, the documentation at http://papervision3d.googlecode.com/svn/trunk/as3/trunk/docs/org/papervision3d/events/InteractiveScene3DEvent.html – shows that we can also listen for MOVE, OVER, OUT, etc. Nice.

If you would like to get hold of the full code for this example then you can download it here (Flashdevelop project).

Theres some great Papervision tutorials over at http://www.madvertices.com where I’ve taken several myself!

AS 3 Dictionary Object: a way to map instances of sealed Classes

In Action Script 3 most classes are sealed. This means that for most Objects we are not able to create new properties run time beyond those that where available compile time. This is not the case with Array and Object though which are both dynamic and regularly come in handy to us for example in the creation of an associative array (or sometimes called a ‘hash’) :

1
2
3
var myAssoc:Object = new Object();
myAssoc["oranges"] = 101;
trace ("number of oranges " + myAssoc["oranges"])

But what to do if you’re in need of creating properties upon an instance that belongs to a sealed class. For example say that we with flash.display.SimpleButton would like to add the property counter which tells us how what time interval to start a timer with. We could not:

1
2
3
(//import flash.display.SimpleButton etc...)
var myBtn:Simple Button = new SimpleButton();
myBtn.timestamp = 1000;

The above would throw an error as SimpleButton like most classes in ActionScript 3 are sealed. The solution would be to extend SimpleButton with a dynamic class like so :

1
2
3
4
5
6
7
8
9
10
11
package
{
import flash.display.SimpleButton;
public dynamic class DynamicButton extends SimpleButton
{
   public function DynamicButton()
   {

   }
}
}

Making use of our dynamic button we could now :

1
2
3
var dynBtn:DynamicButton = new DynamicButton();
dynBtn.timestamp = 1000;
trace ("dynamic button timestamp value " + dynBtn.timestamp);

And this would compile without errors and work nicely. However there is an other approach to this which comes very handy as a way of creating dynamic properties and referring to them. Here enters the Dictionary Object. This object is a bit like our associative array above but with the big difference that it can take an object itself as lookup key to find a value. For our oranges we get:

1
2
3
4
var dict:Dictionary = new Dictionary();
var myOrange:Object = new Object();
dict[myOrange] = 101;
trace ("number of oranges dictionary approach " + dict[myOrange]);

Using a Dictionary Object we thus have a way to lookup properties using the objects themselwes rather than using the variable names to refer to properties. This also works for instances of sealed classes such as our button example. We can write:

1
2
3
4
dict = new Dictionary();
var myButton: SimpleButton = new SimpleButton ();
dict[myButton] = 1001;
trace ("dictionary button counter value " + dict[myButton]);

Since the button is the key, it does not matter that SimpleButton is a sealed class. We are not trying to assign a new property to the SimpleButton instance by using a variable name. Instead we use the instance itself and thus we here have a handy way of assigning values also to instances that don’t take new dynamic properties.

Some further readings:
http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html
http://www.zombieflambe.com/actionscript-3/as3-dictionary-class-array-object-benchmark/
http://pixelwelders.com/blog/best-practices/2008/speed-tests-objects-vs-arrays-vs-dictionaries/