Fil d'Ariane
Mis à jour le jeudi 31 août 2017
  • 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Modélisez des objets simples

Connectez-vous ou inscrivez-vous pour bénéficier de toutes les fonctionnalités de ce cours !

Nous voilà avec une scène avec un sol et une sphère au centre. Super ! Mais on ne comprend pas bien à quoi sert tout ce que nous avons développé. Nous allons décortiquer cela ici et comprendre pas à pas comment les objets fonctionnent. Vous irez aussi explorer quelques fonctions de transformation. Enfin, nous partirons dans le monde magique des matériaux de base. Allez, il est temps de s'y mettre !

Les meshes de base

Avant de commencer quoi que ce soit, supprimez les deux objets sphere et ground : nous allons retravailler l'arène ensemble. Au final, votre fichier  Arena.js doit ressembler à ça :

Arena = function(game) {
    // Appel des variables nécessaires
    this.game = game;
    var scene = game.scene;

    // Création de notre lumière principale
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
};

De très nombreux meshes de base peuvent être créés dans BabylonJS en une ligne de code. Nous allons en étudier les plus importants : Grounds, Carré, Sphère, Cylindre. La structure est extrêmement similaire pour les autres objets. 

Les paramètres des objets

Tous les objets ont des propriétés communes qui sont résumées ici :

  •  name correspond à une chaîne de caractères qui sera l'id de l'objet.

  •  size correspond à la taille de l'objet.

  •  scene est la scène dans laquelle l'objet sera créé.

  •  updatable désigne si le mesh sera modifié après sa création (changement de taille ou des propriétés du mesh). Sa valeur est true ou false.

  •  orientation correspond au sens dans lequel les faces seront affichées.

  •  subdivision indique le niveau de détail de l'objet (plus cette valeur sera grande, plus l'objet sera détaillé.

Grounds

Pour créer un plan, voici le code correspondant :

var ground = BABYLON.Mesh.CreateGround(name, width, depth, subdivision, scene);
  •  width permet d'indiquer la largeur du plan.

  •  depth permet d'indiquer la profondeur du plan.

Cube

La ligne pour ajouter un cube est la suivante :

// Version simplifié
var box = BABYLON.Mesh.CreateBox(name, size, scene);

// Version complète
var box = BABYLON.Mesh.CreateBox(name, size, scene, updatable, orientation);

 Sphère

La sphère est créée grâce à ces lignes :

// Version simplifiée
var sphere = BABYLON.Mesh.CreateSphere(name, segments, size, scene);

// Version complète
var sphere = BABYLON.Mesh.CreateSphere(name, segments, size, scene, updatable,  orientation);

segments, comme  subdivision, augmente la qualité de l'objet si le nombre est élevé. Ce nombre correspond au nombre de segments du cercle.

Cylindre

La création du cylindre est la plus complexe des quatre objets ici. Voici le code :

// Version simplifiée
var cylinder = BABYLON.Mesh.CreateCylinder(name, height, diamTop, diamBottom, tesselation, subdivision, scene);

// Version complète
var cylinder = BABYLON.Mesh.CreateCylinder(name, height, diamTop, diamBottom, tesselation, subdivision, scene, updatable, orientation);
  •  height ajuste la hauteur du cylindre.

  •  diamTop change la largeur du cercle en haut de la colone.

  •  diamBottom change la largeur du cercle en bas de la colonne.

  •  tesselation, comme  subdivision, ajuste la qualité de l'objet rendu.

Avec ces quatre objets, nous allons réaliser ceci :

Trois cubes et un cylindre posé sur un sol, positionné et avec un material
Trois cubes et un cylindre posés sur un sol, positionnés et avec un material

Je vois comment créer les objets, mais nous n'avons pas encore vu comment les positionner ou leur ajouter un matériau !

Nous allons y venir ! Commencez par créer les objets, les positionner puis nous nous occuperons de leur ajouter un matériau.

Une première arène !

Créez tout d’abord le sol. En reprenant ce que vous avez créé plus haut, vous allez affecter un sol de 20 de largeur et de profondeur.

// Ajoutons un sol de 20 par 20
var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 2, scene);

Après cela, il faut ajouter les quatre cubes. Ils ont la même taille et les mêmes propriétés. Nous allons donc voir une fonction simple, mais extrêmement pratique :  Mesh.Clone.

// Notre premier cube qui va servir de modèle
var mainBox = BABYLON.Mesh.CreateBox("box1", 3, scene);

// Les trois clones
var mainBox2 = mainBox.clone("box2");
var mainBox3 = mainBox.clone("box3");
var mainBox4 = mainBox.clone("box4");

Enfin, nous allons ajouter notre cylindre. Il fera 20 de hauteur, 5 de diamètre en haut et en bas, aura 20 de tesselation et 5 de subdivision.

