Posts Tagged ‘away3dlite’

“3D in Flash” and “Away3D 3.6 Essentials”

There’s been a lot of talk as of this weekend about 3D in Flash, due to Adobe’s announcement that Flash Player 11 is now available at Adobe Labs. Included in Flash Player is the much anticipated “Molehill” 3D API. To get an idea of how huge of a leap in terms of rendering this is for Flash, take a look at some of these videos I posted a few months back. Or better yet, experience it yourself by playing “Zombie Tycoon”!

Right in step with Adobe’s announcement came one from the Away3D team. They unveiled the alpha version of Away3D 4.0 “Broomstick”. This is the first version of my favorite 3D Flash engine that leverages the power of the Adobe “Molehill” API. Check out the Adobe Labs page for Molehill to see more of what Away3D will let you do, without having to get into the nitty, gritty details of Molehill.

In order to get a jump start on your Away3D development, I’d highly suggest picking up one (or both, like me) of these books: “” and ““.  Both are great guides to getting started with Away3D,  as well as 3D graphics in Flash in general.  While no longer the latest and greatest, they will undoubtedly continue to give great insight for aspiring Away3D developers.

Away3D 4.0 "Broomstick"

As these are both great texts, I’m not going to put their attributes side by side and compare every detail.  Instead I’m just going to point out the highlights of each.  You really can’t go wrong with either.

“Away3D 3.6 Essentials” Highlights

  • The clearest highlight is without question the choice of technical reviewer… Tony Lukasavage (see also, me).
  • Matthew Casperson is the author and his brighthub.com work was the home for some of my earliest lessons in Away3D. Great demos and tutorials.
  • Gives an extremely detailed look at the objects in Away3D, even laying out the initialization objects for many of the classes.  May not sound like a big deal, but Away3D makes heavy use of init objects for class constructors.  The only way to know how to use them without a reference is to go digging through the source.
  • Answers one of the most frequently asked questions in Away3D with a simple chart: Which lights affect which materials?
  • While both books discuss and explain model animation, this book delves into the sometimes baffling territory of how to properly export rigged models from popular modeling and animation program for use with Away3D.  In most cases its not as simple or intuitive as you might expect and this little extra help can go a long way.
  • This book branches out a little further than “3D in Flash”, discussing topics like particle engines, pixelbender shaders, and postprocessing as they pertain to Away3D.

 

“The Essential Guide to 3D in Flash” Highlights

  • The authors are none other than Rob Bateman and Richard Olsson, cofounder and core developer for Away3D.  There’s no disputing that getting the information from the crafters of the engine cannot be beat.
  • Includes set up instructions for FDT.
  • While “Away3D 3.6 Essentials” gives a brief look at the differences between point, directional, and ambient lights, “3D in Flash” gives a very detailed description of each.  Paragraphs of information and easy to grasp visuals paint a much more clear picture of just how light works.
  • Contains a great example of how you can programmatically animate rigged models.  In some cases even when you follow all the rules, imported animations don’t work quite right.  This valuable example lets you take the animation into your own hands.

I could go on with more, but beyond this, its just splitting hairs.  Both books are so good it’s a great choice either way.

If you are serious about picking up Away3D for 3D Flash development and want the quickest path to success, either one will do just fine.  Just be sure to follow it all and actually code along with the examples.  That’s where a lot of the real value in these books lies.  And be sure you make it to the end where possibly the most important topic lies for each book: performance.  But then again, with the coming of “Molehill”, those performance concerns might not be quite so critical anymore.

Away3d People, Places, and Tutorials

2 things brought about this post:

  1. The increased popularity of Away3D with the announcement of “Molehill” at AdobeMax 2010.
  2. The scarcity and disarray of some of Away3D’s greatest resources for learning and inspiration.

To fix this I am going to create a collection here of the best available blogs, links, tutorials, demos, and videos from the Away3D community. With a little help from you, the visitors to this blog, of course. So PLEASE, if I miss a team member or a good blog, leave a comment and I’ll add it to the list. OK, here we go.

The twitter list

