I'm a software engineer who works on game development part time. I teach game development (on gamedev.stackexchange.com and lynda.com). I'm always working on something, and I'll post updates here. Let me know if there's a game development topic you want to know more about, I probably know the answer, or at least where to get one.

Monday, December 3, 2012

The Blender connection (part 1)

I use Blender for all my modeling and animations. I chose it because it was free, ubiquitous and appeared to produce good results. This post will describe exporting that information from Blender and importing it into AoG. This information will not only help those wishing to duplicate this in their own games, but also help future modders of AoG make their own models.

I'll start with the most basic application, a static mesh.

Step one: Make a model! I won't go into the details of making models here, as that's a process I haven't even mastered myself. We'll use a tree:

Clear proof I have not mastered model creation.

Step two: Export the model in the DirectX (.x) format. What? But I thought AoG was using OpenGL? Keen memory you have there reader. I use the DirectX format because it's fairly plain, easy to understand and supports all the features I want.

Things I want to export:

  • Vertex info: position, color, normal.
  • Armature information: bones, their hierarchy and their weighted vertices.
  • Animation data: bone animation key frames
Things Blender will export in the DirectX format:
  • See above list.
Step three: Place the .x model file in the appropriate directory (TBD where the modders directory will be located). All the .x files are read into the Lexicon and are ready to use in game. I wrote my own importer to read the DirectX format. It's actually fairly simple, because the .x files are written in plain text, easy to read and understand. The exported data is arranged in a hierarchy very similar to how the "Outliner" organizes the scene in Blender:

The difference is that it's arranged as a series of nested Frames. Each frame has a transformation matrix associated with it. Each child frame assumes that the parent matrix has already been applied. So for example, the output of our tree looks like this:

Where as you can see the Root frame matrix rotates everything by 90 degrees on the X axis. This takes care of the "in Blender Z is up/down where as in games Y is up/down" aspect. This will get applied to everything inside of the Root frame (which is the entire scene). Next frame is our model the Tree. Looks like it has a little translation going on. It's moved .5 units up the Z axis (remember that it's going to end up being .5 units up the Y axis because of the Root transformation). A child of the Tree model is the full leaves frame. This is the frame the contains the green leaves mesh. Meshes are defined by, you guessed it, `Mesh {`. It has 60 vertices defined. The vertex positions are all listed in X;Y;Z format. Then the primitives are listed. There are 20 primitives. The primitives are each defined like:


which means:

number of indices; first index; second index; third index;,

So we have a triangle that goes from vertices 0->1->2. Those vertex positions are defined above, their index is the order in which they're defined.

Once you understand the way these are laid out, it's fairly simple to parse the rest of the data. For example, the texture coordinates:

I'm sure you can guess that there's 60 texture coordinates and they're ordered to be paired with the order of the vertices defined earlier. If I'm not explaining it well enough, you can take a look at this site. Or just try exporting your own simple model (like a cube) and seeing what gets spit out and making sense of it. 

OK, so now we know where our vertices are located, the order we should draw them in, their texture information and normal information. That's everything we need to know. So stuff all that data into a VBO and check it out!

... Aw damn it. That's why the game is still pre-alpha.

OK, so I needed to use Ctrl+A in Blender to apply the transformation of the full leaves. Basically this sets most of the matrices to the identity matrix because it just shifts all the vertex positions by the appropriate amount. I shouldn't have to do that, there's a bug in my "accessories" drawing code. The full leaves are an accessory because given certain conditions (like the season), I don't want to draw the full leaves. I'll have to find that bug... Anyway, I applied the transformations and re-exported:

That's better.

Next time I'll cover exporting and importing animation. Thanks for reading!

See part two here, covering animations.

No comments:

Post a Comment