Le squelette d'un avatar ou d'une créature

Actuellement, le seul moyen de donner vie à vos avatars et aux créatures est de créer des animations dans Blender et de les exporter au format Cal3D.

Tous les squelettes sont définis du côté client dans les fichiers au format .CSF du répertoire skeletons. Ce fichier étant au format binaire, il n’est pas humainement lisible. Cal3D offre des outils pour convertir ces fichiers en format XML (humainement lisible … enfin supposé l’être).

Vous trouverez les programmes de conversion déjà compilé pour windows ici.

Nous allons dans un premier temps essayer de comprendre comment fonctionnent les animations dans le jeu.

Le squelette et les os

Non, il ne s’agit pas de ne parler que des mort-vivants mais aussi de toute les créatures des Landes, avatars compris. En fait, pour pouvoir animer un objet 3D aussi complexe qu’une créature, il convient de lui associer un squelette. Le squelette est composé d’os et d’articulations permettant de bouger telle ou telle partie du corps. Les squelettes ont été créés dans Blender et pour chaque créature on a associé telle ou telle partie du mesh à un os.

Roja, l’artiste de la version US, a préféré ne créer que quelques squelettes lui permettant ainsi de limiter le nombre d’animation à créer. On retrouvera donc les squelettes par catégorie, par exemple le fichier medium.csf est utilisé par tous les avatars quelques soient leurs races et leurs tailles. L’avantage est qu’il n’a créé qu’une seule animation pour saluer, par exemple, qui s’appliquera à tous les avatars.

exemple, le squelette des avatars :

Chaque os possède un nom pour faciliter le travail de l’animateur (celui qui va créer les mouvements, pas les animateurs du jeu). Ces noms sont connus dans Blender et mais dans les fichiers Cal3D on utilise également un identifiant numérique. Cet identifiant numérique est utilisé à la fois dans les meshes et dans les animations.

Actuellement, il y a 19 squelettes différents dans le jeu :

  • bear.csf : les ours.
  • bird.csf : les aigles, les faucons.
  • bird2.csf : les cockatrices
  • boar.csf : les sangliers.
  • canine.csf : les chimériens, les renard, les loups.
  • deer.csf : les cerfs.
  • dragon.csf : les dragons (non utilisés).
  • feline.csf : Les férans, les leopards, les lions, les panthères, les pumas, les tigres.
  • gargoyle1.csf : non utilisés.
  • horse.csf : les chevaux (non utilisés), les licornes.
  • medium.csf : les Nains, Les Elfes, les Humains (homme bleu inclus), les Kultars (fichiers nommés gnome), les Galdurs (fichiers nommés orchan) et les Draegonites (non utilisé dans la VF).
  • monster1.csf : les lutins, les cyclopes, les démons D’jhis (feros), les gargouilles, les Géants, les goblins, les hobgoblins, les farfadets, les leprechauns, les ogres, Les orcs, les combattants fantômes, les squelettes, les trolls, les diablotins, les yetis.
  • penguin.csf : les pingouins.
  • puma.csf : non utilisé.
  • rabbit.csf : les lapins, les démons lapins.
  • rat.csf : les rats, les castors, les raton-laveurs, les putois.
  • snake.csf : les serpents.
  • spider.csf : les araignées.
  • wraith.csf : l’Esprit, celui qui donne la force et la volonté de vaincre les Landes…

Au niveau du jeu, c’est dans les fichiers XML du répertoire actor_defs que l’on associe le fichier squelette (CSF) au fichier mesh (CMF). En fait ces fichiers XML définissent tout les avatars, les équipements et les créatures du jeu.

Pour associer un squelette à un mesh :

 <actor type="beaver" id="8">
 	<skin>./meshes/animals2.bmp</skin>
 	<skeleton>./skeletons/rat.csf</skeleton>
         <mesh>./meshes/beaver.cmf</mesh>
 	<scale>1.6</scale>
 	<bone_scale>1.6</bone_scale>
 ...
 ...
 </actor>

Dans cet exemple, on associe le mesh beaver.cmf avec la texture animal2.bmp et le squelette rat.csf. On remarquera les mots clés scale et bone_scale qui servent à mettre à l’échelle le mesh et le squelette (ici un castor est 1,6 fois plus grand qu’un rat).

Conversion du fichier de squelette au format XSF (forme XML du CSF)

Le fichier CSF peut être converti au format XSF par la commande suivante :

cal3d_converter medium.csf meduim.xsf

