Creating a 3D Engine in Flash

3d-engine-banner-part1

A few weeks ago I had to create a simple X-axis based parallax ‘engine’ for a project. Just basic horizontal movement, which is scaled based on an abstract z value. Well, somehow that turned into a full 3D engine. So I am continuing to build on what I had started in order to create my own Flash 3D engine, not because I think I can build a better Papervision, Away3D, or Five3D, (because I’m sure I can’t) but rather in order to learn. Since I end up using 3D engines fairly often now, I figure it’s good experience for me to build my own and see how it can work from the ground up.

Continue reading “Creating a 3D Engine in Flash”

Working with Away3D

So for the last few weeks I’ve been experimenting with Away3D. Away3D is a free 3D engine for Flash, very similar to Papervision3D. As a previous user of Papervision, I noticed a lot of similarities,  but there are a few differences, both good and bad, to take note of.  There are different features between the two, though for the most part they’re pretty similar.

Continue reading “Working with Away3D”

AirTran: EveryFlight.com

airtran_banner

I’m a little behind here, but here is my latest project from Firstborn: AirTran EveryFlight.com, where I was the front-end developer for the project. We worked with Cramer-Krasselt in order to bring this site to life.  AirTran is a small domestic airliner, and they wanted to run a promotion to see what people wanted on every flight.  So we built a site to collect ideas, then let people vote on them and see how each one ranked on a state and national  level. The site only ran live for about 4 weeks until the winner was announced which happened to be Wi-Fi. You can see the old phase 1 site persevered here on Firstborn’s portfolio. It was a really cool project to work on, especially once it launched to see the suggestions come piling in. Our back end developer for the project, Wes Grubbs, built the database and admin tools, and we used AMF php, which provided to be really simple and easy to use.  And as always, I also got to do some nifty features on the site.

So the first challenge was that we wanted the user to be able to write in their suggestion on one of the cards and actually have a pencil do the writing. There were two important parts to this process. The first is getting each letter traced out. The basic methodology behind this is that we will create for each letter a set of points on a path (anchors and control points for curves) and then use that path to mask out the actual letter. By drawing that path over time, we can create the illusion of the letter being drawn in as it is being reveled. The second part is having a pencil follow the letter, which is simple since everything is done by numbers and the drawing API, so from the current path being drawn we can grab the ‘end’ of it and just have an object track that point, thus having it follow the path being drawn in and the illusion that the pencil is drawing the letter. To create the pencil, I used FIVe3D.  Mathieu had created a pencil for the M&M’s Join the Hunt site, so to avoid having it look too similar I didn’t bother using his model/code for reference, I just built out my own (plus it’s more fun that way).

pencil

In order to get the paths for each letter, I created a tracing tool. The tool allowed me to add points and make a path, as well as play with the curves and thickness of the line. Additionally, I added the feature that would allow the pencil to be “picked up” over certain points, meaning it wouldn’t be drawing for that segment (shift+click an anchor point). That is important for drawing letters that have different individual strokes, such as F, where when the pencil was moving I wouldn’t want to unmask a section of that letter as the pencil crossed it to get to another location. Once each letter is traced, it can be saved out as XML which is imported to the site and parsed into usable information.

See the letter tracing demo
See the letter writting demo

Another thing that was kind of interesting, although at this time I don’t have a demo for, was creating the rollover for the stack information. One of our newly hired 3D/Motion Designers, Brett Swanson, first modeled the stack to resemble the initial comps our designer Verena did. In order to make the cross-section, I first made a black and white image of the stack. The black being one side of the paper, and white being the other. Where the two colors met is the corner. So in Flash when the user rolls over the sack, I look across the horizontal strip of pixels from that mouse point and look for the area where white meets black, and I know that’s the corner. I can then do some masking, then calculate the rest of the points around it to create the cross-section plane, which is not 3D in anyway. As for the animation of the card being pulled out, Brett created a static animation that we imported as a PNG sequence, then position it to where the mouse click is, and scale it accordingly to be the correct size. Due to perspective, it doesn’t always match up. But since it is such a quick animation, we can fake the perspective by just slightly rotating the animation a little so that looks like the perspective matches up. As the animation plays, it rotates back to zero and scales back to the default size, and then is swapped out with the flipping animation which is dynamically done in five3D. As I always say, it’s all smoke and mirrors.

