Modèles et Textures : Havok et Collision Boxes (Confirmé)
Note : Cet article et celui-là sont complémentaire pour une grosse partie des informations. Celui-ci étant plutôt théorique et l'autre plutôt pratique. Il est conseillé de lire les 2.
Ainsi donc, vous avez modélisé, texturé l'objet dont vous rêviez et l'avez implémenté dans le jeu ? Bonne nouvelle. Des tas de modeurs ne sont pas allés aussi loin dans cet effort. Mais avant de retirer votre casquette de modélisateur, il vous reste encore une tâche à accomplir : l'intégration du comportement physique de votre modèle.
Pour les armes, le mauvais placement des boîtes de collision provoquera la disparition inopportune de votre objet à travers le sol, ou bien des rebonds peu naturels et d'autres problèmes mineurs. Pour les modèles fixes, un mauvais placement des meshes de collision donne des résultats carrément désastreux.
En l'absence d'un exporteur officiel de fichiers .nif, gérer la physique et les collisions n'est pas si simple. Comme toutes les méthodes actuelles d'édition de modèles, la technique qui suit est assez artisanale et en conséquence, imparfaite. Et comme pour tout ce qui concerne la modélisation pour Oblivion, un grand remerciement revient à l'équipe des Niftools, sans qui aucun de nos projets ne serait réalisable.
Les Blocks principaux
Avant de discuter de comment ajouter des Blocks Havok, ça peut être utile de décrire un peu ce qu'ils sont et ce qu'ils font. En jetant un oeil à n'importe quel .nif vous devriez pouvoir deviner tout ça par vous-même relativement facilement, mais juste pour vous simplifier la tâche :
bhkCollisionObject
C'est la base du collision object (de l'objet de collision) dans un nif. Chaque NiNode peut contenir un, et un seul, bhkCollisionObject. Mais bien sûr, un nif peut contenir plusieurs NiNodes et donc plusieurs collision objects. (Ce qui sera utilisé plus loin dans ce tutorial).
bhkRigidBody
Tout comme le NiNode se réfère à un collision object, le collision object se réfère à un rigid body. C'est le premier des blocks qu'il est important de configurer correctement (dans les Block Details) :
- Shape : Indique l'objet filaire en lui-même qui définit la forme du collision object. On y revient de suite.
- Layer : Détermine la couleur des boîtes de collision dans le Construction Set.
- Translation / Rotation : Gère la position des shapes (formes) dans l'espace.
- Center : Le centre de gravité.
- Mass : La masse. Se comporte globalement comme on s'y attend, excepté le fait qu'elle n'affecte pas la vitesse de chute des corps. Ceci étant contrôlé par l'attribut suivant :
- Linear / Angular Damping : Une force appliquée dans le sens opposé à la direction du mouvement de l'objet. La puissance de cette force est spécifiée par un nombre entier de maximum 100. En modifiant cette valeur sur le squelette des personnages, il a été possible de changer la vitesse à laquelle le corps chute.
- Friction & Restitution : Ces propriétés affectent la vitesse de la… perte de vitesse des objets lorsqu'ils entrent en contact ou glissent contre un autre objet (l).
- Motion System & Quality Type : Ce qu'il y a de plus important à connaître à propos de ces propriétés, ce sont ces deux combinaisons : MS - 7; QT - 1 : donnera un objet statique (ex : architecture) ; MS-3; QT- 4 : donnera un objet déplaçable (ex : armes, vêtements, etc).
Shapes
Comme indiqué ci-dessus, le block bhkRigidBody sera parent d'une shape. Beaucoup des modèles originaux la shape bhkConvexVerticesShape, qui enveloppe précisément la géométrie du modèle (le Trishape). Pour nous elles sont inutilisables, pour plusieurs raisons que je ne détaille pas. Nous avons besoin de formes plus génériques. Les deux plus polyvalentes et pratiques à utiliser sont la bhkBoxShape et la bhkCapsuleShape.
Les Shapes ont une propriété Material (matériau) qui définit entre autres le son produit par un choc de l'objet.
bhkConvexTransformShape
C'est un des blocks en relation avec le Havok les plus utiles, comme le montre le tutorial ci-dessous. Son attribut de contrôle Transform de type Matrix 44 permet de modifier la rotation et translation des bhkBoxShape qu'il contrôle. Par contre, N'UTILISEZ PAS la fonction scale (redimensionner) de ce block. Changer la taille des shapes par ce moyen donnera le résultat attendu pour la boîte de collision normale, mais n'affectera pas la taille des ces boîtes telle que détectée par les flèches ! Pour le redimensionnement, il faut alors utiliser les paramètres de type Vector3 des blocks de shapes.
Bâtir un modèle de collision
Etape 1
- Créez un fichier .nif de votre modèle personnalisé. Peu importe comment vous faites cela (en exportant un nif ou en important un obj dans un nif préexistant). Il vous faut maintenant assembler vos blocks Havok. Si vous avez importé un obj, vous devriez déjà avoir le block bhkCollisionObject et sa structure associée ; laissez tout ça en place mais supprimez les blocks de shape. Si vous avez exporté votre nif depuis Blender ou 3dsmax, vous pouvez faire un copy/paste du bhkCollisionObject d'un nif officiel.
- Regardez votre maillage et évaluez la quantité de boîtes et capsules dont vous avez besoin. Vous pouvez récupérer ces deux shapes dans les nifs d'armes du jeu : les épées contiennent des capsules et les haches contiennent les deux types. Copiez/collez-en autant qu'il vous en faut dans votre nif.
- Pour chaque box shape, vous aurez aussi besoin d'un block bhkConvexTransformShape. Celui-ci peut aussi être copié depuis un nif de hache et d'ailleurs vous pouvez copier toute la branche (incluant donc la shape), ce qui vous évite de devoir refaire les liens de parents/enfants ultérieurement.
- Enfin, vous aurez besoin du block bhkListShape. Celui-ci aussi peut être trouvé dans un nif d'arme. Et là aussi, vous pouvez en fait copier/coller toute la branche.
Etape 2
Maintenant vous devez connecter tous ces block.
- Assignez le bhkListShape à l'attribut Shape du bhkRigidBody.
- Dans l'attribut Num Sub Shapes du bhkListShape, indiquez le nombre de shapes que vous avez créées au début
- Updatez l'Array de l'attribut Sub Shapes.
- Entrez les numéros de vos shapes dans les nouveaux emplacements de sub shapes. (Pour les bhkBoxShape qui utilisent un bhkConvexTransformShape, c'est ce dernier que vous devez référencer dans les sub shapes)
Ensuite vient la partie fatigante de ce processus. Havok requiert une séquence des blocks (leur numérotation) bien précise pour le collision object.
- Fermez les Block Details et Ouvrez la Block List. Celle-ci affiche tous les block dans l'ordre de leur numérotation.
- En faisant clic-droit-->Block-->Move up/Move Down sur un block, vous pouvez changer sa position dans l'ordre des blocks. La séquence doit être ainsi :
0: NiNode ;
1: (Plus éventuellement 2 et 3) Sera le block BSX, UPB et/ou PM, selon le type de nif que vous créez ;
2: Vient ensuite la première de vos bhk shapes. Si c'est une box shape avec un bhkConvexTransformShape, la box shape vient d'abord et son ConvexTrucMachin en-dessous. Puis vient la shape suivant, etc.
n: Après avoir listé toutes vos shapes, vient la bhkListshape ;
n+1: Puis le bhkRigidBody;
n+2: Le bhkCollisionObject;
n+3: Et enfin les blocks trishape/strips. (Note du traducteur : Peu importe l'ordre ici je crois.)
En testant votre mod, si le jeu plante avant même d'avoir fini le chargement, c'est probablement à cause d'une erreur dans cette séquence.
(Ndt : C'est vrai que c'est épuisant tout ça. J'espère que c'est bien nécessaire. En tout cas on peut faire en sorte de s'épargner une partie de ce travail en important son modèle dans un nif tout bien ordonné et en rajoutant des boîtes et des capsules dans la bhkListShape. Il faudra cependant suivre le processus de réorganisation ci-dessus pour ces ajouts.)
Etape 3
Vous avez maintenant un nif fonctionnel contenant plusieurs meshes de collision. Il vous reste à arranger ces boîtes et capsules comme vous le voulez.
- La manipulation des capsules est décrite dans l'autre tutorial.
- Pour manipuler les box shapes, utilisez leur ConvexTransformShape pour la rotation et la translation (faites clic-droit-->Edit Matrix sur l'attribut Transform). Pour les redimensionner, modifiez l'attribut Dimensions du bloc bhkBoxShape.
Voilà pour les bases.