Let me know if you want to be added.

The Project

  • Away3D.com – The official Away3D Flash Engine site
  • Away3D tutorials – A list of useful, though slightly dated, tutorials for the engine
  • – A growing community where Away3D developers and newbies can interact and ask questions, often addressed by the core team members themselves.

The Team

  • Rob Bateman – Away3D founder, lead developer, and co-author of “The Essential Guide to 3D in Flash”
  • Fabrice Closier – Away3D developer and creator of Prefab, the Away3D modeler and workflow enhancer.
  • Peter Kapelyan – Away3D developer
  • Greg Caldwell – Away3D documentation, and the inspiration for my reflection in Away3D demo.
  • Jalava – Away3D bitmap rendering
  • Katopz – Away3D developer and Collada animation
  • Li – Away3D developer and vector text/shapes
  • Richard Olsson – Away3D developer and co-author of “The Essential Guide to 3D in Flash”
  • David Lenaert – Flash 10 shaders and Pixelbender

The blogs, devs, and links

  • Tony Lukasavage (me) – A blog full of Away3D demos, code, and overall goodness.
  • Flash Tutorials (Away3D) – A great collection of Away3D tutorials to help you get started.
  • Ralph Hauwert – Flash 3D wizard with some good Away3D content.
  • Einar Öberg – Great Flash developer with some awesome Away3D projects.
  • Bartek Drozdz – Now mostly a Unity3D blog, it still contains some real Away3D gems.
  • Darcey Lloyd – This site has mountains of great Away3d demos and instructional content.
  • Matthew Casperson – Tons of detailed demos and how-to’s for Away3D
  • Harry Northover – A bit dated, but still has some good, basic Away3D examples.
  • Advanced Mediocrity – A handful of cool Away3D examples
  • Jason Begot – A couple of great Away3D samples, and he was the inspiration for my mesh morphing demo.
  • Exey Panteleev – Flash 3D developer with some Away3D demos, and he inspired my dynamic height demo.
  • blog.tartiflop – Pretty old Away3D stuff, but it still contains some very useful content for understanding the engine.
  • flash-3d.net – A growing collection of Away3D tutorials and examples ported from Papervision3D.
  • John Wilson – Nice collection of Away3D demos and samples.
  • McFunkyPants – Indie game developer content with some great Flash 3D material (Including insight on Molehill).

The books

The games, videos, and extras

  • BattleCell – The incredible Away3D, multi-player, first person shooter. Grab a friend and blow sh!t up!
  • “Molehill” demo videos - Get a preview at the amazing advances coming to Flash 3D
  • Away3D Shoot ‘Em Up with sound – A lengthy tutorial on game building and sound for Away3D.
  • Gesture Works – Shows how to add multi-touch support to your Away3D applications
  • Away3D Mobile – See Away3DLite running on mobile devices

This list is far from exhaustive and I would love it if my readers would contribute. Let me hear what your other Away3D resources are. I’m all ears.

Adobe “Molehill” 3D API Videos

In the wake of the Adobe Flash “Molehill” 3D API being unveiled at AdobeMax this year, interest in 3D Flash has exploded. Rather than bore you with why I think this is so interesting (though I must mention that it uses the GPU), here’s some videos to give you an idea of how incredible this API is going to be:







Yes, I know, it IS awesome. But be patient kids, the word is a painfully vague “mid 2011″ beta release. In the meantime, though, start sharpening with your 3D Flash engine of choice because Adobe has already stated that its going to let the community build the engines. And believe me, Away3D, Alternativa, and a handful of others will be waiting with their Molehill-ready engines as soon as it is released.

Johnny Cash in Flash

Hi, I'm Johnny Cash

Click here or the image above for the demo.
→ View the source code.
→ Download Source: cash.zip
NOTE: You’ll need to download away3dlite, , and to compile the code.

