Everyday Flash

Creative use of technology // A blog about 3D Flash and Actionscript by Bartek Drozdz

FOTB’09 presentation: 3D Bowling demo

Video of 3D Bowling Demo, Flash on the Beach 2009

UPDATE Nov 2009 There is a better quality video posted by John from Flash On The Beach. It is available here: http://vimeo.com/7292505.

As I promised during my "3 minutes" in Brighton, I publish all the sources of my presentation. I added some comments in the code and removed the part with the slides.

Here's also the demo and a video of the mini-session. The demo is pretty rudimentary - I made so because I wanted to keep things simple during the presentation. I hope that it will be a solid base for someone who wish to create a full featured bowling game in Flash.

There were a few other implementations of a bowling game in JigLibFlash and Papervision3D. Initially, guys a Blitz Agency published a few interesting experiments with JigLibFlash, including a simple bowling simulation. Devon O. Wolfgang has written a great tutorial about building such a game on Tech Labs - be sure to check it out. I found it only after the presentation and since the tutorial explains a lot of things in details I felt like I was reinventing the wheel here. But hopefully there are still a couple of things I can add.

Thanks to the new plugin API we developped some time ago, setting up a scene with JigLib and an 3D engine has got a bit less complicated. However, tweaking the engine can be a hell. Here's a few things I found out:

1. Simulation speed

When you create the physics engine instance, the default speed of the simulation is 1. This is very slow and unrealistic. It will look much more natural if the speed is increased. Beware however - at higher speeds the collision detection system can be very inaccurate and result in objects running through each other without any collision being detected. I don't think there is a single setting that works fine in every situation, but for this case 9 worked fine for the regular speed simulation, and 2 for the "slow speed". You should always try different settings.

2. Mass

Each rigid body has a mass property. It's easy to forget about it since it has a default value and it never complains if you don't change it. However, setting the masses right is crucial for a realistic simulation. In real world object have different masses, and so they should in a simulation. This is particularly important for a bowling game, where the ball is pretty heavy and the bins are not (I guess... has anyone ever had a bowling pin in his hands?) The trick is that the masses are relative to each other, so the more different objects you have the more you need to tweak the masses to get the results right. Also remember the effect of any forces applied to an object is related to it's mass.

3. Physics material

Each rigid body has a property called material which is an instance of the MaterialProperties class. It has two properties: friction and restitution. I found out that playing with this values has a quite big impact on the simulation. Ex. setting a high value of the restitution results in the object becoming bouncy - I used this for the ball in my older ping-pong example. In the bowling demo I used lower friction on the ball to make it slide more - just as a real bowling ball does.

4. Object rotation

Once a DisplayObject is wrapped into a physics rigid body you can't rely on it's rotationX, rotationY and rotationZ propeties anymore - because they are not being set. The physics engine sets the transformation matrix directly on the DisplayObject, so if you need to check it's rotation you need to extract it from the matrix. Fortunately, there's an easy way to do this:

Actionscript:
  1. var p:DisplayObject3D = physics.getMesh(pins[i]);
  2. var h:Number3D = Matrix3D.matrix2euler(p.transform);
  3. // h.x is the rotationX of the object in this case.

5. Object activity

As a result of multiple forces being applied to an object and multiple collisions sometimes the objects are left in a state where the shake a bit endlessly. This can also happen when the objects are initially positioned. Calling the RigidBody.setInactive() will fix that. And you can call more than once.

Important conclusion: tweak, tweak, tweak...

It is generally agreed that hardcoded ("magic") numbers are not a good coding practice. However in 3D animations, and especially with physics the important thing is not the beauty of the code, but the what you see at the end. If you browse the source code from this demo you will notice that I not only hardcoded a lot of values, I even left ugly lines like that:

Actionscript:
  1. force = (speed == 9) ? 5000 : 3000 * 8 * 4;

In fact this is what I like the most in doing all those demos and experiments - the moment when code stops being just a list of instructions for the machine and becomes an art of making things look good by adding little tweaks here and there. If you tend to write very clean code and use all possible standards and conventions, from time to time make it ugly... you'll see how good it feels :)

I hope that this few tips will help you with your next JigLib project!

