Modèles et Textures : Havok et Collision Boxes (Confirmé)

De Wiwiki
Sauter à la navigation Sauter à la recherche


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 deux.

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 - Méthode basique

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. /!\ Oyé ! Avec la version 0.8.8 de Nifskope, il existe une fonction de réorganisation automatique des blocs dans le menu Spells > Sanitize > Reorder Havok Blocks. Elle fonctionne très bien dans certains cas, et dans d'autres, vous devrez quand même repasser derrière elle et corriger ses erreurs en appliquant la méthode ci-après.

  • 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.


Bâtir un modèle de collision personnalisé - Méthode avancée

Les utilisateurs de 3DSmax peuvent dorénavant utiliser le plugin de Gundulf qui peut générer "automatiquement" des modèles de collision à l'export. Vous trouverez un lien de téléchargement et un tutorial pour l'utiliser [ici]. Les utilisateurs de ce plug-in pourront cependant trouver de l'intérêt à la lecture de ce tutorial pour Nifskope parce qu'il propose de faire à la main la manipulation qu'effectue automatiquement le plug-in.

Quand à ceux d'entre vous qui n'ont pas la chance d'avoir 3DSmax, eh bien ce tutorial vous est dédié puisque vous allez pouvoir - avec un peu plus de travail - créer vous aussi des modèles de collision personnalisés et optimisés pour vos nouveaux objets. Mais tout d'abord, un peu de mise en garde :

ATTENTION !
La technique suivante génère des objets de collision plus consommateurs de ressources processeur qu'avec la technique simple utilisant boîtes et capsules. Comme nous allons travailler avec des TRIstrips, les quads de vos maillages seront subdivisés en triangles ; cela signifie qu'une simple boîte aura 12 faces et non seulement 6 (ça reste acceptable dans ce cas, hum hum). Pour la détection des collisions, le moteur physique fait un calcul pour chaque face du maillage, donc vous êtes fortement encouragés à faire de votre mieux pour simplifier vos modèles de collision, de manière à avoir le minimum de faces.
Autant que faire se peut, la technique suivante devrait être combinée avec l'utilisation de boîtes et capsules pour les parties qui ne nécessitent pas un haut niveau de précision.

Etape 1

Lorsque vous avez un objet fini, vous devez en faire une version simplifiée dans votre logiciel de modélisation.
Une manière de faire est de dupliquer votre objet dans une nouvelle couche (layer) et de le massacrer consciencieusement. Votre objectif est de réduire le nombre de polygones autant que possible. Cela peut être fait à la main ou à l'aide d'un script de simplification de maillage qu'inclue éventuellement votre logiciel.

Les utilisateurs de Blender pourront utiliser le modifier decimate. Voir les détails ici.
Mieux encore, le script PyRedux de IdeasMan. Disponible ici (Plus bas dans la page).

N'oubliez pas que toutes les parties qui ne nécessitent pas plus qu'une bhkBox ou Capsule peuvent être omises dans ce modèle que vous fabriquez.
(Ndt : Personnellement, je trouverais plus rapide de modéliser des boîtes et les ajouter au modèle directement dans le logiciel de modélisation.)

Si votre modèle est constitué de différents matériaux (maison en bois et pierre par exemple), vous devrez séparer les parties de différentes matières et les exporter comme modèles séparés (un fichier par matériau).

Exportez votre objet puis votre futur objet de collision (en .nif ou .obj, peu importe).

Etape 2

Si vous avez exporté vos fichiers en .obj, importez-les chacun dans un nif séparé.

Si vous avez supprimé des parties dans votre modèle de collision avec l'intention de les remplacer par des bhkBox ou Capsules, c'est le moment de le faire.

Et maintenant, allons-y pour la conversion de vos NiTriStrips en objets de collision :

  • La première chose dont vous allez avoir besoin est un bloc bhkNiTriStripsShape. Vous pouvez en trouver un dans le nif suivant : data\meshes\dungeons\ayleidruins\exterior\arstatue01.nif
  • Sélectionnez ce bloc dans la Block List (sous bhkCollisionObject > bhkRigidBodyT) puis dans les Block Details vous devriez trouver Num Strips Data, suivi par un attribut déroulant indiquant quel bloc contient les strips data.
  • Pour le moment, mettez -1 dans le champ value des Strips Data. (Cela évite des confusions au collage.)
  • Copiez le bloc et collez-le dans le nif de votre objet.

(Ne sauvegardez pas les changements dans arstatue01.nif !)

Etape 3

  • Dans une nouvelle fenêtre Niskope, ouvrez le nif de votre modèle de collision.
  • Copiez son bloc NiTriStripsData (sous le bloc NiTriStrips)et collez-le dans le nif de votre objet.

Vous pouvez fermer la deuxième instance de Nifskope.

  • Sélectionnez le bhkTriStripsShape que vous avez copié/collé à l'étape 2. Dans les block details, changez la valeur des Strips Data (que vous avez passée à -1 dans l'étape 2) pour le numéro du bloc NiTriStripsData que vous venez de coller.
  • Répétez cette étape si vous avez plusieurs fichiers pour votre modèle de collision.

Etape 4

À partir de là, le processus est globalement le même qu'à partir de l'étape 2 de la méthode basique, en terme de liaisons des blocs et de réorganisation de la liste des blocs (le bloc bhkNiTriStripsShape peut être traité comme n'importe quel autre bloc bhk) :

  • Donnez à ce dernier l'attribut Material que vous souhaitez.
  • Indiquez-le comme enfant du bhkRigidBody.
  • (Ndt : Je suppose que si vous avez séparé votre objet de collision en plusieurs parties, ou que vous utilisez des Box ou Capsules, il vous faut coller une bhkListShape et placer tous vos bhkMachins dedans.)
  • Réarrangez l'ordre des blocs correctement.

C'est fini !