Inspired by the legendary Johnny Cash I decided to dive into a few AS3 development topics I haven’t gotten to yet to create a 3d equalizer and tribute to the Man in Black. Those topics, along with some other more familiar ones, include:

  • Playing audio in Flash with Sound and SoundChannel
  • Using the SoundMixer to generate values based on the audio
  • Searching for images with the Google API via
  • Creating a PHP proxy for beating Flash cross-domain security issues
  • Using Away3dLite for speedy 3d visualization (I even get 15 FPS on my phone!)
  • Using Prefab to export 3d models as native AS3 code for Away3d or Away3dLite.

This demo has a good bit more code than I usually post up.  It also uses a couple external libraries, namely away3dlite (3d rendering), (Google API), and (super useful AS3 utilities).  Rather than overwhelm you with mountains of tutorial-like rambling, instead I’ll leave this demo here to be enjoyed, make the source code available, and break down each of these topics into smaller tutorials/guides in the near future.

Sometimes your muse doesn’t need to be even slightly related to your field of creativity.  In fact, that can often make for the most interesting inspiration.

JigLib Flash and Away3D

Away3D and Jiglib Flash

→ Click the above image or here to play the demo
View the source code

The Overview

Toying around with JigLib Flash in Away3D today was both interesting and sobering. For those who don’t know, JigLib is a 3D physics engine, and JigLib Flash is the AS3 port of it. While my expectations weren’t too high since this is complex mathematical processing in Flash, I was hoping for a little more. Don’t get me wrong, though, there’s some very cool potential here.  Be sure to check the tutorials and demos added by people who didn’t give up quite as quickly as me: JigLib Flash demos and tutorials.  I particularly enjoyed some of the car physics demos using this library.

I was setting out to do a basic Jenga-like game. Its just a tower of zig zagging blocks, 3 blocks to a row, 18 rows total. It quickly became evident that this just wasn’t going to happen. After about 4 rows of blocks the frame rate dropped down into single digits and there was tons of “jitter” among the blocks in the scene. I assume the jitter has to do with the fact that Flash can’t process the collisions fast enough and Jiglib is trying to correct rigid body penetrations. I did A LOT of tinkering with the settings, which are a group of static settings that manipulate how the physics is calculated, but couldn’t make it work for me. In the end, I think JigLib Flash just needs a lot of work on “stacking” and rigid bodies with many simultaneous points of contact.

Framerate Fail

Framerate Fail

OK, now that I’ve had my purge of frustration, let me at least talk about a half decent example of Away3D and JigLib running very well together. In the demo at the top of this post I just have a whole bunch of spheres falling into a box with JigLib taking care of the collisions. It works very well and even maintains a good frame rate. So good in fact that I even took the time to add some simple shadows to the falling spheres.

The Code

