Utiliser les objets primitifs

Le concept derrière les objets primitifs (en bref, primitives) est de vous donner la possibilité de créer facilement des scènes 3d simples. Un grand choix de primitives peut ainsi être rendues de manière très efficace. Définir un objet dans Ultimate 3D fonctionne de la façon suivante. Comme je l'ai déjà dit, chaque objet dans Ultimate 3D doit être représenté par une instance d'objet dans Game Maker. Donc, vous devez créer un nouvel objet d'abord. Ensuite, vous devez définir un ensemble de variables pour cet objet. Enfin vous appelez une fonction qui transmet les valeurs des variables à Ultimate 3D et crée votre objet. Nous pouvons commencer avec un premier objet visible.

L'Objet Wall (mur)

Un objet wall est totalement plat et orienté verticalement. Avant de le créer, vous devez définir les variables suivantes:

height
Cette variable indique la hauteur du mur.

x2, y2
Ces deux variables indiquent jusqu'où le mur va à partir de ses positions x et y. Le graphique suivant l'illustre:

PrimitiveWallP2

Illustration not available

texture
Vous devez assigner cette variable à l'un des indices que vous aviez attribué précedemment à une texture lors de l'utilisation de la fonction LoadTexture(...). Cette texture sera alors utilisée pour le mur. Si vous ne souhaitez pas utiliser une texture, vous pouvez définir cette variable à -1.

texx1, texy1, texx2, texy2 (optionnel)
Ces variables sont facultatives. Si vous n'avez pas définit ces variables, toute la texture sera utilisée. Ils définissent les deux prétendues coordonnées de la texture. Les coordonnées de texture x = 0 et y = 0 (en bref (0|0)) se réfèrent à la partie supérieure gauche de la texture. Les coordonnées de texture (0.5|0.5) correspondent au milieu d'une texture, les coordonnées de texture (0|1) à la partie inférieure gauche de la texture, les coordonnées de texture (1|1)  à la partie inférieure droite, et ainsi de suite. L'objet mur utilisera la partie de la texture qui se trouve entre les deux données des coordonnées de la texture. Les coordonnées de texture peuvent aussi être faites pour des valeurs plus grandes que 1. Ensuite, la texture sera appliquée (de la même façon que le tuilage mais pour les textures)

Il y a deux variables supplémentaires qui sont utilisées pour les murs mais pour l'instant, vous n'avez pas besoin de les connaitre. Les primitives Floor et Cube les possèdent elles aussi. Elles sont décrites dans le tutorial "Ajout de lumières".

Maintenant que vous avez mis en place toutes les variables requises, vous pouvez appeler CreateWall()une fois. Cette fonction ne prend aucun paramètre. Elle reçoit toutes les informations nécessaires à partir des variables. Cependant, il faut mettre Step() dans l'évènement step de l'objet et Destroy(), dans l'évènement destroy de ce dernier. Aucune de ces fonctions ne requièrent de paramètres. Destroy() doit être mis dans l'évènement destroy parce qu'autrement Ultimate 3D ne saurait jamais quand l'instance serait détruite. Dans ce cas, l'instance ne disparaîtrait tout simplement pas. Ce que Step() fait est le thème de la prochaine partie de ce tutoriel. Donc accrochez-vous ! ;) .

Transformation des primitives

Transformer... étrange mot. Cela paraît un peu compliqué, n'est-ce pas ? Eh bien, n'ayez pas peur, vous savez déjà comment transformer quelque chose; vous ne saviez juste pas que c'était appelé "transformation". Transformer quelque chose implique de changer son orientation. Si vous prenez un objet et le déplacez, c'est une transformation. Si vous le faite pivoter c'est une transformation aussi. Il y a une transformation qui ne peut se faire dans la vraie vie, mais vous le savez déjà de la 2D: scaler quelque chose. Scaler décrit les moyens de changer la taille d'un objet. Un objet peut être extrapolé (scalé) sur trois axes. Tous ces processus sont appelés transformations. Donc, la chose qu'il faudra retenir est que la transformation est la combinaison du scaling (changement de taille), la rotation et la translation (déplacement).

