Archive for the ‘Flash’ Category

an approach to triangulating polygons with holes

Friday, June 12th, 2009

I know this has been done before, probably much more efficiently, but I had an idea wednesday and had to pursue it to its conclusion :)

The other day Katopz pointed me to this snippet which triangulates polygons. I’ve also seen an approach to ear cutting by nicoptere.

I figured that by converting an “O” into a “C” leaves me with two polygons which are easy to triangulate. Allow me to elaborate:

So the idea is just to cut out a rectangle (two triangles), which connects the polygon and the hole. Triangulate the “cut shape” and then concat the extra two triangles to it. But which rectangle to choose?

I wrote a class called PolygonWithHoles.as . This contains a polygon (Vector.<Point>), and holes (Vector.<Vector.<Point>>). The idea is too loop through the “holes” one at a time (cue beavis and butthead). The safest bet is to find the shortest “connection” between a point on the main polygon and the hole (done by looping and using Point.dist()).

This too has one stipulation. In order to have a rectangle, the code has to find the “shortest connection” either before or after our initially picked “shortest connection”.

Once the “cut out rectangle” has been discovered, the perimeter of the main polygon and the hole are merged through a few loops. If there are more holes, the now modified main shape is chopped again and again, eventually resulting in a “hole free” polygon. This can then be triangulated, and the “removed rectangles” are appended as sets of triangles.


Click image for demo


This approach seems to work well over 90% of the time. A few characters in some fonts do throw an error… not sure why. The triangulation is pretty fast, you can see this in the tracebox in the demo. The vectorization of the text is the slow bit.

The next step, of course, is to extrude the characters using textures :) Maybe even add shading some day…

The code is more or less legible this time, eventually I hope to clean this up into some sort of an API… Once again, the download is a zip of my always expanding “FindBitmapPixelOutline” project… download it’s latest incarnation here. The project you want to look at is “TriangulationTest.mxml”. Warning, it’s 6 megs with tons of crap you probably don’t want :D

.

Dynamic text with phong shading using Stok3d

Tuesday, June 9th, 2009

Yesterday David DerSchmale Lenaerts released Stok3d into the wild. When he showed me the demos, I immediately felt (you guessed it) STOKED!

Naturally my first question was : "does it support transparency?!", and with a resounding yes, I just had to try this with text :D

I wanted to generate the texture maps dynamically. It's not quite there yet, but not bad for a quick experiment :)

This took three steps:

  1. Create the diffuse map by generating a text field, taking a bitmap data snapshot of it and adding some bevel to it.
  2. Create the normal map by repeating the previous step, only using Red and Blue colors, with slightly different bevel settings.
  3. Create the specular map by extracting "outlines" using convolution filter.

These three bitmaps look like this:

Here's the code for generating them:

Actionscript:
  1. var font_size:uint=140;
  2. var tf:TextFormat=new TextFormat("Arial",font_size,0xac8ea9,true);
  3. var diffuse:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  4. diffuse.applyFilter(diffuse,new Rectangle(0,0,diffuse.width,diffuse.height),new Point(),new BevelFilter(5,45,0xFFFFFF,1,0x00,1,10,10,3,3));
  5. _diffuse_map=new Bitmap(diffuse);
  6.  
  7. tf=new TextFormat("Arial",font_size,0xbf6cde,true);
  8. var normal:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  9. normal.applyFilter(normal,new Rectangle(0,0,normal.width,normal.height),new Point(),new BevelFilter(5,45,0x89a1f9,1,0xFF00FF,1,12,12,3,3));
  10. _normal_map=new Bitmap(normal);
  11.  
  12. tf=new TextFormat("Arial",font_size,0xFFFFFF,true);
  13. var specular:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  14. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),new BevelFilter(5,45,0x999999,1,0x00,1,0,0));
  15. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),
  16.                                             new ConvolutionFilter(3,3,new Array(0,20,0,20,-80,20,0,20,0),10));
  17. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),new BlurFilter(2,2,2));
  18. _specular_map=new Bitmap(specular);

Then I just grabbed Davids demo code and replaced his textures with mine... and voila:

click image for demo:


storm image from http://www.flickr.com/photos/digitaltool/2569963337/

For some reason the demo doesn't start everytime. Just refresh a few times and you should be STOKED! ;) Also, the specular lights go black sometimes. I'm convinced this is just due to my happy go lucky texture generation, but David claims he needs to look at his code.

check the demo

download the demo as project. This is just my demo file, you'll need to fetch the Stok3d code from google (see link above);

I have to say, Stok3d is pretty damn cool! Sweet work herr schmale :thumbsup: :pirate:

.

Verlet Text Effect

Thursday, June 4th, 2009

Here's a demo I made for my presentation at multi-mania. I played around with verlet integration before and have long wanted to try this technique on text. Once I got the vectorization going, it was just a matter of connecting all the points to "Verlet Sticks".

This turned out to be a little tougher than expected. The tricky thing about Verlet Sticks, is that if you connect the same Verlet Point to multiple Verlet Points, the calculations go berzerk, and your shape quickly vanishes from the canvas into the ether. So the challenge was to find a way to connect all the points of a vector shape, with a minimum number of "individual connections", yet in a way that maintains the integrity of the shape. Keyboard cat played me off multiple times in my attempts :D .

