Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 13

Organiser les objets avec les Groupes

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons appris à manipuler la position, l'échelle et la direction de nos objets avec la classe Vector3. Nous avons terminé en posant une question : comment gérer des objets complexes composés de plusieurs parties, comme une voiture dont les roues doivent bouger avec la carrosserie ?

Introduction

La réponse à cette question est au cœur de l'organisation de toute scène 3D complexe. Essayer de calculer manuellement la position de chaque roue par rapport à la voiture à chaque image serait non seulement fastidieux, mais aussi très sujet aux erreurs.

L'objectif de cette leçon est de vous apprendre à organiser des objets en hiérarchies logiques à l'aide de THREE.Group. Cette technique fondamentale vous permettra de traiter un ensemble d'objets comme une seule entité, simplifiant radicalement les transformations et les animations. C'est le principe qui permet d'animer un bras de robot, un système solaire ou un personnage.

À la fin de cette leçon, vous serez capable de construire des scènes complexes et articulées en imbriquant des objets les uns dans les autres de manière logique.


1. Le principe de la hiérarchie parent-enfant

Dans Three.js, tout objet qui peut être placé dans une scène (comme un Mesh, une Light ou une Camera) hérite d'une classe de base appelée Object3D. Une propriété essentielle de Object3D est qu'il peut avoir des "enfants".