Et maintenant pour transformer les primitives. Vous savez comment le faire, car vous avez transformé un autre objet avant (si vous lisez ce tutorial complètement): l'objet caméra. Comme l'objet caméra, chaque objet primitif contient les variables x, y, z, rotx, roty et rotz. En outre, il gère également les variables scalx, scaly, scalz. Etant donné que l'explication de l'utilité de rotx, roty et rotz n'était pas détaillée dans le tutorial à propos des Objets caméras, voici une description plus détaillée, ainsi qu'une description de scalx, scalyet scalz.

rotx, roty, rotz
Comme je l'ai déjà dit dans le tutoriel sur les Objets caméras, la variable rotx donne la rotation de l'objet (le pitch), la variable roty donne la rotation de lacet (yaw) et la variable rotz donne la rotation de roulis (roll). Le schéma ci-dessous illustre l'effet de ces variables.

PrimitiveRotation

Illustration not available

Incrémenter rotx pivotera le nez de l'avion vers les bas, décrémenter rotx pivotera le nez de l'avion vers les haut. La rotation de lacet : yaw (roty) dirige l'objet sans changer sa coordonnée z. Enfin, il y a la rotation de roulis (roll). Je pense qu'il n'y a rien de plus à dire à propos. Notez que la rotation de roulis (roll) est appliquée en premier, ensuite la rotation pitch et seulement la rotation de lacet (yaw) est réalisée.
Un bref commentaire à ce sujet: Si vous avez lu attentivement, vous aurez peut-être remarqué que roty tourne autour de l'axe z alors que rotz tourne autour de l'axe des ordonnées (y). Cette petite incohérence est un vestige de la première version d'Ultimate 3D. Ces variables sont nommées selon le système de coordonnées qui est utilisé par Ultimate 3D en interne. Vous n'avez pas besoin de pécisions à ce sujet, il suffit de garder à l'esprit que roty tourne autour de l'axe z et rotz tourne autour de l'axe des ordonnées (y).

scalx, scaly, scalz
La notion de changement d'échelle (scaling) est très facile à comprendre. Une échelle d'une valeur 1 signifie que rien ne change, une échelle de valeur de 2 signifie que tout devient deux fois plus important, et une échelle de valeur de 0.5 signifie que tout devient moitié de la taille. Habituellement, vous ne devez pas utiliser d'échelle de valeur négative. La seule chose qui me reste à vous expliquer est pourquoi, il y a trois valeurs d'échelle (scaling). Parce que de cette façon vous avez la possibilité de scalé la grosseur de l'objet indépendamment dans les trois axes (x, y et z) du système de coordonnées 3D. Mais dans la plupart des cas, vous voudrez scaler votre objet de la même manière tout au long des trois axes, vous devrez alors définir la même valeur pour les trois axes d'échelle. Notez que le scaling se fait avant la rotation.

Une autre chose que vous ne devez jamais oublier, c'est que chaque objet Ultimate 3D doit contenir un appel à la fonction Step() dans leur évènement step. Sinon, les variables n'auront pas d'incidence sur la transformation du modèle!

Objets Sol

Les objets Floor n'ont pas de taille le long de l'axe z, ce qui signifie qu'ils sont totalement plats et horizontaux. Les variables que vous devez mettre en place avant la création d'objets Floor sont les suivantes:

width, height
width décrit la taille du sol le long de l'axe x et height la taille du sol le long de l'axe y.

texture
Indice de la texture qui va être utilisée pour cet objet ou -1 pour aucune. Pour une description plus détaillée, allez jeter un oeil sur le texte d'Objets Wall.

texx1, texy1, texx2, texy2 (optionnel)
La partie de la texture qui va être utilisée. Pour une description plus détaillée, allez jeter un oeil sur le texte d'Objets Wall.

