The Devil’s Details: Skinning (Animating)

I used to have a personal blog where I posted articles about technical issues I was working with at the time. Rather than just let them sit collecting dust, I’ve decided to re-publish some of them here under a special category.

I hope you find them interesting!  And without further ado, here is the first:

Originally posted Friday, May 13, 2011 at 10:24pm

I finally have multiple-bone skinning working! I think I can summarize the last few days as “Wow, that was a pain”. On the surface, a hierarchical animation system sounds easy: “Just go down the tree and accumulate matrices as you go”, but as is usually the case, the devil is indeed in the details.

I would love to make this blog post a full tutorial on skinning, but unfortunately I still don’t completely understand it myself. I slapped in some foreign code for nasty jobs so that I could just focus on getting the bones to animate and stay attached to the skin. Also because the code was written by accumulating many tests, it could be improved quite a bit.

Here are some of what I will affectionately call “the devil’s details”. Hopefully these will help someone who is learning to write a skinning system. Keep in mind that some of these might only apply to the Milkshape3D model format.

Not all Vertices will be Attached to a Bone

While this might not be the case in most animations, you should make sure that your system won’t explode when this situation is encountered. One of the animations I tested my code on was a brick hurtling towards a brick wall, bouncing off the wall and falling onto the ground. The wall was part of the animation, but was not attached to a bone.

Keyframes are Defined per-Bone, not Globally

Rather than having a list of keyframes which each have a list of the bones that they affect, each bone has a list of keyframes.

Calculating Keyframe Indices; not as Easy as You Might Think

The bones are animated by interpolating between two keyframes, keyframen-1 and keyframen, so you need to figure out which two keyframes the current animation time (abbreviated as t) is in between. You also need to gracefully handle the situation where t can be either before the joint’s first keyframe (keyframef) or after its last keyframe (keyframel).

Currently, my code finds these two keyframes as follows (given that keyframes list is a list of all the joint’s keyframes, and it is not empty):

  1. Step through keyframes list chronologically until a keyframe is found with a timestamp after t or the end of keyframes list is reached.
  2. If the end of keyframes list was reached, let keyframen equal keyframel. Otherwise, let keyframen equal the keyframe that was found.
  3. If keyframen is equal to keyframef, let keyframen-1 equal keyframef. Otherwise, let keyframen-1 equal the first keyframe chronologically before keyframen.

There are two cases where keyframen-1 will equal keyframen: If t is before keyframef, or if t is after keyframel. If keyframen-1 equals keyframen, interpolation is not required.

Keyframe Positions and Orientations are Relative to the Bone’s Original Position and Orientation

This was one of the big ones for me. I did not figure this out until well into development, so I had to basically rewrite the skinning system. This means that in order to transform a point to where it should be for the given keyframe, the point must be in the same coordinate space as the bone.

Convert Orientations from RH to LH, not just Positions!

This was the big one. Because of the previous “detail”, things can become really out of sorts if you get rotation wrong. If a parent joint is in a certain orientation, all movement is going to depend on that orientation being correct. If the orientation is wrong, the vertices attached to the joint will be in the wrong spot. This problem gets worse and worse the further down the hierarchy you go. As far as converting the orientations goes, I’m not entirely sure how it works. What ended up working for me was to invert z-axis positions and z-axis rotations, but I have read elsewhere that only the x and y axis rotations should be inverted when z-axis positions are inverted. I’ll have to do more research into this, but it is working fine for now!

Bone Matrix, what is it?

This had me confused for a while. Basically, the bone matrix needs to transform a vertex in model space (which is attached to the bone) into the coordinate space of the bone (without any animations), apply the keyframe transformation, then transform back into model space.

Web Server Improvements and Better Estimates

Improved Web Server

This morning while tinkering around with the Amazon EC2 instance that we use for our website and game server, I noticed that they had a new instance type available. What shocked me was that it was better…  And cheaper!

We have been using their “T1 Micro” instance for a while, which has worked well enough. It has occasionally had its performance issues though.  A performance issue this morning is actually what made me ultimately discover the new instance type: “T2 Micro”.