full source code (download link at bottom)
jiglib_away3d.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*"
                    creationComplete="init();" frameRate="60" height="600" width="800" 
                    viewSourceURL="srcview/index.html">
    <mx:Script>
        [CDATA[
                import away3d.primitives.Plane;
                import away3d.core.base.Mesh;
                import __AS3__.vec.Vector;
                import away3d.materials.BitmapMaterial;
                import jiglib.physics.RigidBody;
                import jiglib.plugin.away3d.*;
                import mx.core.UIComponent;
                import away3d.primitives.Sphere;
                import away3d.core.math.Number3D;
                import away3d.core.utils.Cast;
 
                private var _physics:Away3DPhysics;
                private var _shadows:Vector.<Plane> = new Vector.<Plane>();
                private var _bodies:Vector.<RigidBody> = new Vector.<RigidBody>();
                [Embed("shadow.png")] private var pngShadow:Class;
                [Embed("water.jpg")] private var jpgPaper:Class;
 
                private function init():void {
                        if (stage) {
                                        initAway3D();
                                } else {
                                        this.addEventListener(Event.ADDED_TO_STAGE, function(e:Event):void { initAway3D(); });
                                }     
                }     
 
                private function initAway3D():void {
                        stage.quality = flash.display.StageQuality.LOW;
                        stage.scaleMode = StageScaleMode.NO_SCALE;
                        _drawBackground();
 
                        // prepare physics
                        var walls:Vector.<RigidBody> = new Vector.<RigidBody>();
                        _physics = new Away3DPhysics(away3dMain.view, 5);
                        walls.push(_physics.createCube({width:1000, height:10, depth:1000}));
                        walls.push(_physics.createCube({width:10, height:1000, depth:1000}));
                        walls.push(_physics.createCube({width:1000, height:1000, depth:10}));
                        walls.push(_physics.createCube({width:10, height:1000, depth:1000}));
 
                        var sprite:Sprite = new Sprite();
                        var matrix:Matrix = new Matrix();
                        matrix.createGradientBox(512,512,0,0,0);
                        sprite.graphics.beginGradientFill("radial", [0xdddddd,0x000000], [1,1], [0,255], matrix);
                        sprite.graphics.drawRect(0,0,512,512);
                        sprite.graphics.endFill();
                        var bmd:BitmapData = new BitmapData(512,512,false);
                        bmd.draw(sprite);
                        var mat:BitmapMaterial = new BitmapMaterial(bmd);
 
                        for (var j:uint = 0; j < walls.length; j++) {
                                var body:RigidBody = walls[j];
                                var mesh:Mesh = Away3dMesh(body.skin).mesh;
                                body.movable = false;
                                        mesh.material = mat;
                                        mesh.ownCanvas = true;
                                        mesh.pushback = true;
 
                                        switch(j) {
                                                case 1:
                                                        body.x = 505;
                                                        body.y = 495;
                                                        break;
                                                case 2:
                                                        body.z = 505;
                                                        body.y = 495;
                                                        break;
                                                case 3:
                                                        body.x = -505;
                                                        body.y = 495;
                                                        break;
                                        }
                        }
 
                                var paper:BitmapMaterial = new BitmapMaterial(Cast.bitmap(jpgPaper));
                                for (var i:int = 0; i < 20; i++) {
                                        var sphere:RigidBody = _physics.createSphere({radius:30, segmentsW:6, segmentsH:6});
                                        _bodies.push(sphere);
                                        sphere.x = 100 - Math.random() * 200;
                                        sphere.y = 700 + Math.random() * 3000;
                                        sphere.z = 200 - Math.random() * 100;
                                        sphere.material.restitution = 1; 
 
                                        // This is how to access the engine specific mesh/do3d
                                        _physics.getMesh(sphere).material = paper;
 
                                        var plane:Plane = new Plane({material:new BitmapMaterial(Cast.bitmap(pngShadow)), height:80, width:80, bothsides:true});
                                        plane.ownCanvas = true;
                                        plane.pushback = true;
                                        plane.filters = [new BlurFilter(8,8)];
                                        plane.blendMode = BlendMode.SUBTRACT;
                                        away3dMain.view.scene.addChild(plane);
                                        _shadows.push(plane);
                                }
 
                                // create away3d scene
                                away3dMain.title = "SavageLook.com -- Away3D JigLib Demo";
                                away3dMain.camera.position = new Number3D(0, 700, -1500);
                                away3dMain.camera.lookAt(new Number3D(0,0,0));
 
                                // assign pre and post render functions
                                away3dMain.preRender = function():void { 
                                        for (var k:uint = 0; k < _shadows.length; k++) {
                                                if (_shadows[k].x > 505 || _shadows[k].x < -505 || _shadows[k].z > 505 || _shadows[k].z < -505 || _bodies[k].y < -10) {
                                                        _shadows[k].visible = false;
                                                } else {
                                                        _shadows[k].x = _bodies[k].x;
                                                        _shadows[k].z = _bodies[k].z;
                                                }
                                        }
                                        _physics.step(); 
                                };
                                away3dMain.postRender = function():void { trace("postRender"); };
                }
 
                private function _drawBackground():void {
                        var sprite:Sprite = new Sprite();
                        var ui:UIComponent = new UIComponent();
                        var matrix:Matrix = new Matrix();
 
                        matrix.createGradientBox(this.width, this.height, Math.PI/2, 0, 0);
                        sprite.graphics.beginGradientFill("linear", [0x888888, 0xffffff], [1,1], [0,255], matrix);
                        sprite.graphics.drawRect(0, 0, this.width, this.height);
                        sprite.graphics.endFill();
                        ui.addChild(sprite);
                        this.addChildAt(ui, 0);
                }
        ]]>
    mx:Script>
        <local:AwayUIC id="away3dMain"  x="0" y="0" height="600" width="800"/>