Finally, the solution I landed on, was to create a grid out of all the points. The idea is to create a boundary rectangle, which maintains it's shape via "cross sticks":

Then, create a grid using all the points of your vector shape(s), in such a way that each point connects to a subdivision of the outlines of that "boundary Rectangle":



In the image above you can see the "boundary rectangle" surrounding the vector shape. Then, each point is connected with a vertical and horizontal line. These verticals and horizontals are then connected to a "subdivided" boundary rectangle.



In the demo you can turn "render sticks" on and off to visualize the trick.

Strengths:

  • Can handle pretty much any set of shapes and subshapes

Weaknesses:

  • Due to the "Boundary Rectangle" the shapes "bouncing" is limited, a "T" for instance can't lie diagonally, it always ends up on one of the four sides of the rectangle.
  • The vertical and horizontal lines shouldn't have more than two subdivisions. To fix this, the code first checks for all points along the same x and y, then shifts any instances above 2 by .5 pixels each. It's practically invisible, but it's there.
  • Doesn't support transparency, I guess this could be done with a blendmode or so...
  • More complex shapes can still spazz out and disappear :(

Click to try out the demo here . Ignore the collision physics, it's CRAP! The effect works best with "pixel fonts". The controls are :

  • RENDER : renders the input text with the selected font
  • UPDATE : update one frame of animation (when stopped)
  • PLAY : updates the animation on an enter frame
  • BOUNCE : when the characters are just skidding the floor, spice things up by clicking this button

The code is DIRTY, but does the trick. I've uploaded the source for the brave (or desperate ;) ). It's the same project that I've been using for my last 5 or so blog posts, so there's a lot of redundant code in there. Download it here.

ext steps:

  • compose a clean "all purpose" class for generating such a grid
  • Render shapes with curves, using the drawing api
  • Use nicopteres vectorization code to do this with photos...
  • Improve the curves and optimization, again I think I can use some code from nicopetre

I just wanted to put this out there because, well, it's kind of nifty... More to come, enjoy!

.

Detecting edge pixels with Marching Squares Algorithm

Thursday, May 28th, 2009

Last week a kind individual called "Rothrock" commented on an older blog entry of mine Extract shape outline points from BitmapData and pointed me to the Marching Squares Algorithm.

(Image ruthlessly stolen from wikipedia without remorse)

This does more or less what my "outline point extraction" algorithm was doing, except, with a grid of 4 pixels instead of 9. I nearly choked at the thought of how wasteful my previous approach was. So, I promptly implemented the algorithm in as3, and tested out the speed difference.

Indeed, Marching Squares pwns and humiliates my older implementation, it's 2-3 times faster. This due to the fact that the source bitmap data does not need to be doubled in size, and naturally less pixels require inspection.

However, there are two gaping problems with this 4 pixel grid approach.

1) 'Single pixel vertical and horizontal lines' result in duplicate points

Although the 4grid handles such "single pixel lines" like a champion, it "scans" those points twice (see the line at the bottom of the wikipedia image above). If the goal is to (let's say) extrude this shape, problems just might ensue. So my implementation allows for a parameter which returns only unique points.

2) There is a special case which causes an eternal march. Poor squares.

If you consider the grid variations on that wikipedia page image, the squares march right into our lonely pixel, and keep doing circles Ad infinitum.

The best solution I could come up with, and please don't hesitate to share a better one, was to set a MAX_POINTS value. If the number of discovered points exceeds this, then the algorithm stops, and hands the task over to... wait for it... my old approach :D I refactored this into a class called MarchingSquares9Grid.as . This one has no duplicate pixels by the way, thanks to the double sizing of the source bitmap.

Click the images below to see the algos in action:




On my machine the MarchingSquares runs around 50 fps, but dips whenever the above mentioned exception occurs. The point is that you'll always get the pixel outline, in most cases very fast, in fringe cases a bit slower.

I wrote a MarchingSquares class, which can be used as follows:

Actionscript:
  1. MarchingSquares.getBlobOutlinePointsClockwise(bmd);
  2. //or
  3. MarchingSquares.getBlobOutlinePointsCounterClockwise(bmd);

If speed isn't an issue, use :

Actionscript:
  1. MarchingSquares9Grid.getBlobOutlinePoints(bmd);

Just two considerations:

  • I couldn't be arsed to make the MarchingSquares9Grid run counter clockwise, so there's a method that reverses your Vector if that tickles your perversions.
  • Both of these will require at least a one pixel padding of transparent pixels in your source bitmap. This can be introduced with some bitmapdata magic.

download MarchingSquares.as and MarchingSquares9Grid.as here

Thanks again Rothrock!

It’s Multi-Mania Mayhem May 18-19 Man!

Wednesday, May 6th, 2009


May 18-19th in Kortrijk Belgium Europe’s biggest free multimedia event, Koen was kind enough to invite me to present alongside a cool list of speakers. This will be my second performance at the conference. :buttrock:

I'll be doing an upgraded version of my FITC presentation : "Text Addiction". I've renamed it to "Hot tips to improve your Text life". The "Text Addiction" presentation was almost "too well organized" and focused on one "avenue". This time I'll be covering a broader range of text related topics relating to Flashplayer10. This includes the "vectorizing" I've been doing lately, text-effects with 3d and the drawing api, and aspects of the Text Engine and the Text Layout Framework.

Hope to see you there!