Vous obtenez un fichier contenant (Début seulement car le fichier fait 13ko) :

 <SKELETON VERSION="1000" NUMBONES="30">
     <BONE ID="0" NAME="root" NUMCHILDS="3">
         <TRANSLATION>0.00216135 0.000226406 0.780926</TRANSLATION>
         <ROTATION>0.706989 -0.0128938 0.00183134 -0.707104</ROTATION>
         <LOCALTRANSLATION>-0.018419 -0.780712 0.00026022</LOCALTRANSLATION>
         <LOCALROTATION>-0.706989 0.0128938 -0.00183134 -0.707104</LOCALROTATION>
         <PARENTID>-1</PARENTID>
         <CHILDID>1</CHILDID>
         <CHILDID>6</CHILDID>
         <CHILDID>11</CHILDID>
     </BONE>
     <BONE ID="1" NAME="hipR" NUMCHILDS="1">
         <TRANSLATION>-0.012525 0.143171 -0.000657582</TRANSLATION>
         <ROTATION>-0.174697 0.00373261 0.890854 -0.41934</ROTATION>
         <LOCALTRANSLATION>-0.685893 0.603218 -0.138829</LOCALTRANSLATION>
         <LOCALROTATION>-0.161447 0.632912 -0.631081 -0.418442</LOCALROTATION>
         <PARENTID>0</PARENTID>
         <CHILDID>2</CHILDID>
     </BONE>
     <BONE ID="2" NAME="thighR" NUMCHILDS="1">
         <TRANSLATION>-0.000194804 0.132073 -0.000106222</TRANSLATION>
         <ROTATION>-0.418871 0.890689 0.0999228 -0.145722</ROTATION>
         <LOCALTRANSLATION>0.125751 0.820266 0.150843</LOCALTRANSLATION>
         <LOCALROTATION>0.777087 1.34489e-006 -0.0124644 -0.62927</LOCALROTATION>
         <PARENTID>1</PARENTID>
         <CHILDID>3</CHILDID>
     </BONE>
     <BONE ID="3" NAME="calfR" NUMCHILDS="1">
         <TRANSLATION>6.68953e-017 0.301088 -1.41312e-016</TRANSLATION>
         <ROTATION>0.195613 0.0100634 -0.0112865 -0.980565</ROTATION>
         <LOCALTRANSLATION>0.112602 0.540425 -0.0580916</LOCALTRANSLATION>
         <LOCALROTATION>0.639016 1.17141e-006 0.00270002 -0.769189</LOCALROTATION>
         <PARENTID>2</PARENTID>
         <CHILDID>4</CHILDID>
     </BONE>
 ...
 ...
 </SKELETON>

On trouve comme information :

  • BONE : définition de chaque OS avec son identifiant (ID=0, 1, …), son nom Blender et le nombre d’os fils (NUMCHILDS).
    • Déplacement de l’os par rapport à son père.
      • TRANSLATION : déplacement selon les axes X, Y et Z par rapport à l’os père
      • ROTATION : rotation par rapport à l’os père stockée comme quaternion
    • Transformation à apporter aux points du mesh par rapport à l’os
      • LOCALTRANSLATION : déplacement selon les axes X, Y et Z.
      • LOCALROTATION : rotation stockée comme quaternion
    • PARENTID : Numéro ID de son os père (-1 si pas de père)
    • CHILDID : Numéro ID de l’os fils, il y a un paramètre CHILDID par fils (NUMCHILDS).

Ce qui peut nous intéresser dans ce fichier c’est l’organisation des os de père en fils car le reste c’est plus pour les matheux. Nous laisserons Blender faire la partie mathématique pour nous.

Ce qui nous donne dans l’exemple ci-dessus :

  • root (Id=0) : départ du squelette (ici on pourrait dire que c’est le nombril).
    • hipR (Id=1) : Hanche droite.
      • thighR (Id=2) : Cuisse droite
        • calfR (Id=3) : Jambe droite
          • … (Id=4) : Cheville droite
  • … (Id=6) …
  • … (Id=11) …

Les fichiers squelettes ne sont pas à modifier mais comprendre leurs fonctionnement, ainsi que les os qui les composent, permettra de passer à l’étape suivante : les fichiers d’animation d’un avatar ou d’une créature.

Les images viennent de la version US, il y a donc quelques os en plus comme arrow pour le carquois de flèches et ne sont pas (encore) dans le modèle actuellement géré par le jeu Landes Eternelles’’.

Informations sur les quaternions

http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/index.htm

q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))

où :

  • a=angle of rotation.
  • x,y,z = vector representing axis of rotation.

ou

q = w + x i + y j + z k

Conversion en angle :

angle = 2 * acos(qw)
x = qx / sqrt(1-qw*qw)
y = qy / sqrt(1-qw*qw)
z = qz / sqrt(1-qw*qw)

programme php :

<?php
 
$qx=-0.161447;
$qy=0.632912;
$qz=-0.631081;
$qw=-0.418442;
 
$angle = 2 * acos($qw);
$x = $qx / sqrt(1-$qw*$qw);
$y = $qy / sqrt(1-$qw*$qw);
$z = $qz / sqrt(1-$qw*$qw);
 
echo "$angle $x $y $z";
 
?>