Saturday, March 19, 2016

ASSIMP Skeletal Animation Tutorial 2: The Basics of Bones


This second tutorial is simply going to be the basics of bones.

A very important concept you need to grasp in order to understand skeletal animation is the offset matrix.

-Offset Matrix: The offset matrix is the matrix that transforms from world space into bone space, in other words it is simply the bone's transformation relative to the world's origin.

Think of it as how far the bone is from the origin.
Like this:











When you first try to transform a bone, it will by default be transformed around the world's origin instead of the bone's origin.
Like this:



When we want...


But how do we get this?
We must first transform the bone by the inverse (think of it as the opposite) of the offset matrix so that the bone is at the origin.
Then we transform it by whatever transformation matrix we want (this is specified by you as the bone's transformation matrix).
And finally we transform it back to it's original position by multiplying it by the offset matrix.


Ok but let's dive into the actual code, the first thing we want to do is define a bone class, so create a new file bone.h and create a new class:


#ifndef BONE_H
#define BONE_H

#include <glm/glm.hpp>
#include <string>
#include <vector>

#include <assimp/scene.h>
#include <iostream>


class Mesh;

class Bone
{
    public:
        unsigned int id;
        std::string name;
       
        Mesh* mesh;

        glm::mat4 offset_matrix;

        glm::mat4 transform;
        Bone(){name = ""; id = -2;}
       
        Bone(Mesh* in_mesh, unsigned int in_id, std::string in_name, aiMatrix4x4 in_o_mat);
        Bone(Mesh* in_mesh, unsigned int in_id, std::string in_name, glm::mat4 in_o_mat);
};


#endif

Now I know I said I wouldn't plop any chunks of code but I'm going to walk you through this step by step, and trust me there's more to come.

First we have the include guards and the includes themselves, those should be self-explanatory.

Then we have the id: this will come in handy later on when we have to locate this bone inside the vector of other bones called the skeleton -- the id is the bone's location inside the skeleton.

Next we have the name: this is just for the same purpose as the id, essentially, it is to help us locate the bone inside the skeleton later on. It's for convenience.

The Mesh* mesh is useful because the Mesh class will later on contain the vector of Bones called the skeleton. Giving the individual bones the ability to access this allows them to locate other bones in the skeleton and access their properties, this will come in handy later on.

The offset_matrix is what was explained above, the transform is simply the bone's transformation, and then we have the constructors. The -2 in the first constructor is just a number I picked, it works. That's what matters.
The other two constructors take in the mesh, the bone's id, the bone's name, and the bone's offset matrix -- there are two so the constructor can use both ASSIMP's matrices as well as GLM's. We'll write a convenience function to convert from ASSIMP to GLM pretty soon, so don't worry about that.

We will continue to add on to this class as the tutorial series goes on, this is just the bare bones.

Heehee.



Anyways, the next thing we have to do is write our bone.cpp file, we'll add on to this file later on as well, these are just the basics:


ASSIMP Skeletal Animation Tutorial 1: Basics of Skinning

 Skinning and How It Works

Skeletal animation is a technique in computer animation in which a character is represented in two parts: a surface representation used to draw the character (called skin or mesh) and a hierarchical set of interconnected bones (called the skeleton or rig) used to animate (pose and keyframe) the mesh.

I got that from Wikipedia, so if that's wrong, tell them not me.
Anyways, skinning is accomplished by giving each vertex an extra set of attributes, specifically "which bones it should move with", and "how much it should move".

The first one, "which bones it should move with", is known as the IDs. These are stored as an array of integers, in our case and in most cases in computer graphics 4 will suffice. These are the IDs of the bones this vertex should deform with. Each bone stores its own ID, but we'll cover that in a later tutorial, don't worry about that just yet.

The second one, "how much it should move", is known as the Weights. These are stored as an array of floats. In our case 4 will once again suffice. These Weights control just how much the vertex should deform with the bones specified by the IDs, and each Weight corresponds to its ID.



In terms of code, we will need to go into our base Vertex class and add two new variables to it:

    float weight[4];

    unsigned int id[4];

These should go after the Position, Texture Coordinate, or whatever variables you already have in your Vertex class.


Inside your Mesh class you need to add two more Vertex Buffer Objects, one for the IDs and one for the Weights.

ASSIMP Skeletal Animation Tutorial 0: The Intro

Hello there and welcome to the first in this series of tutorials on how to implement Skeletal Animation using C++, the ASSIMP library, and an OpenGL Engine.

The world needs a skeletal animation tutorial for ASSIMP, because Christ this can be a confusing topic.

There are some things you need to know first though:
    1-It is entirely possible that some of my definitions may be wrong, and if this is the case please be sure to tell me and I will go back and change it until it's all correct.
    2-My drawings are amazing.
    3-This tutorial is written in a 'unique' way. It is written in a way that leads you along the same path I did, I won't just plop some completed code in front of you and explain it, think of it as I'm writing the code with you. This tutorial is being written with the express purpose of you following along, the code you write won't be finished until the very end, but I will lead you down the path where you see the most progress as soon as possible.
    4-I will add links to my YouTube videos that show exactly what you should be seeing. It's not self-promotion, I'll get that part out of the way right now so you can't complain about it later.

HEY GUYS CHECK OUT MY YOUTUBE CHANNEL IT'S REALITYMULTIPLIED HEY HERE'S A LINK
https://www.youtube.com/user/RealityMultiplied/




Ok.
Now that that's out of the way, the tutorials.