Everyday 3D

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

Modifiers in Unity3D

Ringo from FlashBookmarks asked me if there were modifiers similar to AS3Dmod in Unity. I searched for something similar some time ago, but didn't find anything interesting.

However, when I was starting C# scripting, I ported two of the modifiers from AS3Dmod - Bend and Twist. So I thought to share them with everyone. Don't expect much, it's not the full library, just two classes. If I have some free time, I'll look into how to implement stacking, since for the moment you cannot apply two modifiers to the same object (the second one won't have any effect).

To play around with them grab this package and import it into Unity. Keep in mind that the modifiers work at runtime, so you won't see any effects in the editor until you run the game. If you want to animate them, just add another script that will have a reference to the modifier instance and change it's properties at each Update() call.

If you are interested in this kind of "bricolage" with 3D geometry, I recommend to take a look at the Procedural Examples project provided by Unity. You will find there some highly interesting samples like dynamic extrudes or perlin noise. It's a great starting point to explore runtime geometry transformation.

Of course, take a look into the sources of the modifiers too! You'll see how simple it is to access the geometry at runtime and do some modifications. Basically it goes like this:

C#:
  1. MeshFilter mfilter  = GetComponent(typeof(MeshFilter)) as MeshFilter;
  2. mesh = mfilter.mesh;
  3. Vector3[] vs = mesh.vertices;
  4. int vc = vs.Length;
  5. for (int i = 0; i <vc; i++) {
  6.   // Modify your vertices here
  7. }
  8. mesh.vertices = vs;
  9. mesh.RecalculateNormals();

Things worth notice: In Unity a vertex is just an instance of Vector3 - there isn't any special class for this, as in Flash-based 3D engines.

You can see a bit of the casting-drama I need to do (lines 1-2) to get to the object holding the actual geometry information (Mesh). That's a bit annoying in C#, with JS that code would be more readable. Anyway, it's better to make that only once, in Start() and not at every Update().

To get correct lightning effects on the materials, do not forget to call mesh.RecalculateNormals() after you've modified the positions of the vertices.

If you want to modify your mesh continuously (i.e. to animate it) it's necessary to keep the original array of vertices, because the code above overwrites the original positions. Take a look at the source code in the package to see how I did it.

That's all for now, hope you enjoy it!

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!

Getting started with C# for Unity3D

C#

Unity3D offers a choice between 3 different programming languages: JavaScript, C# and Boo. Each of them has its pros and cons, but for me C# almost immediately came out as a clear winner. That is because it is fully object oriented and it's syntax is similar to Java and Actionscript 3, both of which I am experienced with. However, before I started to play with Unity3D, I never wrote a single line in C#, so I had to learn it from scratch.

As you probably know C# was originally developed by Microsoft and is widely used in the .NET framework as well as in Silverlight development. It is important to understand however that learning C# for Unity3D is not the same thing as learning the .NET platform. In fact you don't have to know anything about .NET to use C# with Unity3D.

While I use all kinds of online documentation, a book is often the best companion, so I thought buying a good C# book would be in order. It turns out that the small O'Reilly C# Pocket Guide is exactly what one needs. It is absolutely unnecessary to buy a 500 page C# bible, as most of the stuff in those books is related to .NET and is not applicable to Unity3D at all.

Of course the book alone is not enough. You also need the Unity3D scripting reference. All the examples in the docs are given in Javascript only. But don't worry, they are easy to translate once you get used to.

C# is a very elegant and powerful language. It's dot-syntax is based on Java, so if you come from a Java background you'll quickly feel comfortable with it. There are a few differences though. The most striking difference is the convention to start property and method names with an uppercase letter. I guess it comes from Visual Basic. I am not a fan of this convention, but it's better to use it and have a consistent code rather than fight it.

The list of all C# features is so long, that it makes AS3 look poor in comparison. C# is really like Actionscript on steroids. I suppose the next version of Actionscript will have at least some of those implemented, so it's good to know about them. Here's a list of my favorites.

Operator overloading

This is the coolest one by far! It allows to define custom actions for common operators like +, -, * or /. The best illustration of this feature comes with vector addition. In Actionscript, to get a sum of 2 vectors you need to write something like this:

Actionscript:
  1. var c:Vector3D = a.add(b);

This is not very nice, and becomes almost unreadable if more than two vectors are added. In C#, thanks to the overloaded + operator it looks like this:

C#:
  1. Vector3 c = a + b;

This is much more readable and elegant, isn't it? It goes without saying that the 3D vector implementation in Unity3D has all the operators overloaded. In case you want to do it yourself however, the implementation of operator overloading is very simple and in the above case could look something like this:

C#:
  1. public static Vector3 operator + (a:Vector3, b:Vector3) {
  2.    return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
  3. }

There are some simple rules: the operator function must always be static and must return an object of type it is defined for. However it can take any type of parameters. This allows to define operator overloading for adding or multiplying vectors but also for multiplying vector by a scalar or multiplying vectors by matrices. In fact this can be achieved thanks to another C# feature - method overloading.

Method overloading

Method overloading allows to define multiple methods with the same name provided that they take different parameters. It works with regular methods and with constructors as well. If there a multiple ways to create an object you can define multiple constructors to satisfy each case. As mentioned above it works with operators too.

A good example of method overloading in Unity3D API is the 'Transform.Rotate()' method. It has has been overloaded 3 times with different ways to specify a rotation:

C#:
  1. void Rotate (Vector3 eulerAngles, Space relativeTo)
  2. void Rotate (float xAngle, float yAngle, float zAngle, Space relativeTo)
  3. void Rotate (Vector3 axis, float angle, Space relativeTo)

You can either pass a vector of angle values, three floats - one for each axis, or a single angle combined with a rotation axis. This is only logical to call it 'Rotate' every time because this is what the method does at the end.

Actionscript has default parameter values, which in some cases can simulate method overloading but they are not quite as flexible as that.

Getter/setter syntax

C# has a very concise way of declaring parameters. While in Actionscript it takes two functions - one for 'get' and one for 'set', in C# it can look like this:

C#:
  1. public float Size { get; set; }

In this case the compiler automatically adds a private member for this property and there isn't anything else you need to do. Of course such a parameter is not very practical, so here's a more complex code, involving a public getter and private setter:

C#:
  1. public float Area {
  2.     get { return size * size; };
  3.     private set { size = Mathf.Sqrt(value) };
  4. }

You will also notice that neither the 'function' nor the 'var' keywords do not exist in C#. In that C# closely follows Java. This is good because both these keywords are completely redundant and do not add any information to the code.

Among other interesting features I recommend to explore indexers, generic types, structures and enumerators all of which are covered in depth in the pocket guide mentioned above but also in the many online C# tutorials.

Editing C#

There are multiple editors that support C#. Microsoft offers a great and free editor called Visual C# Express Edition which features code completion, but is Windows only (obviously). For a Mac there's Mono Develop which looks very powerful, but is not very stable yet. Unfortunately the C# plugin for Eclipse is completely unstable for the moment, and I wouldn't recommend it. On the other hand, it is still in alpha so let's give it some time. Of course there's always TextMate.

Last but not least there's Unitron - the Unity3D default editor. It is not very popular among developers, and I saw people complaining about it being too basic. I don't share this opinion. While it ain't no FDT, it's pretty solid, very stable and has basic auto-completion. The trick is auto-completion is turned off by default (why?). To turn it on go to 'Preferences' and you'll find it at the bottom of the 'General' section. With that, I'm sure that Unitron is enough to get started.

Most of us know JavaScript from the browser environment. JavaScript is often the first programming language people ever used. If this is the case, you may be tempted to just use JS with Unity3D right away and not bother learning anything new. After all, as far as Unity3D is concerned, anything that can be done with C# can also be done with JavaScript.

However in the long term, C# offers better control over the code, full OOP support, strong typing and a lot satisfaction of mastering a robust programming language, so the extra effort is worth it. Plus, for a seasoned AS3 developer, mastering C# is a matter of a couple of weeks anyway, so go ahead and try it out!

UPDATE March 2010. Here's a new post about C# and Unity3D:
Loading and manipulating images in Unity3D
(more coming)

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:

PDFBook3D, a 3D flipbook engine

PDFBook3d

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:

Actionscript:
  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!

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.



  • FITC10


  • FITC10


  • FITC10