// Cylindre -> 20 de hauteur, 5 de diamètre en haut et en bas, 20 de tesselation et 4 de subdivision
var cylinder = BABYLON.Mesh.CreateCylinder("cyl1", 20, 5, 5, 20, 4, scene);

Réactualisez votre page web, le résultat doit ressembler à ça :

Nos 5 mesh, sans positionnement
Nos 5 mesh, sans positionnement

Vu qu'ils sont tous au même endroit, il est normal de ne voir que le plan et le cylindre. Vous allez maintenant les positionner dans la scène.

Positionnement des meshes dans la scène

Pour observer l'effet de chaque modificateur sur nos meshes, nous allons les utiliser chacun différemment.

Ground

var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 2, scene);
ground.scaling = new BABYLON.Vector3(2,10,3);

Je vois que le mesh a bien été multiplié par 2 sur l'axe X et 3 sur l'axe Z, mais rien sur l'axe Y. 

Vous pouvez aussi modifier un mesh sur un seul axe, comme ceci : 

var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 2, scene);
ground.scaling = new BABYLON.Vector3(2,10,3);
ground.scaling.z = 2;

Comme vous le voyez, l'objet regagne sa taille sur l'axe Z.

Cubes et cylindre

Nous allons effectuer un scaling sur Y différent pour chaque box et les positionner sur X, Y et Z. Nous allons dans le même temps modifier l'axe Y du cylindre.

// SUR TOUS LES AXES Y -> On monte les meshes de la moitié de la hauteur du mesh en question.
var mainBox = BABYLON.Mesh.CreateBox("box1", 3, scene);
mainBox.scaling.y = 1;
mainBox.position = new BABYLON.Vector3(5,((3/2)*mainBox.scaling.y),5);
mainBox.rotation.y = (Math.PI*45)/180;

var mainBox2 = mainBox.clone("box2");
mainBox2.scaling.y = 2;
mainBox2.position = new BABYLON.Vector3(5,((3/2)*mainBox2.scaling.y),-5);

var mainBox3 = mainBox.clone("box3");
mainBox3.scaling.y = 3;
mainBox3.position = new BABYLON.Vector3(-5,((3/2)*mainBox3.scaling.y),-5);

var mainBox4 = mainBox.clone("box4");
mainBox4.scaling.y = 4;
mainBox4.position = new BABYLON.Vector3(-5,((3/2)*mainBox4.scaling.y),5);

var cylinder = BABYLON.Mesh.CreateCylinder("cyl1", 20, 5, 5, 20, 4, scene);
cylinder.position.y = 20/2;

Il y a beaucoup de code nouveau !

On va voir ça ligne par ligne sur  mainBox. Les autres meshes suivent la même logique.

mainBox.scaling.y = 1;

Cette ligne signifie que l'on va multiplier la taille de l'objet (scaling) sur l'axe Y de 1. Pour tout dire, cela revient à ne rien changer. Cela a cependant une importance pour  mainBox2,  mainBox3 et mainBox4 qui voient leur taille augmenter significativement.

mainBox.position = new BABYLON.Vector3(5,((3/2)*mainBox.scaling.y),5);

Ici nous déplaçons l'objet d'un seul coup sur les 3 axes. Les axes X et Z déplacent l'objet autour du cylindre alors que Y s'occupe de "remonter" le mesh.

Pour détailler le calcul, l'objet fait une taille de 3. Pour le déplacer de la moitié vers le haut, nous divisons donc cette valeur par deux. Puis, vu qu'on augmente la hauteur (scaling sur Y), on multiplie cette valeur par la valeur de scaling.

mainBox.rotation.y = (Math.PI*45)/180;

Ici, vu que les valeurs de rotation sont en radians, nous convertissons 45 degrés en radians avec cette formule mathématique.

Vous pouvez enregistrer tout cela et voir ce que cela donne ! :)

Nous n'avons modifié que la rotation du premier objet, mais tous les autres ont aussi tourné. Pourquoi ?

Cela, c'est dû à la fonction clone() que nous avons utilisée plus haut ! Les rotations affectées au premier objet sont aussi affectées aux objets créés grâce au clonage. Nous verrons plus tard comment faire en sorte que ces objets soient tous parentés les uns au autres, mais nous n'en avons pas besoin pour l'instant.

Parenté ? Qu'est ce que cela signifie ?

Ajouter un matériau à nos objets

Une dernière chose, mais pas des moindres nous attend avec les meshes, les matériaux. De base, BabylonJS applique un material standard blanc à nos objets. Nous allons voir ici comment le changer.

Créer un material

Un material, c'est un objet JavaScript comme un autre, qui n'a cependant aucune forme physique. Il sera simplement appliqué à un mesh. Pour ajouter un material, voilà le code :