map

(images after the jump)

Continue reading “AirTran: EveryFlight.com”

Controlling AS2 swfs within an AS3 application.

Sometimes you’ll need to load an AS2 swf into your AS3 project, and this seems like it can be a nightmare. And it can be, depending on what it is. You loose some functionality, such as loadMovieNum and getURL. On top of that, you can’t control the movie, as in you can’t access any public functions. There can be a workaround, though. The trick is to write an AS2 shell that acts like a bridge. You’ll load the AS2 swf into that shell, and communicate with the swf from that file, then communicate to the AS2 swf  bridge from your AS3 project via localConnection. This comes from a problem I recently was required to tackle, so I fiugred I’d share my solutution.

In this example, we need to load an existing game written in AS2 into an AS3 website. We do not have any access to the source files, just the compiled swf, which needs to be properly disposed in order to stop its audio channel. The solution is to create an AS2 shell that can load and unload the game, and then communicate with the shell via localConnection.

Step 1. Setting up the AS2 shell

Make a new AS2 targeted flash file and on the stage create a new empty MovieClip and give it an instance name, in this case container_mc.

Now as much as this hurts, click on the first frame and open the ActionScript panel. Yes, we’re going to add some very simple code to the timeline. First we want to load the game using loadMovie, targeting the container_mc that we created on the stage. This will load our file into this empty MovieClip so we can easily remove it later. Since we’ll be bringing this into and AS3 swf, we cannot use loadMoiveNum. The one line of code should look like this: loadMovie(“game_as2.swf”,this.container_mc) .

Step 2. Setting up the LocalConnection listener

This file is basically going to wait for a command from a localConnection at some point, so we’ll set that up immediately after loading the movie. In this case, we named the connection ‘gameBridge’ and will need to use that string in out AS3 swf in order to sync the two together. The code looks like this:
var lc:LocalConnection = new LocalConnection();
lc.connect(“gameBridge”);

Now we need to set up a method that will be called from AS3. In this case, it’s a dispose method. In order for the method to be called, it needs to be a method of the localConnection, so the full function name is lc.dispose = function():Void. Remember that lc is our localConnection object, and that in AS2 the datatype for void is capitalized. All we want to do in this function is kill the game, so we’re going to unload it and kill the connection. Just two lines of code, which looks like this:
lc.dispose = function():Void {
unloadMovie(container_mc);
lc.close();
}

That’s it for the AS2 side.

Step 3. Setting up the load in the AS3 project

We load in the AS2 swf just like we do an AS3 one, the only difference is that instead of it being of type MovieClip, it will be a special class called AVM1Movie, which stands for ActionScript Virtual Machine 1 MovieClip. Remember, we’re loading our shell we just made, not the game. So my load method looks like this:

private var game:AVM1Movie;
private var loader:Loader;

private function loadGame():void {
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, hndlGameLoad);
loader.load(new URLRequest(“gameshell.swf”));
}

private function hndlGameLoad(e:Event):void {
game = AVM1Movie(loader.contentLoaderInfo.content);
addChild(game);
}

In this case, the game was set to a frame rate of 30fps, and my app is running at 71fps. That means that the loaded game will now run over twice as fast. There’s not much we can do about this, but we can set the overall stage frame rate to match the loaded game, and when the game is unloaded, just remember to set it back. It’s just one line of code: stage.frameRate = 30;

Step 4. Setting up the LocalConnection call method

The last thing to do is call the AS2 swf and tell it to dispose when we need it to. We just set up a new LocalConnection object and pass it the name of the connection we set up in the AS2 swf and the method that we want to call. Looks like this:

lc = new LocalConnection();
lc.send(“gameBridge”, “dispose”);

And that’s about it. Pretty simple and quick way to load and still be able to dispose of an AS2 file.

FITC Toronto 2009 Presentation

FITC Toronto 2009 Banner

It gives me great honor to announce that this year I will be giving a presentation at FITC Toronto alongside Firstborn coworker Jens Fischer. I’ve attended FITC for the last three years, and each time I’ve always enjoyed it. Shawn Pucknell has always puts together a great program with the best of the best of the Flash and web community. I have always found great ammount of inspiration from FITC, I always leave feeling creativtily renewed, so I really hope that this year I can be amoung one of the presentors that inspires others.

