Synthèse d'images, ESSI3
Examen, 21 février 2006

Objectifs et moyens

L'objectif de ce travail est de représenter un Rubick's cube simplifié.

Avant de commencer le travail de programmation, lisez le sujet dans son entier et réfléchissez à la structure de votre programme.

Vous disposez d'installations linux sur CD avec Java3D, sa documentation et les tutoriaux. Vous êtes connectés sous l'identité 'knoppix'. Votre répertoire utilisateur de travail (/home/knoppix) est un disque virtuel en mémoire. Vous disposez d'une disquette pour la sauvegarde et le rendu de votre travail. S'il est plus confortable de compiler et d'exécuter le code depuis le répertoire de travail, cet espace mémoire ne survit pas à un éventuel plantage machine. Il est donc indispensable de copier régulièrement votre travail sur la disquette. Pour cela, réalisez les commandes:

Java (JDK 1.5.0) et java3D (1.3.2) sont installés sur votre système. Vous devez configurer les variables d'environnement PATH et le CLASSPATH de votre système pour compiler et exécuter le code:
export PATH=/usr/java/jdk1.5.0/bin:${PATH}
export CLASSPATH=::/usr/java/jdk1.5.0/jre/lib/ext/j3dcore.jar:\
/usr/java/jdk1.5.0/jre/lib/ext/j3daudio.jar:\
/usr/java/jdk1.5.0/jre/lib/ext/j3dutils.jar:\
/usr/java/jdk1.5.0/jre/lib/ext/vecmath.jar

Ensuite, vous pouvez compiler en invoquant simplement la commande javac et exécuter en invoquant java. La documentation de java, java3D et les tutoriaux sont installés localement sur votre système. Vous êtes cependant isolés du réseau.

L'utilitaire emacs est installé sur vos machines. Vous pouvez réaliser la compilation directement depuis emacs en utilisant le menu 'Tools' -> 'Compilation'. Entrez la ligne de compilation (javac *.java) lors de la première compilation. Vous pouvez forcer la colorisation du code lors du premier chargement de chaque fichier source avec la commande: 'Alt-x font-lock-mode'.

Un squelette de programme est disponible sur votre disquette dans le fichier Example.java. Il ouvre un canvas 3D et affiche un cube. Vous le modifierez et vous ajouterez les classes nécessaires. Vous n'avez pas besoin d'étudier le détail du code fournit. Il devrait vous suffire d'écrire vos classe et d'insérer les appels à votre code dans le constructeur de la classe Example.

Les 3 boutons apparaissant sous la fenêtre principale ont pour but de vous faciliter la tâche si vous éprouvez le besoin d'utiliser des commandes pour faciliter l'utilisation de votre programme. Afin de ne pas perdre de temps en développement d'interface graphique, vous pouvez simplement:

  1. Implémenter l'interface ButtonListener dans la classe qui doit recevoir les événements.
  2. Transmettre l'objet de réception des évènements au constructeur de Frame3D.
  3. Gérer les actions à associer à chaque bouton dans les méthodes onButton1/2/3 de cette classe.
L'utilisation de ces boutons n'est en rien indispensable.

A la fin de la séance, vos fichiers seront récupérés depuis votre disquette. Vous devrez y laisser:

N'oubliez pas de copier tous les fichier du disque virtuel vers la disquette avant de rendre votre travail!

Sujet

Vous allez représenter un Rubick's cube de dimensions 2x2x2 ressemblant, dans sa première version, à ceci:

Vous l'enrichirez progressivement en suivant les étapes ci-dessous. D'une manière générales, les étapes sont assez indépendantes les unes des autres et vous pouvez en modifier l'ordre.

  1. Définissez une structure de donnée simple pour représenter l'objet graphique Rubick's cube.
  2. Créez le graphe de scène permettant de visualiser votre Rubick's cube.
  3. Changez le point de vue de la caméra de manière à visualiser le Rubick's cube sous un angle oblique comme illustré ci-dessus.
  4. Dans la suite, Vous devrez permettre l'interaction avec l'utilisateur pour réaliser des rotations des cubes de la manière suivante:

    Dans un premier temps, on ne considérera que la rotation des deux "plateaux horizontaux" haut et bas, comme dans l'illustration ci-dessus.

    Utilisez le picking pour réaliser des rotations des plateaux. Par cette méthode, les rotations sont libres sur tous les axes et ne sont donc pas réalistes.
  5. Commentez ce code faisant appel au picking et mettez en oeuvre à la place un comportement (Behavior) que vous définirez vous même, pour contraindre les rotations sur un seul axe. Vous suivrez ces étapes:
    1. Définissez un nouveau comportement et introduisez le dans la scène.
    2. Votre comportement devra d'abord capturer les événements de type "bouton pressé" (MOUSE_PRESSED). Une fois le bouton pressé, il devra capturer les événements de déplacement de la souris (MOUSE_DRAGGED). Enfin, il devra capturer le relâchement du bouton (MOUSE_RELEASED). Réalisez un affichage en console pour vérifier que vous capturez bien ces 3 événements dans l'ordre.
    3. Vous ferez tourner le plateau du haut en mouvement lorsque l'utilisateur réalise un mouvement horizontal avec la souris dans le haut de la fenêtre. Inversement, vous ferez tourner le plateau du bas en fonction d'un mouvement horizontal dans le bas de la fenêtre.
    4. Assurez vous que lors du relâchement de la souris, le plateau tourne jusqu'à un angle multiple de π/2 (pas de position intermédiaire).
  6. Texturez l'une des faces du Rubick's cube (une image de texture est disponible sur votre disquette). La texture devra se décomposer en 4 morceaux sur les 4 facettes des cubes composant une face, comme ceci:
  7. Définissez des matériaux avec des couleurs et des propriétés de brillance différentes pour chacune des 5 autres facettes des cubes.
  8. Ajoutez un éclairage à votre scène sous forme d'une lumière ponctuelle située dans un coin, avec atténuation de l'intensité lumineuse en fonction de la distance.
  9. Hmmm. Déjà fini? Ajoutez un plan de référence sous votre Rubick's cube et représentez l'ombre projetée (en simplifiant au maximum).
  10. Et si vous vouliez autoriser des rotations des deux "plateaux verticaux" droit et gauche? Comment vous y prendre?
  11. N'oubliez pas de copier tous les fichier du disque virtuel vers la disquette avant de rendre votre travail!