Last but not least, I'd like to say thanks to everyone who woke up early to see the Elevator Pitch session. It was a great experience being there and talking to you. The Brighton Dome packed with people can be intimidating and 3 minutes is not much time, so there was no place for mistakes. Fortunately, the FOTB technical crew made it all seamless. Great job guys!

Finally, I would like to give a special thanks to John Davey for inviting me to Flash On The Beach and for making this great conference happen!

Hope to see you next year!

Exploring JigLibFlash – the AS3 3D physics library

JigLibFlash is a new library for 3D physics simulation in Flash. It is ported from a C++ open source engine. It's been around for a few months now, and if you haven't heard about it, you need to catch up!

I believe physics simulation is the next step in the Flash 3D world, so I got very excited when Ringo from FlashBookmarks invited me join the JigLibFlash team a couple of months ago. One little problem: I am perfectly lame when it comes to physics... In this situation, the only logical thing to do was to join the team and learn all the stuff I need to know about it in the meantime. Sounds like a challenge!

Now I slowly fill my knowledge gap. However, I also managed to do some actual work on the library. Together with Reyco we remodeled the API. We started by making it more Flash developer friendly, less C-style and more AS-style. All the methods start with a lowercase letter now, and instead of having to set the position and rotation using vectors and matrices, the new API offers simple getter/setters for properties like x/y/z and rotationX/Y/Z just like in Papervision3D or in the new Flash Player 10 API.

Last but not least, we also created a plugin system to easily integrate JigLibFlash with the popular 3D engines like Papervision3D or Away3D. Now there are specialized classes to interact with those two engines and it should be pretty easy to create a plugin for another engine if one needs. If you worked with AS3Dmod you should notice that the concept is similar to the plugin architecture in there. Update: I just saw in the sources that someone already created a plugin for Sandy3D.

To learn more about these changes you can refer to the tutorial I wrote which is posted on the projects wiki page. Reyco also wrote a great article about this on his blog.

The demo above is my first little experiment with JigLibFlash and Papervision3D. My idea was to integrate a Collada object with the physics system and to add some interactivity to it. I extended the Mouse constraint class created by Reyco to control the racket. I encountered some problems with stabilizing it in the long run. After having bounced the ball a few times the racket starts to rotate as if the constraints were broken... well, I still need to do some research on that.

Source code. You can browse the sources for the demo here.

Links. Some links to get you started with JigLibFlash:

Mustang goes into augmented reality

Augmented Reality (AR) generated so much buzz in the community in the last few weeks that I had to give it a try!

I suppose most of you know what AR is, however just in case you don't, here's some basic facts from an Actionscript developer perspective: augmented reality uses pattern recognition to render 3D graphics on top of a video display. A pattern, also called marker, is a rectangular shape that you need to print and position in front of your camera. The stream from the camera is analyzed and the marker is used to determine the coordinate system of the world captured by the camera. This coordinate system is passed to a 3D engine which renders objects on top of the video image. Pretty simple, huh?

As far as Flash is concerned, the API for augmented reality is called FLARToolkit, which is an AS3 port of library written in Java and C done by Saqoosha. If you want to know more about this project, here's a great intro to the subject written by Mikko Haapoja.

In most of the cool AR projects I have seen so far [1] [2] the user is supposed to hold the marker and move it around in front of the camera and the 3d object follows the marker. I had a slightly different idea: why not just leave the marker and the camera in one place and use your keyboard to move around the 3d objects?

Some time ago I posted a demo featuring a Mustang that you could drive around a desert scenery. I thought it would be cool if I could now drive it around my bedroom floor. I was very surprised how easy it was to integrate my model with FLARToolkit and Papervision3D. All I had to do was to scale and rotate the model a bit and that's it!

The above video shows a recording of the experiment. If you have a webcam you can try it yourself. To do this, follow this instructions:

  1. Print the marker (You can alternatively display it on your iPhone)
  2. Click on this link, and choose "Allow" from the security dialog
  3. Point your webcam so that the marker is fully visible
  4. When the car is loaded (~250kb) it will appear on top of it
  5. Use cursor keys to drive the car and CTRL key to apply hand brake
  6. Have fun!

If you want to dig further here's the source code. The whole magic is in the FlarMustang.as class. The rest of the classes are an adaptation from the FLARToolkit basic example and some classes I used for the Mustang demo.