Our presentation is about the blending of 3D with web to create an engaging experience. We’ll talk about the techniques we have used in recent projects at Firstborn (such as Puma Lift, which launched on this past Friday), as well as technologies and techniques that we’ve just played around with. Here’s the writ-up as it is found on the FITC website:

Dimension Wars. Bridging the Gap Between 2D and 3D in Flash

The focus of this presentation will be the techniques used in creating 3D experience in Flash. We’ll look at different means of accomplishing this; whether it is creating a fully 3D environment right in Flash, combining pre-rendered sequences within a 3D environment, or even faking the 3D completely. We’ll be showing techniques that we have used in projects such as Sport Chalet: The Mountain, M&M’s Join the Hunt, Puma and XM Wild Ride. In addition to these, we’ll also be showing behind the scenes prototypes and demos, as well as internal experiments from our Firstborn Experiment Lab.

We will cover techniques from projects that use alternative means of creating 3D objects (how we created the mountain for the Sport Chalet site, first as based off of noise, then later from a VRML file), compositing rendered stills into a 3D-like environment (M&M’s), displaying 3D assets in a non-3D environment and adding 3D as a detail or interactive component in the Flash experience.

It’s not too late to buy tickets and attend. For more information about tickets, travel, etc, check out the FITC website.

The Mountain in .NET Magazine

Sport Chalet: The Mountain was featured in April’s issue of .NET Magazine, which is called Practical Web Design here in the ‘States. I was just short and simple write up in their showcase gallery section. It was very cool to see a project I was lead developer for in print in an international magazine. Here’s the short writeup:

TM Advertising approached Firstborn to design
a microsite for its new retail client, Sport Chalet.
Firstborn’s solution used an entire mountain motif
as the gateway for the content. The mountain
itself is modelled in Cinema 4D and exported into
Papervision3D. The result is an exciting and vibrant
interface that provides users with access to winter
apparel and equipment. The mountain serves as a
showcase for brands and their sponsored athletes.
You can check out the rider page of athletes and
see them model their sponsored gear through
video clips as well. Papervision is best used in
conjunction with some Flash, good photography
and web video. The Mountain has an excellent
dose of each.

net1.jpg

net2.jpg

net3.jpg

Bitmap Filter Adventures

I ran across two little bitmap related issues in Flash during my last project (should be live by end or March) that I’d thought I share.

The first issue is regarding layers of transparency. Sometimes in a sprite I’ll have multiple shapes layered on top of each other, or various layers of shapes drawn. Now if you change the alpha of that sprite, it will affect all the objects it contains. So, for example, if in my sprite I have one sprite with contains a red rectangle, and on top of it there is another sprite with a blue circle, if I change the alpha of the container sprite, you’ll be able to see though the blue circle since it’s alpha is also being changed. If I want the whole thing to fade together, so I don’t see though the individual parts, I’m out of luck.

So I figured I could use cacheAsBitmap to essentially flatten the sprite, so when the alpha is applied it would be applying it to an image. However, this doesn’t work. Obviously, I could just do it manually and draw the contents to bitmapdata, and swap it out whenever I need to do a fade. I’d like to avoid that as much as possible, so I figured I would try a last ditch attempt – using a empty filter. Basically, if I put a blur filter (or any other) on the container sprite that I am applying the alpha change it, Flash will automatically cache it as a bitmap. Logically, this should be no different than just setting the cacheAsBitmap property to true, as I had done before and failed. However, this works. I don’t know why, but somehow setting a filter to the sprite forces it to cache differently then just using the property. Below is an example (The bars at the top are to show a side to side comparison of each color for each object. It shows that the alpha affects the colors the same way for all of them, since it appears as an optical illusion that the one on the right is different)