Comme vous pouvez le voir, il n'y a pas beaucoup de changement par rapport aux objets wall. À nouveau, il y a deux autres variables qui seront introduites dans le tutorial à propos des sources de lumière. Après l'affectation de ces variables, vous devez appeler CreateFloor()pour initialiser l'objet floor. Et comme d'habitude, vous avez besoin de Step() et Destroy() dans les événements correspondants.

Objets Cube

Les objets cube sont un peu plus complexes que les sols et les murs, mais ils peuvent être utilisés pour des choses plutôt cool. Dans l'ancienne démo d'Ultimate 3D v. 1.31 tous les bâtiments étaient constitués de simples cubes. Comme avec d'autres primitives, vous devez configurer plusieurs variables avant de pouvoir créer un cube. Voici une liste de ces dernières:

width, height, depth2
Les dimensions du cube. width donne la largeur du cube (axe x), depth2 donne la profondeur du cube, soit sa taille sur l'axe y et height donne la taille du cube sur l'axe z. depth2 s'appelle "depth2" au lieu de "depth", parce que la variable depth est déjà utilisée par Game Maker.

texx1, texy1, texz1, texx2, texy2, texz2 (optionnel)
La partie de la texture qui va être utilisée. Pour une description plus détaillée de ces paramètres, allez jeter un oeil sur le texte des Objets Wall. Etant donné que les objets cube sont en trois dimensions alors que les murs sont en deux dimensions, les objets ont trois paires de ces paramètres.

texture
L'indice de la texture qui va être utilisée pour cet objet ou -1 pour aucune. Pour une description plus détaillée allez jeter un oeil sur le texte sur les Objets Wall.

subdivide_texture (optional)
Comme chacun le sait, un cube a six faces. Si vous définissez cette variable à "false" toutes les faces utiliseront la même partie de la texture. Si vous la définissez à "true", la texture sera subdivisée en six parties et chaque côté du cube utilisera une autre partie de la texture. Le schéma suivant montre comment cela fonctionne.

PrimitiveDispartTexture

Illustration not available

Quand subdivide_texture est "false", l'ensemble de la texture est affichée de chaque côté. Quand il est "true", chaque côté ne montre qu'une seule partie.

originx, originy, originz (optionnel)
Ces variables prennent habituellement des valeurs dans la fourchette de 0 à 1. Elles définissent où l'origine du cube se trouve. Par exemple, la saisie de 0.5 pour chacune d'entre elle voudrait dire que l'origine du cube se trouve exactement au milieu. Saisir les valeurs correctes pour ces variables est très important, surtout lorsque vous faites pivoter le cube. Le schéma suivant en illustre le mécanisme:

Illustration not available PrimitiveCubeParameters

Après l'affectation de ces variables, vous devez appeler la fonction CreateCube()une fois pour initialiser l'objet cube. Et comme d'habitude, vous avez besoin de Step() et Destroy() dans les événements correspondants.

Objets Billboard

Les billboards diffèrent un peu de tous les autres objets 3D. La raison en est simple. Ils ne sont pas en 3D. Il arrive souvent que de la géométrie extrêmement complexe soit requise pour certains objets. Les arbres sont le meilleur exemple. Pour éviter cette géométrie complexe, vous pouvez utiliser les billboards. Dans les jeux anciens, vous voyez souvent que les arbres sont en 2D alors que tout le reste est en 3D. Voici les billboards. Des billboards sont des objets 2D dans un espace 3D. Ils sont fixés à un point dans un espace 3D et leur taille sur l'écran change en fonction de la distance de la caméra.

Quoi qu'il en soit, la création de billboards n'est pas plus difficile que toute la création d'autres objets primitifs. Voici les variables qui doivent être mise en place pour cela:

width, height
Les dimensions du billboard.

originx, originy
Ces variables définissent l'origine du billboard. L'origine est le point du billboard qui ne change pas de position dans l'espace 3D lorsque la caméra pivote. En général il est quelque part au milieu du billboard. En principe, il fonctionne de la même façon que les variables originx/y/z des Objets Cube. Alors, jetez un coup d'œil à leur description.

