Last night I was experimenting some with a different cloud style at the behest of my girlfriend. I’m not really sure which I like best at the moment, but I figured I’d go ahead and post a screenshot and see if anyone had any thoughts.
Tonight after it cools off some, I’m going to start restructuring the code to be quite a bit cleaner. Currently I have only built a few classes, namely the ShivaVG related classes, and a set of other game related classes.
The ShivaVG classes:
- VGPath – A class that holds ShivaVG handles and necessary path data.
- VGRect – A child class of VGPath which has rect specific data.
- VGObject – A moveable object that holds a list of VGPaths.
The game classes (so far not many):
- Bone – A single bone, which holds a 2D point where the bone starts, an angle in radians, a length for the bone, and a list of keyframes.
- Skeleton – A collection of Bones that animate a single object.
- Player – The player object, which will hold a VGObject and a Skeleton (and probably other things as well but I’ve not got that far).
I think the first thing I need to work on is writing a manager for drawable objects that will handle loading and setting up all of the VGObjects. The reason I want to go this route is that I know at some point it will get too expensive to draw the static objects using vgDrawPath each frame. Instead I’m going to set up the VGObject class to have a flag defining whether the object is static or not. If it’s not static, it will be handled like it is currently – no change. If it is static, however, I’m going to render it and read it back into a VGImage (which in C# is really just an IntPtr) which will be used for subsequent rendering.
Another issue requiring me to set up this manager class is gradients and how Inkscape saves them in the SVG file. When you set up a gradient in Inkscape, it creates a child element under the svg:defs element, and the child elements of that element are the stops with the information needed to define the gradient to ShivaVG. The actual path that uses the gradient merely holds its ID. So to get gradient parsing working I’m going to have to parse all the gradient definitions into a list of some sort of gradient structure, then when parsing path attributes, request-by-ID the gradient defined in the style attribute of the paths.
I’m not sure how this will all be laid out or if I may end up with multiple managers (probably), but I know I also need other manager-level functionality for keeping tracking of drawing and other things.
I am really enjoying developing the SVG Ninja Game here, and I got to thinking about my process. Right now I really don’t have a concrete plan as to what bits of the project I’ll immediately be working next, and I think this is a benefit rather than a hindrance.
What brought this minor realization to the fore for me was just now while I had decided to do some new art for my level, namely the clouds. As I was drawing the clouds in Inkscape, I went to set them up how I had them before and realize, oops, I need to implement cap styles for path stroking for these to render correctly. I really like that I can implement little chunks of functionality driven by what I’m doing on the art side.
I think most of my enjoyment of this particular project is driven by the fact that I’m the closed loop for the whole pipeline. I do the art, I see it in game, I do more art, I write more code to display that new art and so forth.
I meant to post this about an hour ago, but I ran into a minor roadblock. After setting up the parsing for the stroke-cap parameter of the style attribute, and setting up the set call in my draw function, my little clouds still had square ends!
So first thing I do is go and search around to see if anyone else is having the same issue with OpenVG or ShivaVG in particular. No luck there…. I poke around the ShivaVG code some, and then the test suites. I compile and run the dash test and I’m looking at the code…I noticed it calls draw twice, once for fill and once for stroke, which is a bit odd. Eventually after going back and forth a few times I thought, “Well, it seems like it’s always setting the join style with the cap style…hmm.” I try that and voilà!
So, remember folks, if you’re setting up stroke cap styles, you have to set the join style as well!
And here’s the result of my process, this time:
I was just looking at this article, and it looks like for the most part the big three at E3 don’t seem to have a lot of interesting stuff planned to show. MS is going to be mostly Natal, I think that’s a safe bet, and not very interesting unless they show something really phenomenal that uses it well. Sony is going to be showing off the Move and 3D TV stuff, the latter of which is especially uninteresting given that no one has 3D TVs and it’s impossible to see how good/bad the integration is.
I don’t see 3D taking off when many developers are barely pushing the hardware to render a single perspective of their games’ scenes at 30fps in HD resolution, much less two renders of the scene at 60fps.
Nintendo hasn’t had an interesting E3 in quite a while with the last one being the extremely disappointing Wii Music and Wii Vitality Sensor unveiling, both of which are absolute duds. This year they might show off something with the Vitality Sensor, but who cares? I think Nintendo is just chillaxing with their millions, not trying to do much and resting on their success, which I think is a mistake.
Tonight I spent some time setting up the preliminary classes I’ll need for a
skeletal animation system. It’s all quite straight forward stuff, but just as a reference I have been using this excellent tutorial.
In the same vein, I also stumbled across some C# code for various types of 2D two-bone inverse kinematics solvers. The 2D IK problem is simple enough for two bones that one can solve it analytically and come up with a pretty fast solution (certainly faster than cyclic coordinate descent, which is pretty fast). I had planned on implementing either CCD or trying to do a Jacobian Transpose IK, but I think this should be sufficient for my needs, and the license is very liberal (free to use for commercial, just retain the license and a note attributing the author – nice).
Anyway, after setting up the classes for the skeletal animation and getting those compiling okay, I decided to go ahead and start dealing with the picking code. Of course, this led to using the ShivaVG functions for getting the bounds of a path. After setting it all up I was getting some odd results, so I eventually futzed around with the bounds calculation and eventually got it all sorted out.
I sat down today with the project in order to get some rudiments of movement working, and quickly ran into an issue. Namely, in the old version of the project in C++, I wasn’t directly drawing the ShivaVG paths. Instead I was drawing to a pixel buffer which was then used as the texture for quads. This enabled me to have an absolute position in the scene for any given object, and movement was a simple matter of translating the quad around. That made sense in the old project because it was the easiest way to draw the objects in the first place. Not so in the new project.
So, what did I do you may ask? Well, after much mucking about in the OpenVG spec and other searching around, I became a bit stumped and was almost ready to rewrite my code to do things the old way. However, with a bit of rethinking, I realized that if I change all the path objects to use relative coordinates (a setting which I had disabled in Inkscape because I was getting lazy earlier when writing the parsing code, but which is no longer an issue after I refactored it), I can simply update the initial move to command in the path, and clear and reinitialize the path data, which will give me a simple path-specific translation. Wonderful!
Amusingly enough, if you do this using paths that are forced to use only absolute commands, you get a nice ‘Scream‘-like effect:
I also figured out how to enable anti-aliasing in SFML, which makes things look a lot nicer. Unfortunately, my development PC is a little low-end in the graphics department so it performs rather badly at 6xAA.
Don’t have much time to expand upon this, so I’ll let the screen cap do the talking.