var materialGround = new BABYLON.StandardMaterial("groundTexture", scene);

Il vous faut ajouter cette ligne de code avant tous les autres objets. Les propriétés des matériaux sont très nombreuses, mais une règle est essentielle pour comprendre les trois types d'application d'un material.

Avec cela, nous allons pouvoir définir soit une image soit une couleur comme matériau.

Nous allons ici utiliser uniquement des  diffuseTexture. Pour cela, nous allons récupérer deux textures pour notre scène : de la pierre et du bois. Ces images, vous allez les mettre dans notre dossier  images dans  assets après les avoir respectivement renommées brick et wood.

Pour ajouter une  diffuseTexture, voilà la ligne nécéssaire :

materialGround.diffuseTexture = new BABYLON.Texture("assets/images/brick.jpg", scene);

Maintenant que la texture a été créée, il faut désormais changer sa taille pour lui donner un aspect plus réaliste.

var materialGround = new BABYLON.StandardMaterial("groundTexture", scene);
materialGround.diffuseTexture = new BABYLON.Texture("assets/images/brick.jpg", scene);
materialGround.diffuseTexture.uScale = 4.0;
materialGround.diffuseTexture.vScale = 4.0;

La texture est à la bonne taille et possède désormais une image à afficher. Maintenant, vous devez l'ajouter à  ground. Vous allez devoir appeler le  material après avoir effectué le  scaling :

var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 2, scene);
ground.scaling = new BABYLON.Vector3(2,10,3);
ground.scaling.z = 2;
ground.material = materialGround;

Voilà une première texture d'ajoutée à notre composition ! Nous allons maintenant pouvoir faire de même avec le cylindre et les cubes. Vous n'avez besoin de créer qu'un seul material que vous affecterez à tous les cubes.

Le code final de Arena.js pour cette section doit ressembler à cela :

Arena = function(game) {
    // Appel des variables nécéssaires
    this.game = game;
    var scene = game.scene;

    // Création de notre lumière principale
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 20, 0), scene);

    // Material pour le sol
    var materialGround = new BABYLON.StandardMaterial("wallTexture", scene);
    materialGround.diffuseTexture = new BABYLON.Texture("assets/images/brick.jpg", scene);
    materialGround.diffuseTexture.uScale = 4.0;
    materialGround.diffuseTexture.vScale = 4.0;

    // Material pour les objets
    var materialWall = new BABYLON.StandardMaterial("groundTexture", scene);
    materialWall.diffuseTexture = new BABYLON.Texture("assets/images/wood.jpg", scene);

    // Ajoutons un sol pour situer la sphère dans l'espace
    var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 2, scene);
    ground.scaling = new BABYLON.Vector3(2,10,3);
    ground.scaling.z = 2;
    ground.material = materialGround;

    // SUR TOUS LES AXES Y -> On monte les meshes de la moitié de la hauteur du mesh en question.
    var mainBox = BABYLON.Mesh.CreateBox("box1", 3, scene);
    mainBox.scaling.y = 1;
    mainBox.position = new BABYLON.Vector3(5,((3/2)*mainBox.scaling.y),5);
    // Vu que cet objet sert de clone pour les autres, les deux valeurs ci-dessous sont clonées
    mainBox.rotation.y = (Math.PI*45)/180;
    mainBox.material = materialWall;

    var mainBox2 = mainBox.clone("box2");
    mainBox2.scaling.y = 2;
    mainBox2.position = new BABYLON.Vector3(5,((3/2)*mainBox2.scaling.y),-5);

    var mainBox3 = mainBox.clone("box3");
    mainBox3.scaling.y = 3;
    mainBox3.position = new BABYLON.Vector3(-5,((3/2)*mainBox3.scaling.y),-5);

    var mainBox4 = mainBox.clone("box4");
    mainBox4.scaling.y = 4;
    mainBox4.position = new BABYLON.Vector3(-5,((3/2)*mainBox4.scaling.y),5);

    var cylinder = BABYLON.Mesh.CreateCylinder("cyl1", 20, 5, 5, 20, 4, scene);
    cylinder.position.y = 20/2;
    cylinder.material = materialWall;

};

Encore une fois, vous pouvez voir que la fonction  clone() nous a permis d'économiser des lignes de code en partageant son  material avec les objets clonés. Avec cela, vous n'avez donc eu qu'à définir une seule fois le material pour toutes les Box.

  

Et voilà ! Nos objets sont créés et placés sur un plan avec de bien belles textures ! Amusez-vous à modifier ce que nous avons ici ! Vous devez bien comprendre ces transformations car elles seront présentes à chaque recoin de notre jeu.

Allez, direction les lumières et les caméras, il est temps de voir ce que nous pouvons faire avec cela ! :)‌

Exemple de certificat de réussite
Exemple de certificat de réussite