texture
Indice de la texture qui va être utilisé pour cet objet ou -1 pour aucune. Pour une description plus détaillée de ces paramètres, allez jeter un oeil au texte d'Objets Wall.

texx1, texy1, texx2, texy2 (optionnel)
La partie de la texture qui va être utilisée. Pour une description plus détaillée de ces paramètres, allez jeter un oeil au texte d'Objets Wall.

Après la mise en place de ces variables, vous devez appeler la fonction Create2D() une fois pour initialiser l'objet billboard. Et comme d'habitude, vous avez besoin de Step() et Destroy() dans les événements correspondants.

Objets Polygônes

Dans la partie de cette documentation destinée aux utilisateurs avancés vous constaterez que tout modèle peut être manipulé comme un objet primitif. Cependant actuellement, vous ne savez pas que les objets polygones sont les primitives les plus complexes que vous allez connaître. Avant de vous dire ce qu'est un objet polygon, je vais vous expliquer que signifie le terme: vertex. Un vertex est un point dans un espace 3D, possèdant les coordonnées d'une texture, faisant partie d'un objet 3D. Un triangle est toujours constitué de trois vertices (sommets) et chaque objet 3D est constitué d'un ensemble de triangles. Donc on pourrait dire des vertices que c'est la plus petite unité des objets 3d.

Les polygones ne sont pas définis par un ensemble de variables. À la place de quoi vous appelez trois fonctions. Vous avez besoin d'une instance d'objet pour chaque objet polygon. La première fonction que vous devez appeler se nomme BeginPolygon(...). Cela informe Ultimate 3D que vous désirez créer un objet polygon et prépare tout ce qui est nécessaire dans ce but. Voici un description de la fonction:

BeginPolygon(
VertexNumber
)

VertexNumber
Le nombre de vertices (sommets) du polygone que vous vous apprêtez à créer. La valeur de cette variable doit toujours être supérieure ou égale à trois, sinon vous n'obtiendrez pas un véritable polygone.

Après avoir appellé BeginPolygon(...) vous devez appeler AddVertex(...) plusieurs fois en fonction de la valeur que vous avez passé à BeginPolygon(...). Voici la description de AddVertex(...):

AddVertex(
X,Y,Z,
U,V
)

X, Y, Z
La position du vertex. Notez que ces positions sont transformées selon les valeurs que vous avez choisies précedemment pour x, y, z, scalx/y/z et rotx/y/z. Ainsi, la position est donnée à l'échelle de l'objet.

U, V
La coordonnée de la texture du vertex. Pour obtenir une description détaillée de ce qu'est une coordonée de texture, lisez la description des variables texx1 et texy1 des Objets Wall.

Lorsque vous avez appelé AddVertex(...) suffisamment, vous pouvez appeler CreatePolygon()pour créer l'objet polygon. Comme pour tous les autres objets primitifs, il possède la variable texture, et les variables de transformation (pour plus d'information jetez un coup d'œil à la description des Objets Wall au sujet de la transformation des primitives). Pour cette raison, vous devez mettre Step() et Destroy() dans les évènements Game Maker correspondants.

Voici un exemple de code qui montre comment créer un objet polygon simple:

BeginPolygon(5);
AddVertex(0,0,0,0,1);
AddVertex(0,0,5,0,0.33);
AddVertex(0,2.5,7.5,0.5,0.0);
AddVertex(0,5,5,1,0.33);
AddVertex(0,5,0,1,1);
CreatePolygon();
texture=1;

Cette image montre le résultat de l'appel de ces fonctions:

PrimitivePolygon

Modifier des objets polygônes

Chacun des vertex d'un objet polygon peut être modifié après la creation du polygône. Pour faire cela, il y a deux fonctions: l'une pour récupérer des données à propos du polygône, et l'autre pour changer ces données. Voici une description de deux d'entre elles:

Cette fonction permet d'extraire des données de l'objet polygône qui appelle la fonction. Elle peut être appelée après CreatePolygon().

GetVertex(
VertexIndex,
ElementIndex
)

