In Detail: Tricked Out Trucks

In early 2008, Cadbury’s were launching a new TV advert and wanted a new online presence for their “Glass and a Half Full Productions” brand. This site would provide information about Cadbury’s and the adverts, and also house some fun interactive bits & bobs inspired by these adverts.

We pitched for and won two interactive activities. The first of these activities, and the one which I’ll talk about in this post was named ‘Tricked Out Trucks’. The brief was simple enough: we were to create a tool which would allow visitors to the site to customise an airport truck in 3D. The creator of the best design (as picked by a panel of luminaries) would win that truck for real, all pimped out and delivered to their door. Apparently, the client had come to this concept without ever having seen Den Ivanov & PARK Studio’s Brahma Bus in 2007, and were very surprised when we told them about it :)

We ended up differing from PARK Studio’s (pretty seminal) app in two ways. First, rather than allow freehand drawing, we assumed that most casual visitors to the site either wouldn’t have the artistic skills or inclination to draw an elaborate design, so we provided preset patterns which the user could customise to their liking and decals which they could transform and place freely. Second, we wanted to allow users to make modifications to the shape of the truck by adding body mods: spoilers, wheels and wing mirrors.

The Process, Part I: 3D Models

The first thing we needed were 3D models. After gathering a whole bunch of photos, we asked JS3D to cast their minds back to Quake-era game modeling and provide us with low-polycount models of the truck and mods. We worked on a rule of thumb of 200 – 500 polys per model, which was pretty conservative; we could probably have got away with up to about 1000, but we were treading carefully in unknown territory (this was our first big 3D project), and I wanted to err on the side of caution in the interests of keeping the chances of encountering unpleasant surprises as low as possible. JS3D were really helpful here: they understood what we were trying to do straight away, and were great at suggesting optimisations I’d never have thought of, such as faking complex geometry by using transparent texture maps on simple planes (this is how the wing mirrors and spoilers were achieved). 

They were also really helpful when we ran into that dreaded pitfall of Flash 3D engines: sketchy z-sorting. Working closely with JS3D, we identified the areas of the model which were most affected: areas where polygons overlapped, for example, or were in close proximity to each other, or inside the volume of other shapes, and tweaked the model to minimise those effects. At the time, I wasn’t aware of the alternative depth sorting options available in Papervision and Away3D; these would certainly have been helpful to us, but actually altering the geometry of a model is a fairly bullet-proof way of reducing z-sorting artifacts, and I’d recommend it to anyone who is having trouble with polygon-popup issues, especially given the extra processing overhead of the sorting methods.

The Process, Part II: Decorating the truck

The second big part of this project was working up a system which would allow us to redraw parts of the texture map on the fly, and have that update on the model in realtime. Conversely, for positioning decals, we needed to detect where the user was pointing on the model and accurately draw decals back onto the texture map, based on their state in the interface. We were lucky here in that the truck was a pretty simple, boxy shape, which made manipulating different parts of the texture map pretty easy: essentially, I treated the truck as a box, and the texture as a net of that box. I then created a set of masks corresponding to each side of the truck to allow me to isolate those sides in the texture bitmap, and a matching set of transforms that allowed me to composite new bitmaps in the correct place (and with with properly adjusted scale & rotation) on that texture.

The texture drawn onto the truck model has five layers (in order, from the bottom up):

  1. paint
  2. pattern
  3. body details
  4. decals
  5. baked lightmap

As the user makes changes in the interface, the layers for the relevant side are redrawn within their mask area, and the newly-recomposited texture is passed to the truck view, where the truck’s material is updated with the new bitmap. By redrawing the texture in specific areas only, the whole cycle could run quickly enough to update the truck view in realtime, most of the time ;)

Getting decals working correctly was quite tricky. In the interface, we presented the user with the option to drag & transform decals across the view of the truck, which would then be added to the texture map. I eventually got this working with a bit of a hack: given that the truck view was being locked off at dead-on 90 angles while the user was positioning their decals, this meant that the view on screen corresponded fairly directly to one of the masked face areas in the texture map. Therefore, if I could get the mouse’s relative position on the truck view, I could translate that directly to a corresponding position on the texture. This position had to be a percentage of the distance from the top left of the view (e.g. (.3, .8) ) rather than absolute pixel values to allow for scale differences between the texture map on the onscreen rendering of the truck. 

I later found that this is called UV mapping by proper 3D programmers, and the ability to get the mouse’s UV coordinates on a texture has been available in both PV & Away for quite a while. Oh well; nothing like implementing something yourself for getting a proper understanding of it!

Afterword: 3D in Flash

At the beginning of the project, whilst still in the prototype stage, I created an abstract TruckView class and wrappers for Away3D and Papervision so I could switch back and forth between the two during the development process for actually rendering the thing. The following are my impressions of the two as I worked through the project. 

I started out with Away3D, because (to my eye) it looked a bit better during my early tests. Then, as I tackled the finer points of interacting with the surface of the truck model, I switched to Papervision, as it seemed to have better interactive features, and better documentation on those features. Finally, however, I switched back to Away3D; in the final stages of the project, we were having some performance and z-sorting issues, and Away3D was hitting consistently higher framerates and looking better whilst doing it. It’s generally my impression that Papervision was a bit stronger at hardcore technical stuff and tends to implement new features more quickly, but Away3D had a nicer API and (crucially) looked nicer.

I should stress that this is just my opinion, and the observations that I made about the strenghths and weaknesses of the two could just as easily be down to my (mis)use of them as to any actual differences. Remember, I started this project as a n00b to both engines, and they make progress all the time; both will certainly be totally different beasts by now from their state last year. That said, we’re currently working on another 3D project which went through a similar evaluation process at the beginning of development, and again we settled with Away. The best recommendation I can make if you’re about to start a 3D project in Flash is to evaluate both and see which best meets your needs.

Leave a Reply