Unrelated note. In case you are reading this post in your RSS reader, you might not have noticed that I redesigned the blog. It's good to change from time to time! Among other stuff, there's a new list of previous 3D experiments and new links in the blogroll, so take a look.

Car simulation with Maya & Papervision3d

Mustang GT | Maya, Papervision3D

Take a test drive with a powerful Mustang GT in a desert scenery! This demo features a car model imported from Maya into Papervision3D. It uses some home-made physics to simulate the car movement and a couple of new AS3Dmod features to manage the model (more below).

I created this demo together with Krister Karlsson. Krister is a 3d artist working with Maya and founder of Modesty - a Stockholm based creative agency. The (super)low poly Mustang used here is based on a concept model made by Krister that was later used to create an actual car! You can read more about this project here.

Working with this demo has been an occasion for me to explore all the spectrum of Flash 3D related development, like importing and managing a complex model, adding interaction and scripting car physics. All this with a reasonable performance in mind, of course.

There is quite a lot of source code involved in this demo. I won't be publishing it all as parts of it are rather messy. Instead I'll focus on some particular problems I've encountered and solutions to them.

Pivots. I can't tell if this is a problem of the Maya Collada Exporter or if we have been doing something wrong, but the fact remains that moving the pivot point of an object in Maya is not reflected in Papervision3D. Instead, all pivot points default to the center of the whole object when the DAE file is imported.

To fix it, I had the idea to move the pivot point in Actionscript. Unfortunately, there isn't an easy way to do that in Papervision3D. This problem is generally solved by putting the DisplayObject3D inside another and move it in relation to its parent. But when all the objects are part of a structured DAE it becomes quite painful and requires additional steps. So instead, I wrote a modifier that takes care of that. It's called Pivot, and this is the way it works:

Actionscript:
  1. var do3d:Cube = new Cube(materials, 200, 200, 200);
  2. var stack:ModifierStack = new ModifierStack(new LibraryPv3d(), do3d);
  3. var pivot:Pivot = new Pivot(-200,-200,-200);
  4. stack.addModifier(pivot);
  5. stack.collapse();

This piece of code will move the pivot point -200 units on all 3 axes. In case of this cube it will end up in the lower left corner. It does it without creating any additional display objects, but rather by offsetting all the objects vertices.

Please note that I collapse the stack after applying the pivot. Otherwise the pivot would be moved at every call to stack.apply(), which is not what we are looking here for.

The problem with the Mustang model was that all 4 wheels were rotating around the center of the car rather then around individual centers of each object. I needed to move the pivot point to the center of each wheel. I thought that moving the pivot to the geometrical center of the object is a typical thing to do, so I create a shortcut method for it:

Actionscript:
  1. pivot.setMeshCenter();

Calling this function automatically sets the pivot point in the geometrical center of the mesh. At this point I thought I was done with the wheels, but there was one more problem...

Roll & steer. I think anyone who ever created an interactive 3d car model must have faced this one. A wheel rolls around the Z axis and the steering goes along it's Y axis. So, the first think that came to my mind when I started to code it was:

Actionscript:
  1. wheel.rotationZ += 10; // roll 10 degrees
  2. wheel.rotationY = 30; // turn 30 degrees

While this code seems perfectly logical, when put in action things go wrong and the wheel starts to act like if the car had undergone a severe crash.

The reason for this is that once the wheel rotates along the Y axis (turns), the Z axis is no longer the right axis for roll. The correct axis would be the Z axis rotated 30 degrees on the XZ plane.

Again, a solution would be to enclose the wheel into a parent DisplayObject3D and then use the parent to steer and the child to roll. However, since I had already an elegant solution for the pivot I didn't want to clutter my model with an additional set of elements for this one either.

There comes the Wheel modifier. Apply it to an object - typically of a cylindrical shape - and use its speed and turn properties to manipulate the wheel.

Actionscript:
  1. var do3d:DisplayObject3D = dae.getChildByName("wheel", true);
  2. var stack:ModifierStack = new ModifierStack(new LibraryPv3d(), do3d);
  3. var wheel:Wheel = new Wheel();
  4. stack.addModifier(wheel);
  5. ...
  6. // Please mind that it expects values in radians
  7. wheel.turn = Math.PI / 6;
  8. wheel.speed = 5;
  9. stack.apply();