[flash http://testing.eric-decker.com/layercache/layer_alpha.swf w=550 h=400]

The other thing I’ve run into before, and I’m sure countless others have to, is applying a filter to an object which you have drawn something round in. What happens is that the right-most one or two pixels of the image get cut off.  It looks like Flash is converting the object to a bitmap (which we know it does), but is not taking anti-aliasing into account when setting up the bitmapdata width and height. The solution I used to get arround this issue is when drawing my shape I add a 2px transparent line around it. You won’t see the line, and since it’s a stroke it shouldn’t affect the active mouse area if the target is a button. If you’re drawing a shape  that already has a stroke around it, you’ll either need to draw it twice or do something to give the are just that little extra bit of padding on the edges. Here’s an image to help illustrate what I’m rambeling on about:

bitmap_circle_filter_bug.jpg

Pixel Bender Filters

I started to play around with pixel bender a few weeks ago, but didn’t have much  time to really accomplish anything interesting. However, I came across the opportunity (or rather excuse) to use it to whip up a quick filter for my current project. Basically, we have a bunch of transparent png images of people or objects. In the images, the figures or objects cast shadows, but the shadow’s transparency is not taken into account (think of it more like a .gif where transparency is either true or false rather than smooth). So I wanted a way to take a selection of the image, and basically have it translate the brigtness value to alpha. The result would be similiar to using a multiply blend mode, if blend modes could be used with only one layer. Anyways, I couldn’t find a way in Photoshop to accomplish the effect to my liking, so I wrote a super simple pixel bender filter, imported it, and voilà, I had exactly what I needed. Pixel Bender is going to be a great too for player 10, but I think there could be a lot of interesting and practical uses for it even outside of Flash.

Here’s the filter (right/option click and save as, I guess Firefox and the like recognize it as a text file) if you’d like, as well as an image that hopefully clarifies what I was trying to describe above.

bender_example.jpg

Sport Chalet: The Mountain

sc_banner.jpg

So I just recently finished up a micro site for Sport Chalet, a California/West Coast based sporting goods boutique. Sport Chalet came to Firstborn wanting to promote their winter line of snowboarding and skiing equipment and apparel. To help, they also got a bunch of professional snowboarders and skiers to help promote the site by modeling with equipment and by giving interviews. Our goal was to figure out a way to display all these professionals as well as just models in an interesting way. The concept we arrived at was to create a 3D mountain and populate the face with hot spots that would represent one of the sixty or so people. After selecting a person, the user is taken to a ‘rider page’ that has motion tracked video with target points that describe what that person is wearing.

The first challenge was to create the mountain in 3D in Flash. Originally we were going to create the mountain based off of a grayscale depth image, where the height of the 3D mesh would correlate to the brightness value. However, this did not offer us as much controll over the final result of the mountain. Instead, we decided to model the mountain in an external editor and bring it into papervision. Our first inclintion was to use collada or md2 format. However,  I was unsure of how much accessesability I would have to the mesh, as we would need to make it interactive. In fact, since each triangle would be it’s own object it could not be appart of one mesh, so rather the mountain would be a collection of independent objects. Additionally, the art director was using Cinema 4D which at the time did not support collada export. So it seemd to me that the only option left was to make my own importer from Cinema 4D. The importer I created uses VRML files (.wrl) which are ascii text based files that contain an array of point and faces, as well as UV coordinates for texturing. It’s actually a simple process to rebuild all mesh, except for a few tricks such inverting the Z-axis (papervision’s is opposite to Cinema’s) and reversing the normals since they all come in backward. Since I wrote my own importer, I knew exactly what was happening, and thus had totally controll over how the polygons are created and handled, therefor making the interaction process that much easier. Here are a few steps/examples of creating the mountain:

Example 001:  Bringing the object in directly from Cinema (the color is from its original material) and showing the wireframe as well.
Example 002:  An example of adding a bitmap texture to the object and have it retain proper UV coordinates.
Example 003: Adding a color gradient based off of each triangle’s centroid position relative to the entire mesh, as well as cropping polygons on the lower portion to remove the rectangular base
Example 004: Adding some effects such as Flat Shading (which had a bug that I needed to fix first) and subtle glow.

Another interesting process was creating the tracked videos. The site contains 78 tracked videos, which for each we needed to do the keying, color correction, and finally motion track each one. After each video was tracked with one or several trackers, we simply copied the keyframes right from after effects and ran them though a custom parser we built to convert them into XML. You can see the result on the site or in this demo.

So please check the site out, hopefully you’ll enjoy it, as it was pretty fun to make. There’s a contest you can enter as well, but you have to be able to get to one of the Sport Chalet stores, and they’re only located around Southern California / west coast area.

sc_1.jpg

sc_2.jpg