mx:Application>

AwayUIC.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
        <mx:Script>
                [CDATA[
                        import away3d.debug.AwayStats;
                        import away3d.core.math.Number3D;
                        import away3d.cameras.TargetCamera3D;
            import away3d.containers.View3D;
            import away3d.core.render.Renderer;
 
            public var view:View3D;
            public var camera:TargetCamera3D;
            public var doRender:Boolean;
            private var _title:String;
            private var _link:String;
            private var _titleText:TextField;
 
            public var preRender:Function = null;
            public var postRender:Function = null;
 
            override protected function createChildren():void {
                super.createChildren();
                doRender = true;
 
                // setup camera
                camera = new TargetCamera3D();
                camera.position = new Number3D(0, 0, -1000);
                                camera.lookAt(new Number3D(0,0,0));
 
                // setup view
                view = new View3D({camera:camera, renderer:Renderer.BASIC});
                view.x = this.unscaledWidth/2;
                view.y = this.unscaledHeight/2;
                this.addChild(view);
 
                // add stats and title
                var stats:AwayStats = new AwayStats(view);
                this.addChild(stats);
                _title = "SavageLook.com";
                _link = "https://savagelook.com/blog";
                _setText();
 
                this.addEventListener(Event.ENTER_FRAME, function(e:Event):void { _render(); });
            }
 
            private function _setText():void {
                if (_titleText == null) {
                        _titleText = new TextField();
                        this.addChild(_titleText);
                }
 
                _titleText.text = _title;
                _titleText.setTextFormat(new TextFormat("arial", 14, 0xffffff, false, false, false, _link));
                _titleText.x = 150;
                _titleText.y = 10;
                _titleText.width = _titleText.textWidth * 1.1;
                _titleText.filters = [new DropShadowFilter()];
            }
 
            public function get link():String {
                return _link;
            }
 
            public function set link(value:String):void {
                _link = value;
                _setText();
            }
 
            public function get title():String {
                return _title;
            }
 
            public function set title(value:String):void {
                _title = value;
                _setText();
            }
 
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
                super.updateDisplayList(unscaledWidth, unscaledHeight);
                view.x = unscaledWidth/2;
                view.y = unscaledHeight/2;
 
                if (view.stage) {
                        _render();
                }
            }
 
            private function _render():void {
                if (doRender) {
                        if (preRender != null) {
                                preRender();
                        }
                        view.render();
                        if (postRender != null) {
                                postRender();
                        }
                }
            }
        ]]>
        mx:Script>
mx:UIComponent>

The Summary

My hasty opinion in this case is that JigLib is fun to play with, but don’t get excited about doing anything super complex… yet.  I follow a few of the developers and contributors and they are constantly working on it.  They even just recently added support for Away3dLite so you can use all that quick rendering goodness along with it.  I fully intend to follow this project closely as it matures.

Away3dLite: Bitmaps and BlendModes

I finally took some time away from Away3D… and dove into Away3DLite!  Away3dLite is quite simply your choice when you need performance over functionality.  It strips a lot of the heavier features from Away3D and leverages improvements in Flash Player 10 directly.  For this reason it’s only compatible with Flash Player 10 (sorry 2.x users).  Away3dLite in the right hands, though, is no slouch in the visual flair department.

In this demo I take a JPG, slice and dice it up into cubes, apply a color material to each cube that is the “color average” of a chunk of BitmapData, then let you change the background color and blend mode to get some interesting visual effects.  The demo below has almost 5000 faces and 400 color materials, which would likely bring Away3D down to a crawl in terms of frame rate.  With Away3dLite, though, I’m currently getting a steady ~27 frame per second!  Great performance and cool effects all rolled into one great package.