Internally the modifier applies some math to rotate the roll axis according the the current turn value so that everything looks fine and you don't need to worry about it ;) Read the documentation of this class for more information.

All this new features are available in the latest SVN revision of AS3Dmod. So, go ahead and grab it later. But first, enjoy your ride!

Making things walk in Flash 3D

Walk cycle in Papervision3D

An Actionscript-based 3D bone system is something I wanted to do for a long time, but I couldn't figure out how to approach this problem for several months. A few days ago, I finally made a breakthrough. Here's a first demo I quickly put together: a 3D walk cycle.

So far the only way to have a walking character in Flash 3D was to create an animation sequence in a 3D editor and export it as an animated DAE and/or use Cast3D. For sure, this method allows to achieve awesome results, but it is not nearly as flexible as being able to control the animation directly from Actionscript.

So, how does the above demo work? First of all I created a model of pants in Blender. This is the 4th model I ever did with Blender so it not perfect, but is good enough for the job. The important part is that both legs and the waist form a single mesh.

After I imported the model into Papervision3D I applied several Break modifiers to the model. The Break modifier is a new class I wrote for AS3Dmod and is of key importance for this demo. In brief, it allows to apply rotation only to a group of vertices while leaving the rest untouched. The resulting deformation makes the mesh look like it was broken, hence the name.

I created a modifier stack and added 4 Break modifiers to the pants. One for each tight, and one for each knee. The angle for each of them can be modified separately, which allows dynamic animation.

You probably wonder how I did indicate which vertices belong to which part of the mesh (waist, thigh, calf) and how I even know where those parts start or end on the code level. That is crucial in creating an armature and it is also the tricky part. Most of the 3D IDEs, like 3Dsmax or Blender have some kind of visual interface that allows the user to select vertices and attach them to a bone. In AS everything is code, so this is a challenge. I must confess that for this demo I hardcoded some values and did some assumptions to make it work, but I think there is a way to make this task relatively easy or at least possible to apprehend.

In the long run, it would be cool if bones could be exported from 3D IDEs and exposed as objects in Actionscript. As far as I know, there isn't anything like this available for the moment. Away3D supports collada bone animation but, despite its promising name, it serves a different purpose (correct me if I am wrong.)

Let's go back to the demo. Once I had the Break modifiers in place and applied to the correct areas of the mesh, the rest was rather easy. To create a proper walk cycle, I just took Keith Peters' book "Making Things Move", Chapter 13 on Forward Kinematics, and I adapted the code from the examples.

In case you don't know that book, I would strongly recommend getting it. It contains all the essential stuff you need to know, if you want to call yourself a serious AS3 developer. I never leave home without it! There is also a sequel, with stuff for Flash Player 10.

This walk cycle is only a first step to create a bone system in AS, but I wanted to share it with you without spending another few months making it fully featured. Break modifier is available in the latest AS3Dmod SVN repository. I should warn you however that this is a very early version, not really usable for the moment.

Of course, updates are coming so stay tuned!

The AS3Dmod tutorial

The AS3Dmod tutorial

I did some research in the blogs and on Twitter, and often when someone mentioned AS3Dmod, the recurring theme was the lack of documentation. Yeah... but creating proper documentation is such a difficult task!

First of all, it's hard to find enough free time. Then, even if you find some, most of us, including me, will always find it more fun to write code instead. Eventually, I profited of the calmer period in the last 3 weeks and made some progress with that. The result is the AS3Dmod tutorial.

In the tutorial you will find answers to the following topics:

  • how to integrate AS3Dmod with the Flash 3d engines
  • how the modifier stack works
  • how to create and apply modifiers
  • how to animate the modifier properties
  • how to use the collapse feature

Beside the tutorial there are API Docs available for some time now.

Another thing are simple interactive demos for each modifier. So far I created it for one: Skew. You can view it here. The demo allows to see all the properties and features of the modifier in action, instead of explaining it in writing. If this concept gets some positive feedback, I'll try to do more of those.

Hope you will find all this useful, and remember that feedback is very welcome (and much needed). And of course Happy New Year everyone!



  • FITC10