Everyday 3D

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

PDFBook3D, a 3D flipbook engine


PDFBook3D is a Flash application that allows to transform a PDF document into a 3D model, that later can be viewed pretty much like a real book. The product was just released by Powerflasher, and I was involved in creating the front-end 3d Flash part of it.

This application belongs to the family of flipbook engines. I am sure you have seen the classic 2D version of a flipbook at least once. It is widely popular around the web! PDFBook3D replaces this classic piece with a more accurate and realistic 3D version of the effect created with AS3Dmod bend modifier. The bend modifier allows to create paper simulation in Flash, which is something I already posted about back in November.

The application has a rich set of configurable properties, including dimensions of the book (for non typical page sizes) and a number of quality settings to get a decent framerate on slower machines as well. The Powerflasher team created an admin interface to generate 3d books on the fly. You can see it in action here. The product functionality also includes links editor and video embedding. If you are interested in more information please refer to the Powerflasher Solutions site.

PDFBook3D is also my first commercial project made using Away3D. There are a few features in Away3D that made me choose it, but mostly it was the curiosity to try "the other" engine. I must admit Away3D turned out to be pretty cool!

It is most famous for its advanced features like normal maps, path extrudes and bones animation. However, this project does not rely on those advanced functionalities. Most of what I used in here is pretty basic, but still I was able to find some cool stuff.

One very useful feature is being able to assign back material to planes. It might not seem like a huge thing, but since it is used to create the flipping page, it helped me a lot. Actually any mesh in Away3D can have a back material assigned to its faces using the back property of the class:

  1. myMesh.material = new WireframeMaterial(0xff0000); // classic front-side material
  2. myMesh.back = new WireframeMaterial(0x00ff00); // back material

Notice, that it is not the same thing as having a double sided material - that is, the same material used for both sides of a face. In this case - one material is used for one side, and a completely different one for the other. This is why it was perfect for creating a page of a book.

Another cool feature of Away3D is triangle caching - it is a built in functionality, that doesn't require any extra coding and it can give a significant performance boost. Thanks to triangle caching, whenever the page flip animation is on, the rest of the book that does not move at this moment is not re-rendered at each frame. A similar optimization can be achieved in Papervision3D using render layers, but it's not as easy to use.

Last but not least, I'd like to thank Fabrice Closier from the Away3D team for support and feedback during the project!

3D experiments with Flash Player 10 and AS3Dmod

Flash Player 10 3D experiments

Demos: [ 1 ] [ 2 ] [ 3 ] [ 4 ]      Flash Player 10 required (obviously)

Flash Player 10 has been around for a few months now. As most of you know, it brings some native 3D support. It's not as robust as Papervision3D or Away3D, and in fact was not designed to compete with those engines. Rather than that, it contains classes that perform 3D calculations and allows basic 3D manipulation of display objects.

The last months I focused on catching up with 3D math. I ordered a book called "3D Math Primer", which explains in detail all the vector and matrix operations involved in 3D graphics. Even though the examples are in C++ I recommend this book to anyone doing 3D in Flash. The authors made a great effort to explain the subject with clarity. It worked pretty well for me and I understand the math behind 3D much better now.

Both Papervision3D and Away3D were created so that we don't have to deal directly with 3D calculations. If you are working on a project that involves non-trivial 3D and has a deadline, it's better to choose one of those engines instead of "pure Flash Player 10".

However, if you just want to do some casual experiments and learn something on the way, FP10 is great. It offers a small number of tools, focused around Vector3D and a Matrix3D classes. These classes offer low level functionality, so to use them one needs to understand what's going on under the hood. This is a great way to learn!

Then I had this idea to port AS3Dmod to Flash Player 10 and try to run the modifiers on objects created using FP10 3D classes. It turns out it was not so difficult. Instead of rendering textured 3D objects I just render a single pixel for each vertex. Thanks to this I get a relatively good performance even with as much as 8000 vertices. I found that a modifier applied to such a large amount of vertices, gives interesting visual effects. I even wrote a very simple Wavefront OBJ importer, and I could import the 3d pants model from one of my previous posts to render them in Flash Player 10.

All my previous demos with AS3Dmod involved pretty small amount of vertices - most often no more than 500-600. At this level the performance of the modifiers was not a problem. But with 8000 vertices the modifiers start to have an big impact on the frame rate. A Perlin modifier alone takes 4-5 FPS, which is quite a lot and it got me worried. I believe code optimizations are in order. An interesting solution could be to implement the modifiers as a Pixel Bender kernels. Anyway, I need to do some more research...

In the AS3Dmod SVN you'll find the FP10 branch. The main difference between this version and the trunk is that it uses FP10 built-in Vector3D and Matrix3D classes as well as Vectors instead of Arrays. The sources for all experiments mentioned above, including a simple AS3Dmod plugin for FP10, are available here.

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:

  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:

  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:

  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.

  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!

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!

Paper simulation in with AS3Dmod and Away3D

Since I released the bend modifier a lot of people have been asking how to bend an object not only along one of its axes, but along any angle. That was clearly a feature missing, but I also didn't have a clue ho to do that. Now, a after a good few days of struggle, and with a little help from my friends - here it is.

The Bend class now takes 3 arguments in the constructor, the third being the angle at which the bend is executed. Please mind, that this argument expects an angle in radians. In the code it looks like this:

  1. var mesh:Mesh = [a mesh]
  2. var stack:ModifierStack =
  3.     new ModifierStack(new LibraryAway3d(), mesh);
  4. var bend:Bend = new Bend(1, .5, 1.2);
  5. stack.addModifier(bend);
  6. stack.apply();

Of course, there is also a getter/setter for the angle, which allows to change the value dynamically, and to use libraries such as Tweener to animate it.

The Bend modifier is now part of the AS3Dmod library. Since AS3Dmod is cross-engine, the above demo was done with Away3D, but of course, the same functionality can be used with other engines, including Papervision3D.

For those of you who remember the initial bending demo, I used a 100$ bill as a graphic element then. I thought it would fun to be consistent and to stay in the American theme. Therefore, this time you can play with the Declaration of Independence. Fans of "National Treasure" should be delighted.

As usual the sources are available and you can get them here. I hope you like the demo and that you will find the code useful. To compile it you need the latest versions of AS3Dmod, Away3D and Tweener libraries.

Update: what’s up with AS3Dmod?

A few weeks passed since I wrote about the AS3Dmod library and released an initial version of the code. Some new stuff has happened since, so here's an update.

First of all AS3Dmod has a new team member - Makc. Makc has been involved in several AS open-source projects, most notably Sandy3D. You can read more about Makc, here, where you will also find some cool Flash experiments.

The code has also evolved, and was moved to a modest 0.2 version. The most important changes are some fixes in the imports that prevented the compilation of the project so far.

The 0.2 version has 5 new modifiers: Bloat, Twist, Taper, Skew and a UserDefined modifier that allows to create custom vertex manipulation and easily integrate it into the stack.

Other then that, there is now an ANT script that allows to compile the demos for all 4 engines, and also to generate API Docs. Of course the documentation is ever evolving, but the latest version is always available here. Please note, that API docs are synchronized with the contents of the SVN repository. The zipped sources available on the project home page are there for reference, but they quickly become outdated.

Last but not least, there already are a few demos that use AS3Dmod. I allowed myself to gather a short list of what I found out there:

Thanks to everyone! We will try to put in more and more features, document the code and also create a tutorial, so stay tuned.

  • FATC2011

  • FITC2011

  • FITC2010

  • FITC2010