T2 Micro has a better CPU than its T1 cousin, almost twice the amount of RAM, and a better network connection all for a slightly cheaper price!  The only downside appears to be that you have to move  over to their new “VPC” otherwise you get a rather ambiguous error message. I was stuck on this issue until a blog post on Sam Rueby’s Findings helped me out of it.

Better Estimations

Edit: Due to Twitch.tv changes, most of our livestream recordings are no longer available. Sorry for any inconvenience this has caused.

My brother and I spent the rest of the day working out how long different features of the game will take to complete. We also livestreamed the process.

I’ve drastically reduced the scope of the features; they are now estimated in ideal work hours rather than ideal work days. This allows for easier scheduling since more features can be fit into one iteration (one work week), although they are smaller.

When estimating, I’m also listing out all of the tasks that would be needed to complete that feature.  Each task is then given an estimate in ideal work hours no less than 1/4 of an hour, and no more than 1 hour. As before, estimates are powers of two, in order to combat increasing uncertainty as estimates become longer.

A feature’s estimate is calculated by adding up the estimates of each of its tasks. This sum is then rounded up to the nearest power of two. If a feature takes longer than 2 hours, there is a good chance that it needs to be split up unto smaller features.

Img_0932

Well that was… Unexpected

screenshot3

First off, sorry about no project updates over the past couple days! It’s been hectic.

One interesting thing that did happen is that Areum was talked about on a Polish MMORPG news website!
www.mmorpg.org.pl/news/zobacz/Już-przesadzają-z-tymi-retro-MMORPG-ami-Przed-nami-kolejny-z-nich-Areum

It wasn’t a glowing review, but it’s still super cool that they noticed our project :)

On the subject of what today’s work looked like, it was something similar to the following:

  • 1 – 2 hours managing Twitter
  • 9 hours fixing unexpected household problems *facepalm*

Needless to say, not much progress was made on Areum >.< I’ll have to take part of my day off (Saturday) to plan the next iteration, since I have no time left now. I’ll post another project update either tomorrow or Sunday!

Trello Board is Live

trello

Areum finally has a Trello board :D https://trello.com/b/Zk7QjfjY/areum

Trello is a free online task management program: I highly recommend it to anyone who needs to do planning for a project.

Today I finished estimating the tasks for the first pre-production demo of the game. So tomorrow, I should be able to actually start working on them :)

Edit: Due to Twitch.tv changes, most of our livestream recordings are no longer available. Sorry for any inconvenience this has caused.

Finally: A Progress Report!

I’ve wanted to do this since Friday, so I’m finally writing it up :)  I technically don’t have any time left for work today, but I’m making an exception just so that this whole thing actually gets started!

Over the past few days, I’ve been working on the task list for Areum, as well as designing the new movement system.  Specifically, I’ve been working on the list of tasks that I need to finish before IfThen Software can release version 0.1.0 of the 1st Real Level Prototype of Areum.

2014-09-01 17.14.56

Boy, there’s more to do than I thought!  D:  Pictured here are the features (index cards), tasks (sticky notes), and the design for the new movement system.  There is also another page of designs under the one shown, for different networking and login related tasks.

To give a quick overview, I have to do the following:

  • New Movement System (designed to reduce the effect of latency)
  • Login Prompt
  • Misc. Informational Screens (for example: “the server is offline”, “the game is too crowded”, etc.)
  • Walking Animations
  • Security Improvements

In total, there is about 12 hours worth of work to be done.  But that’s ideal work hours which means that it will probably take a little longer since it is impossible to work at 100% efficiency.  Currently, I’m looking to have these finished by the end of the week.

Note that these are all things *I* need to complete: Jake, who normally handles content related tasks, has already finished all of the work he needs to do for this first release. So, I am feeling slightly swamped o_o  I’m just recovering from a cold as well, which didn’t help productivity at all.  Back in full swing now though!

Livestreaming Areum Gamedev!

As some of you may already know, we have started work on Areum again!  Today marks the 4th day of pre-production so far, and things are going well :)

I’ve decided to livestream the work we are doing today! You can tune in using the widget below. If you want to participate in the live chatroom, visit the following link http://www.twitch.tv/invisibleman6 and register/login to your Twitch.tv account if you haven’t already. Hope to see you there!

Watch live video from InvisibleMan6 on www.twitch.tv