VertexIndex
Ce paramètre permet d'identifier le vertex duquel vous souhaitez obtenir des informations. Le vertex qui a été ajouté en premier au polygône a l'indice 0. L'indice le plus élevé valable est VertexNumber-1.

ElementIndex
Ce paramètre indique dans Ultimate 3D quel type d'information doit être récupéré. Voici la signification de chaque valeur:
0 = X;
1 = Y;
2 = Z;
3 = U;
4 = V;

Cette fonction modifie les données de l'un des vertices d'un objet polygône qui appelle la fonction. Elle peut être appelée après CreatePolygon().

SetVertex(
VertexIndex,
X,Y,Z,
U,V
)

VertexIndex
Ce paramètre permet d'identifier le vertex dont vous souhaitez modifier les informations. Le vertex qui a été ajouté en premier au polygône a l'indice 0. L'indice le plus élevé valable est VertexNumber-1.

X, Y, Z
La position du vertex. Pour plus d'informations, jettez un oeil à la description de la fonction AddVertex().

U, V
Les coordonnée de la texture du vertex. Pour obtenir une description détaillée de ce qu'est une coordonnée de texture, jetez un œil à la description des variables texx1 et texy1 Objets Wall.

C'est tout ce dont vous avez besoin pour modifier la géométrie d'un polygone. Voici un exemple pour illustrer cela. Placé dans l'évènement step de l'objet polygone, le troisième vertex se déplace un peu vers le haut à chaque step.

SetVertex(2, GetVertex(2,0), GetVertex(2,1)+0.1, GetVertex(2,2), GetVertex(2,3), GetVertex(2,4));

Changer les matériaux (couleurs) des primitives

Dans sa forme la plus simple, en changeant les matériaux d'un objet on entend "changer sa couleur". Pour ce faire Ultimate 3D dispose d'une fonction très simple:

Cette fonction change l'étoffe (ses couleurs) de l'objet primitive qui est appellé.

SetMaterial(
Red,
Green,
Blue,
Alpha
)

Red, Green, Blue
Ces paramètres définissent la nouvelle couleur qui va être utilisée. Les valeurs des paramètres peuvent être de l'ordre de 0 à 255. (0 | 0 | 0), le noir et (255 | 255 | 255) signifie blanc.

Alpha
Ce paramètre donne l'opacité de l'objet. Il est défini de 0 à 255. 0 signifie qu'il n'y a pas d'opacité (totalement transparent) et 255 signifie qu'il est totalement opaque.

Cette fonction modifie la partie émissive d'un matériau. La partie émissive d'un matériau n'est pas influencée par l'éclairage. Un bon exemple pour un matériau qui devrait utiliser l'éclairage émissif est un écran de TV. Il émet de la lumière ainsi sa luminosité n'est pas relative à la lumière. Vous pouvez également utiliser des matériaux émissifs si vous ne voulez pas que des objets soient influencés par la lumière. Par exemple, il semble généralement assez bizarre que les billboards soient influencés par la lumière.

SetMaterialEmissive(
Red,
Green,
Blue
)

Red, Green, Blue
La couleur qui doit être utilisé pour la partie émissive de la matière. Là encore, les valeurs doivent être contenue entre 0 et 255.

Mise à jour des objets primitifs

Vous savez déjà que vous pouvez changer la transformation d'une primitive après sa création en utilisant les variables x, y, z, rotx/y/z, scalx/y/z. La même chose peut être faite avec la texture. Elle peut être modifiée à tout moment. Mais qu'en est-il des autres propriétés d'une primitive? Par exemple, si vous souhaitez animer une texture en changeant texx1, texy1, texx2 et texy2? Si vous changez ces variables après la création de la ligne primitive, l'objet ne change pas. Pour cette raison, il y a la fonction RecreatePrimitive(). Cette dernière fait exactement ce que son nom indique. Elle détruit les primitives qu'elle recrée ensuite avec les nouvelles données des variables.



© Christoph Peters. Certains droits réservés. (Traduction FR 04/2008, Franck Vernel / Damien Buhl).

Creative Commons License XHTML 1.0 Transitional