You can right click and “view source” on the demo to get a look at exactly what I did, but there’s one section of code in particular I’d like to point out here.  In Away3D, if you want to apply Flash filters and blending, you needed to do the following:

var object:Cube = new Cube();
object.ownCanvas = true;
object.filters = [new GlowFilter()];
object.blendmode = BlendMode.ADD;
view.scene.addChild(object);

In Away3DLite, things are slightly different.  In Away3DLite, objects don’t have their own canvas by default, I assume as a performance boost.  To give your objects a canvas and achieve the same as the above code, you have to create your own canvas in the layer property of Object3D and add it to the view, like this:

var object:Cube6 = new Cube6();
object.layer = new Sprite();
object.layer.filters = [new GlowFilter()];
object.layer.blendmode = BlendMode.ADD;
view.addChild(cube.layer);
view.scene.addChild(cube);

Hopefully this saves somebody switching from Away3D to Away3DLite a few minutes (or hours).

Featured Away3dLite Code:

  • flash.display.BitmapData.getPixel()
  • flash.display.BlendMode
  • away3dlite.primitives.Cube6
  • away3dlite.core.base.Object3D.layer

Away3DLite + Augmented Reality = Free Camaro!

As promised the demo above includes bare bones source code (right click to view source)  for getting FLARManager up and running with Away3dLite.  And for a limited time, it comes with your very own Camaro!  99% of the credit goes to Eric Socolofsky as the code is just a trimmed down version of his example code included in FLARManager.  The model has been provided free by the modeler “Race Tracks” at turbosquid.  In order to use this demo, you need to do the following:

  • Download and print this marker
  • Turn on your webcam and point it at yourself.
  • Start the demo, point the printed marker at the webcam, and enjoy!

If the above steps aren’t clear, check out the .  For those out there constantly evaluating how far we can push the performance of away3dlite, you might like to know that the model consists of right around 1000 faces.  1000+ faces along with the video processing of patterns and I’m still maintaining right around 30 FPS.  Not bad at all.

Away3dLite: Face linking, take 2

It was great.  I had a moment of triumph.  In my meager 3D and Away3D experience I managed to get face linking functionality into Away3DLite.  Proud of myself, I posted my success at the list.  But my party was soon rained on by one of the Away3D developers, Peter Kapelyan, who immediately informed that my linked objects weren’t aligning as they should be.  It felt a lot like that scene in National Lampoon’s Christmas Vacation where Clark finally gets the lights lit on his house, only to have his father-in-law inform him that the little lights weren’t twinkling…

I know Peter, thanks for noticing.

To that end, the above demo is the next revision of my prior face linking code.  This time, I got alignment working.  Because I am 3D math deficient (I’m working on it) I was unable to implement the alignment properly without using a container object for the source and the linked objects.  Someone a little more math savvy can surely make use of the upAxis parameter of the lookAt() function to make it work, but I need some studying before I can do it on my own.  Shawn McInerney from the dev list offered up a potential solution, but it’s a little over my head now.  Perhaps someone else perusing this blog can make use of it.

I hope Peter didn’t take this the wrong way, as I have an abrasive sense of humor that doesn’t translate well to written word.  Just in case, here’s a link to his site which is extremely clean, cool, slick, and a whole bunch of other adjectives that equal up to awesome.

Away3dLite: Normals and Face Linking

The above is a demo of face linking implemented in Away3dLite (right lick to view source).  As you’ll see in the demo, face linking allows us to “link” a 3D object to another, rendering it at the center of the source’s face and then moving along the face’s normal by a given offset.  All credit goes to the original author of the Away3D FaceLink class, as my work was just a minimal modification to port it to Away3DLite.

One thing to note is that this demo required a modification to the Face class, found in away3dlite.core.base.Face.  I simply added a calculated normal and center for the face at creation time and made it available as a public variable.  It’s not altogether the cleanest code I’ve written, but it gives you a good idea of how you might use face linking in your own Away3DLite application.

Just for fun, here’s a couple links to other flash apps I’ve seen that make cool use of faces, vertices, and normals: