Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Skeletal animation  (Read 3330 times)
0 Members and 1 Guest are viewing this topic.
Offline theagentd
« Posted 2012-01-10 07:43:19 »

I need animated 3D models, and skeletal animation is pretty much standard everywhere. I was surprised by the lack of information on the internet about it or maybe I'm just looking in the wrong places.

I understand the theory; each vertex is given a number of bones that affect it, and the vertex is transformed in a vertex shader. In practice I have no idea how to do this, again because I haven't studied university math yet. As far as I've managed to uncover each bone is a 4x4 transformation matrix. Bones also have a hierarchy (fingers attached to hand, hand attached to elbow, elbow attached to shoulder, e.t.c). In the 3D model format I want to implement a loader for bones are stored as a 3D rotation vector + an angle and a 3D translation vector.

My real question is: How do I generate these matrices? Create an identity matrix, rotate it and translate it? The other way around? What about the hierarchy? How/when do I multiply it with its parent matrix? WHAT IS GOING ON?! Cry

When I have my bone matrices loaded and ready I just send them as instance specific attributes to GLSL and access them in a vertex shader. So I multiply it by the model matrix first, then I transform this vertex with the bone matrices and average the result? Ah, matrices... I've hated you since the second movie!!!

I do realize that this is indeed over my head, but I just want to get it working more than actually understanding everything completely...

Myomyomyo.
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #1 - Posted 2012-01-10 08:21:58 »

Has I understand skeletal animation :
- To each bone, a matrix is associted. This matrix is composed of a translation (position of the root of this bone in the parent local location) and a rotation (from a quaternion to interpolate). Ali = Ati * Ari
- To each vertices, several matrices can be associated with a ratio ( rji, the most basic skeletal animation is done with a vertex associeted with only one matrix with a ratio of 1). Most vertices with have a ratio on 1 for one matrix and 0 for the other but vertices near joins.
- The position of the vertice is the position when all rotation are in the initial position.

So before calling the shader, you have to compute all the matrix by composing the child matrix with the parent matrix. For exemple Al1 is the local matrix for the body, Al2 local matrix for the pelvis, Al3 the left upper leg, Al4 the the left lower leg. Then the global matrix for the lower leg is :
Ag4 =  Ap1 * Ap2 * Ap3 * Al4

At initialisation you have to compute, the inverse of the matrices on each bones at the initial position :
Ag4'-1 = (Ap'1 * Ap'2 * Ap'3 * Al'4)-1

So for the local position of the vertex before rotation is : Agi'-1 * Pj
Then you get the global position of the vertex after rotation : Agi * Agi'-1 * Pj

Then in the shader for the vertex j :
Pgj = sum(i=0 to n , rij * Agi * Agi-1 * Pj) / sum (i=0 to n, rij)

In pratice :
- Agi * Agi-1 is compute before the shader
- the ration are done to have sum (i=0 to n, rij) = 1
- you limite the number of matrices associeted to a vertex (i don't think that more than 4 matrices is that usefull).


Offline gouessej
« Reply #2 - Posted 2012-01-11 10:39:17 »

Ardor3D supports skeletal animations but I assume you would like to implement this feature by yourself.

@Bonbon-Chan thank you for your nice explanation.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Spasi
« Reply #3 - Posted 2012-01-11 11:47:06 »

You may find this topic useful. It's old (2005) and a bit specific to a particular file format, but most skeletal animated data are described in about the same way.

Edit: You can find sample shader code here (4.4 Skinning)
Offline theagentd
« Reply #4 - Posted 2012-01-11 12:20:30 »

@Bonbon-Chan
Thanks a lot for your explanation! I think I understand more of the basics now!

I only have one real question right now: How do I generate a bone matrix from a translation vector and a rotation quaternion? I want to try to do this in software first since that's less error prone, and I'll skip interpolation for now. I'll implement all that later when I get a better grasp of the math going on here.

Thanks again for your response! I'll have to read it a few more times...

You may find this topic useful. It's old (2005) and a bit specific to a particular file format, but most skeletal animated data are described in about the same way.

Edit: You can find sample shader code here (4.4 Skinning)
That's one hell of a verbose thread! I'll look through it a bit, but like I said, It think I understand the concept of how this works, but not the math behind it. I'll probably be back with more questions if I can't figure it out after reading everything here...

Myomyomyo.
Offline Spasi
« Reply #5 - Posted 2012-01-11 12:59:11 »

How do I generate a bone matrix from a translation vector and a rotation quaternion?

For a row-major matrix:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
public Matrix4f set4f(Vector3f p, Quat r) {
   float r2x = 2.0f * r.x;
   float r2y = 2.0f * r.y;
   float r2z = 2.0f * r.z;

   this.m00 = 1.0f - (r2y * r.y + r2z * r.z);
   this.m10 = r2x * r.y - r2z * r.theta;
   this.m20 = r2x * r.z + r2y * r.theta;
   this.m30 = p.x;

   this.m01 = r2x * r.y + r2z * r.theta;
   this.m11 = 1.0f - (r2x * r.x + r2z * r.z);
   this.m21 = r2y * r.z - r2x * r.theta;
   this.m31 = p.y;

   this.m02 = r2x * r.z - r2y * r.theta;
   this.m12 = r2y * r.z + r2x * r.theta;
   this.m22 = 1.0f - (r2x * r.x + r2y * r.y);
   this.m32 = p.z;

   this.m03 = 0.0f;
   this.m13 = 0.0f;
   this.m23 = 0.0f;
   this.m33 = 1.0f;

   return this;
}
Offline theagentd
« Reply #6 - Posted 2012-01-11 14:12:15 »

That's awfully convenient! =D

EDIT: What the hell does "bind pose" mean?!

Myomyomyo.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (35 views)
2014-10-17 03:59:02

Norakomi (26 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (27 views)
2014-10-15 16:18:58

TehJavaDev (52 views)
2014-10-14 00:39:48

TehJavaDev (54 views)
2014-10-14 00:35:47

TehJavaDev (42 views)
2014-10-14 00:32:37

BurntPizza (63 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (76 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!