- nodeJs v16+
- npm v8.11
- un navigateur web pas trop vieux :-p
- votre IDE préféré (^_^)
- Git
- clonez le projet git en local:
git clone https://github.com/ineat/hands-on-babylon.git
- allez à la racine du projet
- rendez-vous sur la branche step-01:
git checkout step-01
- executez
npm install
- executez
npm run start
- ouvrez votre navigateur sur
http://localhost:5173/
- pensez à coupez votre appli lorsque vous changez de branche
-
Avant d'aller plus loin, prenons le temps de regarder ce projet:
- Dans le fichier
src/components/scene-display/scene-display.vue
:- Dans la fonction
setup
: la référence du canvas est récupérée et passée en attribut interne du composant. - Dans la fonction
mounted
: la référence du canvas est valorisée puis passée dans la fonctioncreateScene
.
- Dans la fonction
- Dans le fichier
src/components/scene-display/scene-display.service.ts
:- Dans la fonction
createScene
: Le moteur de rendu et la scene sont crées. on y rajoute une camera, une source de lumière et des objets à afficher.
- Dans la fonction
- Dans le fichier
-
À vous de jouer!
- Avant de passer à l'étape 2, nous allons nous familiariser la scene. Pour cela, vous pouvez:
- Rajouter un model 3D en utilisant l'api
MeshBuilder
dans la fonctioninitMeshes
(https://doc.babylonjs.com/typedoc/modules/BABYLON#MeshBuilder). - Modifier l'éclairage de la scene en changeant les propriétés de la lumière existante ou en rajoutant une autre source de lumière (une PointLight par exemple).
- Rajouter un model 3D en utilisant l'api
- Avant de passer à l'étape 2, nous allons nous familiariser la scene. Pour cela, vous pouvez:
-
Lorsque vous aurez fini de jouer avec la scene, vous pourrez passer à l'étape suivante :
git checkout .
puisgit checkout step-02
Nous allons voir ensemble comment modifier notre scene à partir du modèle de l'application. Pour cela, nous allons devoir exporter dans un contexte partagé des fonctions qui nous permettront de modifier la scene à partir d'un autre composant. Cette notion de contexte partagé sera prise en charge par Pinia.
-
Dans le fichier
src/model/scene-handler.ts
:- Nous définissons une interface
SceneHandler
qui définit les interactions que nous aurons avec notre scene.
- Nous définissons une interface
-
Dans le fichier
src/stores/scene-handler.ts
:- Nous créons un store
Pinia
avec un état initial et des accesseurs pour gérer les valeurs d'un objet SceneHandler.
- Nous créons un store
-
Dans le fichier
src/components/scene-display/scene-display.vue
:- nous affectons une valeur au currentSceneHandler gérée par
Pinia
- nous affectons une valeur au currentSceneHandler gérée par
-
Dans le fichier
src/components/hands-on/hands-on.vue
:- nous récuperons une référence sur la valeur de
currentSceneHandler
pour en éxecuter les fonctions en cliquant sur un bouton à l'extérieur de notre canvas.
- nous récuperons une référence sur la valeur de
-
À vous de jouer!
- Rendez-vous en
src/components/scene-display/scene-display.service.ts
et implémentez les fonctions dusceneHandler
.
- Rendez-vous en
-
Lorsque vous aurez suffisamment pollué la scene avec des cubes , vous pourrez passer à l'étape suivante :
git checkout .
puisgit checkout step-03
Il est aussi possible de modifier l'état de notre application en intéragissant avec la scene 3D.
Pour cela, il est possible de definir une fonction onPointerDown
de notre objet scene
afin de capter un clique sur notre scene et d'executer un traitement en fonction de l'élément cliqué.
Le cas échéant, nous allons afficher un compteur qui indiquera le nombre fois où on aura cliqué sur la sphere.
-
Dans le fichier
src/stores/counter.ts
:- Nous créons un store
Pinia
avec un compteurcount
et une fonction d'incrément.
- Nous créons un store
-
Dans le fichier
src/components/hands-on/hands-on.vue
:- nous récuperons une référence sur la valeur de
count
pour l'afficher à l'écran.
- nous récuperons une référence sur la valeur de
-
Dans le fichier
src/components/scene-display/scene-display.vue
:- nous récupérons la fonction d'incrément dans
Pinia
afin de la passée danscreateScene
.
- nous récupérons la fonction d'incrément dans
-
À vous de jouer!
- Rendez-vous en
src/components/scene-display/scene-display.service.ts
et implémentezscene.onPointerDown
. - Indice: Vous pouvez regarder la documentation de la classe (PickingInfo)[https://doc.babylonjs.com/typedoc/classes/BABYLON.PickingInfo] de babylonjs.
- Rendez-vous en
-
Après avoir augmenté la valeur du compteur en cliquant sur la sphere , vous pourrez passer à l'étape suivante :
git checkout .
puisgit checkout step-04
Nous allons maintenant rajouter des propriétés physiques à notre scene:
- Dans le fichier
src/components/scene-display/scene-display.service.ts
:- la gravité et la gestion des collisions de la caméra on été activées.
- une ellipsoïde a été affectée à la caméra (ce sera son masque de collision).
- la gestion des collisions et de la gravité a été activée au niveau de la scene
- Si vous essayez de bouger la camera avec le clavier, celle-ci passera à travers le sol.
- À vous de jouer: Activez la gestion des collisions au niveau du sol et de la sphere
Nous allons associer les objets de notre scene à des matériaux:
- Un matériel est une combinaison de textures utilisées pour définir les propriétés optiques d'une surface (voir PBRMaterial).
- Un ensemble de matériaux ont été définis dans le fichier
src/services/material.service.ts
. - À vous de jouer: Affectez des matériaux à la sphere et au sol.
Enfin, nous allons rajouter un émetteur de particule:
- Les particules sont des sprites émis à partir d'une source (voir ParticleSystem)
- Un generateur de particules a été défini dans le fichier
src/services/particles.service.ts
. - À vous de jouer: _Créez un générateur de particules ayant la sphère pour émetteur _
Lorsque vous aurez fini, vous pourrez passer à l'étape suivante : git checkout .
puis git checkout step-05
Dans la pratique, charger des textures comme nous l'avons fait à l'étape précédente peut prendre du temps à cause de la latence réseau. Il est préférable de masquer la scene tant que toutes les ressources ne sont pas chargée. C'est là qu'entre en jeu AssetsManager.
- Dans le fichier
src/components/scene-display/scene-display.service.ts
:- Nous créons une instance d'
AssetsManager
après la création de la scene. - à chaque fois que l'on devra charger une texture, on déclarera une tâche de chargement (avec la méthode AssetsManager.addTextureTask).
- Une tâche de chargement possède une callback
onSuccess
qu'il faut définir et qui sera executée à la fin du chargement de la ressource (voir la doc de babylon). - Enfin, on lance le chargement asynchrone des resources en appelant AssetsManager.loadAsync. Le mot-clé
await
nous assure que les resources sont entièrement chargée avant de démarrer le rendu de la scène.
- Nous créons une instance d'
- À vous de jouer:
- Ajoutez les textureTasks dans
src/services/material.service.ts
. - Ajoutez les textureTasks dans
src/services/particles.service.ts
.
- Ajoutez les textureTasks dans
Lorsque vous aurez fini, vous pourrez passer à l'étape finale de ce tuto : git checkout .
puis git checkout step-06
Dans cette étape, nous allons charger une scène entière (stockée dans le fichier src/assets/scene/my-scene.babylon
).
Cette scene comporte déjà une caméra, des objets, des matériaux et des lumières.
Cette fois-ci, vous n'aurez rien à écrire. Tout ce que vous aurez à faire sera lire et comprendre le code du fichier src/components/scene-display/scene-display.service.ts
.
- Ouvrez le fichier
src/components/scene-display/scene-display.service.ts
et essayez d'identifier:- l'endroit où la scene est chargée
- l'endroit où on rattache la camera de la scene au canvas de notre page
- l'endroit où la skybox est crée (ce qui l'arrière plan de la scene et la couleur de la lumière environnante)
- l'endroit où on crée le générateur de particule
- l'endroit où on lance les animations pré-définis dans la scene
- Enfin, lancer le serveur et ouvrez la page
- Pour vous diriger dans cette nouvelle scene, vous devrez utiliser et touche directionnelles de votre clavier et votre souris
- Rendez-vous au pied du grand arbre décoré pour avoir une surprise;-)