Le concept est simple :

  • Vous pouvez ajouter un Object3D (l'enfant) à un autre Object3D (le parent) en utilisant la méthode parent.add(enfant).
  • Dès lors, toute transformation (position, rotation, échelle) appliquée au parent est également appliquée à tous ses enfants.

Les transformations de l'enfant s'ajoutent à celles héritées du parent. Par exemple, si un parent est déplacé de 5 unités vers la droite, et que son enfant est déplacé de 2 unités vers le haut, la position finale de l'enfant sera de 5 unités à droite ET de 2 unités vers le haut par rapport à l'origine du parent.

Pour mieux visualiser cette structure, imaginez un arbre généalogique où la Scene est l'ancêtre commun.

Three.js Scene Graph Hierarchy
Ce diagramme illustre la hiérarchie d'une scène 3D. La `Scene` est à la racine. Des objets comme les `Mesh` et les `Light` peuvent y être ajoutés. Remarquez l'objet `Group`, qui sert de conteneur pour d'autres objets, créant ainsi une sous-hiérarchie.

2. THREE.Group : Le conteneur universel

Plutôt que d'utiliser un Mesh visible comme parent, Three.js fournit un objet spécialement conçu pour cela : THREE.Group. C'est un conteneur invisible dont le seul but est de regrouper d'autres objets. Son centre (0,0,0) sert de "pivot" pour toutes les transformations appliquées au groupe.

La mécanique est très simple :

  1. On crée un nouveau groupe : const monGroupe = new THREE.Group();
  2. On y ajoute des objets : monGroupe.add(monCube); monGroupe.add(maSphere);
  3. On ajoute le groupe à la scène : scene.add(monGroupe);

Désormais, si vous faites monGroupe.rotation.y += 0.01;, le cube et la sphère tourneront ensemble autour du centre du groupe.

La vidéo suivante montre très clairement cette mise en pratique.

Particules 3D connectées avec Three.js

Cette vidéo de Grafikart.fr, bien que sur un autre sujet, contient une excellente démonstration de la création et de l'animation d'un Group. Observez comment le groupe est créé, comment les objets y sont ajoutés, et comment la rotation du groupe affecte tout son contenu.

Regardez la première partie (de 00:34:31 à 00:35:06) pour voir la création du groupe. Ensuite, regardez la seconde partie (de 00:35:06 à 00:37:08) pour voir comment l'animation est appliquée au groupe entier.


3. Construire des hiérarchies complexes : l'exemple du système solaire

La véritable puissance des groupes apparaît lorsque vous les imbriquez (nesting). C'est ainsi que l'on crée des articulations complexes. Un exemple classique est un système solaire : la Lune tourne autour de la Terre, et l'ensemble (Terre + Lune) tourne autour du Soleil.

Tenter de faire cela sans hiérarchie est un véritable casse-tête mathématique.

Three.js Groups Tutorial | How to Organize Code with Three.js Groups

La vidéo suivante (en anglais) illustre parfaitement ce problème et sa solution. La clarté des visuels et du code la rend très facile à comprendre, même sans maîtriser l'anglais.

Regardez d'abord la partie de 01:19 à 02:27. Elle montre la complexité de l'animation d'une orbite avec des calculs manuels (Math.sin, Math.cos). Ensuite, regardez de 02:27 à 05:06. L'auteur réorganise le code en utilisant des groupes imbriqués : un earthOrbit qui contient la Terre, et un moonOrbit (lui-même enfant de earthOrbit) qui contient la Lune. Observez comme l'animation devient simple : il suffit de faire tourner les groupes pivots.

Cette approche hiérarchique est la solution standard pour ce type de problème. L'article ci-dessous détaille une implémentation complète en français pour un système Terre-Lune, en utilisant exactement cette logique de groupes imbriqués.

Animer le système Terre-Lune en HTML et JavaScript (2/2)

Cet article de 'La voie du dev' explique en détail la logique de hiérarchie pour animer le système Terre-Lune. Il est un excellent complément à la vidéo précédente.

Lisez les sections 'Solution : hiérarchie d’objets' et l'arborescence qui la suit. Cela formalise l'idée que vous venez de voir en vidéo : décomposer un mouvement complexe en une série de transformations parent-enfant simples.


4. Introduction aux coordonnées locales vs. mondiales

Cette idée de hiérarchie introduit un concept fondamental que nous détaillerons dans la prochaine leçon. Lorsque vous définissez monCube.position.x = 2;, cette position est relative au parent du cube. C'est son espace de coordonnées local.

La position finale du cube dans la scène, après application de toutes les transformations de ses parents, est sa position dans l'espace de coordonnées du monde (world space).

Objets et scène — JavaScript avancé

Lisez cette courte explication pour bien comprendre la distinction entre l'espace local et l'espace du monde.

Lisez uniquement le premier paragraphe de la section 'Hiérarchie d’objets', qui commence par 'Les transformations appliquées à un objet...' jusqu'à '...l’espace de coordonnées du monde (world space).'

Retenez simplement pour l'instant : .position, .rotation et .scale opèrent toujours dans l'espace local de l'objet.


Exercice pratique

Mettons en pratique la création d'une hiérarchie simple. Nous allons créer un "soleil" et une "planète" qui orbite autour.

  1. Mise en place : Repartez de votre code de base (scène, caméra, renderer, boucle d'animation, OrbitControls).

  2. Créez le soleil :

    • Créez une sphère (SphereGeometry) de rayon 1.
    • Utilisez un MeshBasicMaterial de couleur jaune (0xffff00).
    • Créez le Mesh du soleil et ajoutez-le directement à la scène.
  3. Créez le groupe pour l'orbite :

    • Créez un THREE.Group nommé planetOrbitGroup.
    • Ajoutez ce groupe à la scène. Il sera notre pivot invisible.
  4. Créez la planète :

    • Créez une autre sphère, plus petite (rayon 0.3).
    • Utilisez un MeshBasicMaterial de couleur bleue (0x0095dd).
    • Créez le Mesh de la planète.
    • Positionnez la planète à 4 unités du centre sur l'axe X : planet.position.x = 4;.
    • Important : Ajoutez la planète non pas à la scène, mais au planetOrbitGroup.
  5. Animez l'orbite :

    • Dans votre boucle d'animation animate(), mettez à jour la rotation du groupe pivot : planetOrbitGroup.rotation.y += 0.005;.

Si tout est correct, vous devriez voir la planète bleue tourner autour du soleil jaune central. Vous pouvez toujours utiliser OrbitControls pour vous déplacer dans la scène et observer le mouvement sous différents angles.

Solution
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

// Scène, Caméra, Renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
camera.position.y = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);

// AxesHelper pour le débogage
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

// 1. Créer le soleil
const sunGeometry = new THREE.SphereGeometry(1, 32, 32);
const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
scene.add(sun); // Ajouté directement à la scène

// 2. Créer le groupe pour l'orbite
const planetOrbitGroup = new THREE.Group();
scene.add(planetOrbitGroup); // Le groupe est ajouté à la scène

// 3. Créer la planète
const planetGeometry = new THREE.SphereGeometry(0.3, 32, 32);
const planetMaterial = new THREE.MeshBasicMaterial({ color: 0x0095dd });
const planet = new THREE.Mesh(planetGeometry, planetMaterial);

// 4. Positionner la planète et l'ajouter au groupe
planet.position.x = 4;
planetOrbitGroup.add(planet); // La planète est enfant du groupe

// Boucle d'animation
function animate() {
    requestAnimationFrame(animate);

    // 5. Animer l'orbite en faisant tourner le groupe
    planetOrbitGroup.rotation.y += 0.005;
    
    // Bonus : la planète tourne aussi sur elle-même
    planet.rotation.y += 0.01;

    controls.update();
    renderer.render(scene, camera);
}

animate();

Conclusion

Félicitations ! Vous venez de maîtriser l'un des concepts les plus importants pour la création de scènes 3D structurées.

Points clés à retenir :

  • Les objets 3D peuvent être organisés en hiérarchies parent-enfant.
  • Les enfants héritent des transformations (position, rotation, échelle) de leurs parents.
  • THREE.Group est un conteneur invisible idéal pour servir de parent ou de pivot.
  • L'imbrication de groupes permet de créer des animations complexes (comme des orbites) de manière simple et intuitive.
  • Les transformations que nous appliquons (.position, .rotation) se font dans l'espace de coordonnées local de l'objet (relatif à son parent).

Aperçu de la prochaine leçon :
Nous avons effleuré la différence entre les coordonnées locales et mondiales. Dans la prochaine leçon, nous allons explorer ce sujet en profondeur. Vous apprendrez comment déterminer la position exacte d'un objet dans la scène, peu importe sa profondeur dans la hiérarchie, et comment passer d'un système de coordonnées à l'autre. C'est une compétence essentielle pour des interactions avancées, comme faire en sorte qu'un objet suive la caméra.