Hey everyone,
I decided to release my skeletal animation editor. The program supports only SVGs for the image format (I may add support for a folder of images if anyone cares enough :p), but it's pretty nice. I haven't released the source code, as it's a terrible mess right now (I redeveloped it over the course of a day...).
Here is a screenshot of it in action:
{"name":"605813","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/a\/4a40dc6e2724fbb8b11b6d8b1d10d5fa.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/a\/4a40dc6e2724fbb8b11b6d8b1d10d5fa"}
Download link is here: http://commaexcess.com/articles/9/skeletal-animation-editor
(There is an example skeleton in the download, as well. Left click moves a bone, right click rotates. The rest is easy to figure out.)
]]>I thought about doing something like this a few years ago, but never found the time. This looks awesome, I'll try it out as soon as I get time - downloading now...
]]>Thanks ! I have another animation that is considerably better than the included (check the attachment). Since I don't have smart skin loading, you may have to edit Soldier.xml, scroll to the bottom, and change this:
<editor background="CornflowerBlue" skin="Soldier.svg" />
To...
<editor background="CornflowerBlue" skin="X:\Path\To\File\Soldier.svg" />
Else you'll get an error upon loading the file.
Here is a screenie of the soldier using a crush attack:
{"name":"605820","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d6c4c498f3bfa1592d9bced1c6b94394.png","w":640,"h":480,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/6\/d6c4c498f3bfa1592d9bced1c6b94394"}
]]>I may add support for a folder of images if anyone cares enough :p
Me, me cares enough!
I have a project that needs this kind of animation. But SVG is too complex format (at SVG files created by Inkscape are ). Bitmaps are better for me.
]]>Would you mind to explain how the SVG data is rendered to screen? I mean the whole process? sorry if I asking too much
Thanks in advance.
]]>Anyone with too much free time could make an SVG addon for Allegro 5.
]]>Would you mind to explain how the SVG data is rendered to screen? I mean the whole process? sorry if I asking too much
It's no problem! The skeletal animation editor uses a bridge between SVG and GDI+ and it's not something I made. On the other hand, my actual game uses a custom SVG loader that basically ignores everything but groups and path data.
Once the SVG is loaded, I have to perform a rudimentary triangulation of the points. Since I use a programmable pipeline, I am able to transform the points (better put, the resulting fragments; I'll explain this later) on the GPU, which allows me to generate the "infinite resolution" curves.
In order to triangulate the points, I perform a rather simple triangulation method that leverages the stencil buffer. I basically create a list of triangles out of points. Say I start off with four points:
Normally, triangulation would look like this:
However, if you have the stencil buffer available, you can triangulate them as so:
Notice the extra point (in red). This is the "dangling point" as I call it; it's used in the same manner as a triangle fan. Each point is connected to the dangling point. The stencil buffer allows us to skip a heavier triangulation method (e.g., Delauney), as outlined below, by using this method.
Now, when you go to draw the shape, you set the stencil buffer to always invert when a fragment is drawn and disable color writing. This will produce the following output in the stencil buffer:
Notice it's the triangulated shape? Simply draw the shape (in my case, I draw a special rectangle that is scaled and translated to fill the shape, which allows me to use gradients, etc with ease), this time with color writing enabled and the stencil test to only draw if the stencil value is odd (basically, not equal to 0). Basically, I am employing the common "even-odd" rule used by most SVG paths.
With that in mind, here is a Bezier curve that needs to be triangulated (note, this is a quick sketch and is not a quadratic curve, but let's pretend it is!):
First we need to assign to the points a curve value for the fragment shader (as explained later on) that defines the curve. Luckily, for quadratic curves, these values are simple: point 1 gets the curve value (0.0, 0.0); point 2 (the control point) gets the curve value (0.5, 0.0); and point 3 gets the curve value (1.0, 1.0).
Now, triangulating the curve is easy. First, create a triangle out of points 1, 2, and 3 (in that order). Next, connect points 1 and 3 to the dangling point in order to fill the shape in. For the curve I presented just above, this would have no effect. However, when adding more curves, it will fill in the shape.
Now, when drawing the path, you have to use a fragment shader. The fragment shader is extremely simple; you subtract the second component of the curve value from the first component of the curve value squared, as seen in the following fragment shader:
And then you're done. You need to understand that this method is much heavier than drawing a bitmap or even multiple bitmaps; however, even with many thousands of shapes, it's still not nearly as taxing as Crysis .
Also, keep in mind that I subdivide cubic curves into four quadratic curves that emulate the cubic curve nearly perfectly. This is because drawing a cubic curve on the GPU gives me too much of a headache . SVG paths primarily use cubic curves, so other than subdividing them, you'd have to calculate four special values as outlined in Loop and Blinn's excellent paper.
I have source code for the curve drawing available in Algae, a game library I programmed. You can get it here. The appropriate code is in Algae/Graphics/QuadraticPathBuilder.cs. Sadly, it's in C#, but the principle remains the same.
]]>Aaron, thank you very much! your explanation is great, thanks!
Implementing a real-time vector graphics engine seems to be a tremendous amount of work! I was thinking in implement a real-time vector graphics game using plain Opengl, but now I'm a little scared perhaps I should start using some SVG-to-GPU library?
]]>