|
Java 3D |
Démarrer en Java 3D
Un premier exemple
Principes 3D
Les classes de bases
Java 3D est une bibliothèque de classes d'extension Java destinée à créer des scènes 3D en réalité virtuelle (avec utilisation de formes complexes, d'éclairages, de textures, d'animations, de sons,...). Ce chapitre décrit les notions de base utiles pour programmer avec cette bibliothèque.
Prérequis
Ce manuel s'adresse aux personnes connaissant la programmation en Java et désirant s'initier à Java 3D. Si vous ne connaissez pas Java, commencez par apprendre ce langage en utilisant par exemple le manuel Du C/C++ à Java ou un autre de la liste des liens utiles.
Des connaissances en programmation 3D ne sont pas obligatoires mais des notions en géométrie 3D (un point dans l'espace défini par ses coordonnées (x,y,z), ça vous dit quelque chose ?) faciliteront votre apprentissage.
Tous les exemples de ce manuel sont compatibles avec la version 1.1 de bibliothèque Java 3D.Téléchargement
Java 3D est disponible sur le site http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138252.html. La version complète de cette bibliothèque est actuellement disponible sous Windows, Solaris, SGI, HP-UX et Linux. La version Windows est disponible sous OpenGL ou DirectX.
Comme Java 3D est une extension, vous devez avoir déjà installé Java 2 pour pouvoir l'utiliser. Une ancienne version 1.3.1. est préinstallée comme extension Java sous Mac OS XSur son site, Oracle fournit aussi des documentations en anglais. Voici la liste des plus intéressantes :
- L'ensemble des classes Java 3D et leur interface de programmation (Java 3D API Documentation) sous forme de fichiers HTML à visualiser avec un navigateur.
Ce manuel qui décrit partiellement les classes les plus importantes de Java 3D en français est suffisant pour débuter en Java 3D mais la documentation des API Java 3D en anglais est indispensable pour avoir une référence complète des classes.- Les spécifications de Java 3D au format Acrobat Reader (Java 3D API Specification). Un document complet sur Java 3D mais assez indigeste pour les débutants en 3D.
- Un tutorial complet se dénommant Getting Started with Java 3D. Ce tutorial est disponible sous forme de fichiers au format Acrobat Reader rassemblés dans un fichier ZIP.
Installation
Il est conseillé d'installer Java 3D dans le même répertoire que le JDK, pour simplifier l'arborescence de l'installation de votre JDK.
Java 3D installe essentiellement :
- Des DLLs (Dynamic Link Library) dans le répertoire bin du JRE (Java Runtime Environment).
- Les fichiers vecmath.jar, j3dcore.jar, j3daudio.jar et j3dutils.jar dans le répertoire lib/ext du JRE. Selon l'environnement de programmation utilisé vous devrez peut-être rajouter ces fichiers JAR dans votre CLASSPATH (essayez d'abord sans modification car les extensions sont normalement automatiquement importées).
- Un ensemble d'exemples disponibles dans le répertoire demo/java3d du JDK. Les plus intéressantes :
- FourByFour (fbf.html)
- GearTest (GearBox.class)
- Morphing
Les exemples fournis avec Java 3D fonctionnent généralement sous forme d'application ou d'applet. Comme Java 3D nécessite Java 2 pour fonctionner, vous pourrez utiliser les versions actuelles de Netscape Navigator et d'Internet Explorer pour visualiser les applets qu'avec le plug-in Java. Le plus simple reste d'ouvrir une fenêtre de commandes et d'utiliser les commandes java pour lancer les applications et appletviewer pour lancer les applets.
Architecture
Figure 1. Architecture Java 3DLa réalité virtuelle est grande consommatrice de calculs. Pour accélérer son travail, Java 3D utilise le plus possible les optimisations 3D offertes par le système sur lequel la Machine Virtuelle Java tourne :
- Quand vous utilisez une version OpenGL de Java 3D, certaines fonctionnalités de l'API font appel à des méthodes native de la DLL Java 3D/OpenGL. Ces méthodes elles, utilisent des fonctions de la DLL OpenGL du système.
- La DLL OpenGL du système utilise l'accélérateur graphique disponible sur la carte graphique. La puissance de traitement de Java 3D dépend donc de la puissance de votre microprocesseur mais aussi de celle de votre carte graphique. Vérifiez que le driver de votre carte est à jour pour profiter à plein de sa capacité de traitement.
Les classes de l'API Java 3D appartiennent au package javax.media.j3d (fichier j3dcore.jar).
Le package javax.vecmath (fichier vecmath.jar) rassemble les classes dédiées au calcul vectoriel et matriciel dont Java 3D a besoin. Ces classes sont dans un package isolé pour être réutilisables dans d'autres contextes de programmation.
Bien que les classes des packages javax.media.j3d et javax.vecmath soient suffisantes pour programmer toutes les fonctionnalités offertes par Java 3D, des classes utilitaires facilitant la programmation sont fournies dans les packages commençant par com.sun.j3d... (fichiers j3dutils.jar et j3daudio.jar).
Voici un premier exemple utilisant Java 3D et mettant en oeuvre les principes généraux de cette bibliothèque.
Cette classe est programmée pour fonctionner en tant qu'applet ou comme application.
Recopiez-la dans un fichier Applet3D.java, que vous compilez avec l'instruction javac Applet3D.java pour ensuite l'exécuter avec java, grâce à l'instruction java Applet3D. Cet exemple affiche un cube avec 6 faces de couleur différente. Comme aucune rotation n'est effectuée sur ce cube, le résultat n'est pas très impressionnant puisque vous n'en voyez qu'une seule face ! Mais cet exemple va servir comme base pour la suite du manuel...import java.applet.Applet; import java.awt.*; import javax.media.j3d.*; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.applet.MainFrame; // Applet de base pour visualiser des scènes 3D public class Applet3D extends Applet { // Méthode appelée à l'initialisation de l'applet public void init () { // Création d'un composant de classe Canvas3D permettant de visualiser une scène 3D // Avec JFree-D, utiliser new Canvas3D (null) dans la ligne suivante Canvas3D canvas = new Canvas3D (SimpleUniverse.getPreferredConfiguration ()); setLayout (new BorderLayout ()); add (canvas, BorderLayout.CENTER); // Création de la scène 3D à visualiser BranchGroup scene = createSceneTree (); // Création d'un univers 3D rattaché au composant 3D SimpleUniverse universe = new SimpleUniverse (canvas); // Rattachement de la scène 3D à l'univers universe.addBranchGraph (scene); // Positionnement pour avoir une vue correcte sur la scène 3D // (permet de voir une scène 3D contenue dans un cube d'1 unité // de côté et centré sur le centre du repère). universe.getViewingPlatform ().setNominalViewingTransform (); } public BranchGroup createSceneTree () { // Racine de l'arbre des objets représentés dans la scène 3D BranchGroup root = new BranchGroup(); // Création d'un cube coloré dont deux des sommets opposés sont // situés en (-0.5,-0.5,-0.5) et (0.5,0.5,0.5) ColorCube cube = new ColorCube (0.5); // Ajout du cube à la racine de l'arbre root.addChild (cube); return root; } // Méthode main () pour permettre d'utiliser cette classe // comme applet ou comme application public static void main (String [] args) { // La classe com.sun.j3d.utils.applet.MainFrame est une classe // qui crée automatiquement une fenêtre avec l'applet passée en paramètre new MainFrame (new Applet3D (), args, 150, 150); } }La classe MainFrame utilisée dans la méthode main () de tous les exemples de ce manuel est une classe utilitaire qui affiche l'applet passée en paramètre à son constructeur dans une fenêtre de dimensions données. Cette classe permet aussi d'interpréter les arguments de la ligne de commande comme des paramètres de l'applet. Par exemple, le code HTML qui utilise la classe Applet3D, suivant :
<APPLET CODE="Applet3D.class" WIDTH=150 HEIGHT=150> <PARAM NAME="param" VALUE="paramValue"> </APPLET>aura l'équivalent suivant avec la commande java : java Applet3D param=paramValue
Construction d'un univers 3D
L'exemple précédent utilise tous les éléments nécessaires pour programmer avec Java 3D. De quoi a-t-on besoin ?
Figure 2. Composants d'un univers 3D
- Une instance de Canvas3D : Ce composant AWT qui dérive de la classe java.awt.Canvas, est la zone de l'écran où est visualisèe une scène 3D. Cette zone peut être vue comme la pellicule d'un appareil photo : elle ne permet pas de capturer tous les objets autour de l'appareil mais juste d'avoir une vue plus ou moins large sur un ensemble d'objets en 3 dimensions.
- Une scène 3D à visualiser : cette scène est un ensemble d'une ou plusieurs formes (shape) géométriques simples (parallélépipède, sphère, cylindre ou cône) ou complexes (ensemble de points reliés entre eux, texte 3D). Sur chacune de ces formes 3D, on peut effectuer des transformations (translation, rotation, homothétie) pour les positionner dans l'espace et les animer.
L'ensemble de ces formes et de ces transformations est représenté par un graphe de type arbre dont la racine est une instance de BranchGroup.- Une instance de SimpleUniverse : Cet objet relie l'instance de Canvas3D avec la scène 3D à visualiser. Cet objet modélise l'espace dans lequel on positionne l'appareil photo. A cet espace sont rattachés une instance de Canvas3D et une scène 3D. La classe SimpleUniverse est une classe utilitaire qui permet de créer des instances par défaut des classes VirtualUniverse, Locale, ViewPlatform, View, PhysicalBody et PhysicalEnvironment, nécessaires à Java 3D.
Dans la classe Applet3D, la création de l'arbre représentant la scène à visualiser est isolée dans la méthode createSceneTree (). Tous les exemples qui suivent dans ce manuel outrepassent cette méthode pour montrer les différents types de scènes qu'il est possible de créer en Java 3D.
Repère 3D
Une scène 3D est composée d'un ensemble de formes 3D. Chacune de ces formes est construit par un assemblage de triangles ou de quadrilatères plans. Ces formes simples sont décrites grâce aux coordonnées (x,y,z) de leurs sommets. Pour s'orienter correctement dans la scène 3D à laquelle vous allez ajouter des formes 3D, il faut donc connaître comment est positionné le repère 3D sous-jacent à tout espace 3D.
Figure 3. Orientation d'un repère 3DQuand vous utilisez la classe SimpleUniverse, le centre du repère 3D est dans l'axe du milieu du composant Canvas3D. L'axe x va vers la droite, l'axe y vers le haut. Pour que le repère soit direct, l'axe z est orienté vers l'observateur. Sur la figure, les flèches circulaires indiquent le sens positif de rotation autour de chaque axe.
La méthode setNominalViewingTransform () utilisée dans la classe Applet3D positionne l'instance de Canvas3D à une certaine distance sur l'axe z entre l'observateur et l'origine du repère. La largeur du composant Canvas3D permet alors de voir entièrement un cube d'une unité de côté et les points de coordonnées (-1,0,0) et (1,0,0) dans le plan z=0.
Ce paramètrage est celui utilisé par défaut par la classe SimpleUniverse mais il est tout à fait possible de le changer pour avoir une ou plusieurs vues différentes sur une scène 3D.
En 3D, l'axe y est orienté vers le haut et non vers le bas comme généralement en dessin 2D sur ordinateur.
Transformation 3D
Les transformations sont utilisées en 3D pour positionner et animer une forme 3D dans l'espace. Java 3D utilise la classe Transform3D pour décrire une opération de translation, de rotation ou d'homothétie (changement d'échelle, scale en anglais). Cette opération est associée à une instance de la classe TransformGroup et ajoutée à l'arbre de la scène pour l'appliquer sur une forme.
Voici l'applet CubeSides dérivant de la classe Applet3D : Cet exemple effectue sur un cube deux rotations de PI / 6 radian (30°) autour des axes x et y. Ces deux rotations permettent à l'observateur de découvrir les couleurs de 3 des faces du cube.import javax.media.j3d.*; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.applet.MainFrame; public class CubeSides extends Applet3D { // Méthode de la classe Applet3D outrepassée public BranchGroup createSceneTree () { // Racine de l'arbre des objets représentés dans la scène 3D BranchGroup root = new BranchGroup (); // Création d'une rotation de PI / 6 autour de l'axe X Transform3D rotationXAxis = new Transform3D (); rotationXAxis.rotX (Math.PI / 6); TransformGroup rotationXAxisGroup = new TransformGroup (rotationXAxis); // Création d'une rotation de -PI / 6 autour de l'axe Y Transform3D rotationYAxis = new Transform3D (); rotationYAxis.rotY (-Math.PI / 6); TransformGroup rotationYAxisGroup = new TransformGroup (rotationYAxis); // Création d'un cube coloré ColorCube cube = new ColorCube (0.5); // Construction de la branche de l'arbre de la scène rotationYAxisGroup.addChild (cube); rotationXAxisGroup.addChild (rotationYAxisGroup); root.addChild (rotationXAxisGroup); return root; } // Méthode main () pour permettre d'utiliser cette classe // comme applet ou comme application public static void main (String [] args) { new MainFrame (new CubeSides (), args, 150, 150); } }
L'ordre dans lequel sont effectués les transformations a une importance. Si vous enchaînez différemment les rotations sur les axes x et y dans la méthode createSceneTree () de la classe CubeSides, vous n'obtiendrez pas le même résultat :
// Construction de la branche de l'arbre de la scène // Rotation autour de l'axe y puis de l'axe x rotationYAxisGroup.addChild (cube); rotationXAxisGroup.addChild (rotationYAxisGroup); root.addChild (rotationXAxisGroup); // Construction de la branche de l'arbre de la scène
// Rotation autour de l'axe x puis de l'axe y rotationXAxisGroup.addChild (cube);
rotationYAxisGroup.addChild (rotationXAxisGroup);
root.addChild (rotationYAxisGroup);
Arbre d'une scène 3D
Un arbre représentant une scène 3D est constitué de noeuds (node) qui sont soit des feuilles (leaf), soit des groupes (group). Les noeuds reliés entre eux ont une relation parent-enfant (parent-child). Tous les noeuds ont un parent sauf la racine (root) et peuvent avoir un ou plusieurs enfants sauf les feuilles.
Figure 4.
Arbre de la scène CubeSidesL'arbre de la scène créé par la classe CubeSides est constitué d'une seule branche :
- La feuille au bout de la branche, symbolisée par un triangle , est une forme géométrique (shape) qui est une instance de la classe ColorCube.
- Le groupe rattaché à l'instance de la classe SimpleUniverse est une instance de la classe BranchGroup.
- Entre ces deux noeuds, deux groupes de transformation ont été insérés : l'un exécute une rotation autour de l'axe y de -PI/6 rad puis l'autre une seconde rotation autour de l'axe x de PI/6 rad.
Les relations parent-enfant entre les noeuds d'un arbre sont créées avec la méthode addChild () grâce à l'instruction parent.addChild (enfant);.
Un programme Java 3D doit compter autant d'appels à la méthode addChild () que de relations parent-enfant.
Voici l'applet MultiCubes dérivant de la classe Applet3D : cet exemple crée une scène 3D représentée par un cercle de 12 cubes centré autour de l'axe z. Une rotation de 45° est appliquée ensuite autour de l'axe x, pour mieux voir cet ensemble.
import javax.media.j3d.*; import javax.vecmath.Vector3f; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.applet.MainFrame; public class MultiCubes extends Applet3D { // Méthode de la classe Applet3D outrepassée public BranchGroup createSceneTree () { // Racine de l'arbre des objets représentés dans la scène 3D BranchGroup root = new BranchGroup (); // Création d'une rotation de -PI / 4 autour de l'axe x Transform3D rotationXAxis = new Transform3D (); rotationXAxis.rotX (-Math.PI / 4); TransformGroup rotationXAxisGroup = new TransformGroup (rotationXAxis); // Création d'un cercle construit avec 12 cubes Group cubeCircle = createCubeCircle (12); // Construction de l'arbre de la scène rotationXAxisGroup.addChild (cubeCircle); root.addChild (rotationXAxisGroup); return root; } // Crée un cercle avec cubeCount cubes public Group createCubeCircle (int cubeCount) { Group cubeCircle = new Group (); // Boucle de création de cubeCount cubes for (int i = 0; i < cubeCount; i++) { // Création d'une translation de (0.7,0,0) Transform3D translation = new Transform3D (); translation.setTranslation (new Vector3f (0.7f, 0, 0)); TransformGroup translationGroup = new TransformGroup (translation); // Création d'une rotation variable autour de l'axe z Transform3D rotationZAxis = new Transform3D (); rotationZAxis.rotZ (2 * Math.PI * i / cubeCount); TransformGroup rotationZAxisGroup = new TransformGroup (rotationZAxis); // Création d'un cube coloré ColorCube cube = new ColorCube (0.1); // Déplacement du cube de 0.7 unité sur l'axe x translationGroup.addChild (cube); // Rotation variable pour répartir l'ensemble des cubes // autour du centre du repère rotationZAxisGroup.addChild (translationGroup); // Ajout d'une branche à la racine de l'arbre cubeCircle.addChild (rotationZAxisGroup); } return cubeCircle; } // Méthode main () pour permettre d'utiliser cette classe // comme applet ou comme application public static void main (String [] args) { new MainFrame (new MultiCubes (), args, 150, 150); } }
Figure 5. Arbre de la scène MultiCubesLa figure précédente représente l'arbre de la scène créée par la méthode createSceneTree () de la classe MultiCubes (les douze branches représentant les douze cubes ne sont pas toutes dessinées). Cet arbre est construit comme suit :
- Les douze cubes subissent tous le même type de transformation : une translation de 0.7 unité le long de l'axe x puis une rotation de i*PI/6 radian autour de l'axe z, i étant compris entre 0 et 11.
Chaque feuille qui correspond à un cube est donc liée à deux groupes de transformation : ce sous-ensemble forme une branche rattachée au groupe , racine de l'arbre qui rassemble les douze cubes. Cet ensemble forme un arbre cohérent représentant le cercle des douze cubes. Cet arbre pourrait être directement rattachée à la racine de la scène 3D.- Le cercle de douze cubes subit une rotation de -PI/4 radian autour de l'axe x. L'opération la plus simple pour appliquer cette transformation à chacun des cubes est de rattacher le groupe représentant le cercle à un seul groupe de transformation effectuant cette rotation.
- La racine de la scène 3D doit être une instance de la classe BranchGroup et ce groupe est donc relié au dernier groupe de transformation .
La création un groupe intermédiaire permet de manipuler le cercle de cubes par sa racine. Mais tout groupe peut avoir plusieurs enfants et la programmation de l'arbre suivant aurait donné le même résultat :
Figure 6.
Arbre simplifié de la scène MultiCubes
En observant le résultat de l'application MultiCubes et l'arbre de la scène qu'elle affiche, vous pouvez maintenant comprendre comment Java 3D utilise un arbre pour calculer la position des formes d'une scène 3D dans l'espace :
- Un arbre est un graphe ayant des propriétés particulières : A partir de sa racine, il est possible d'énumérer toutes les feuilles et il existe un chemin unique reliant la racine à chacune des feuilles.
- En Java 3D, une feuille représentant une forme géométrique est un assemblage de triangles ou de quadrilatères décrits par les coordonnées (x,y,z) de leurs sommets.
- Le chemin qui relie la racine à une feuille est un ensemble de groupes. Java 3D part de chaque feuille puis remonte le chemin jusqu'à la racine de l'arbre, en appliquant aux coordonnées des sommets l'opération correspondant à chacun des groupes de transformation rencontrés. Les transformations sont donc appliquées dans l'ordre, d'une feuille vers la racine.
L'arbre d'une scène 3D peut contenir des groupes de transformation et des formes 3D, mais aussi d'autres types d'éléments utilisés par Java 3D : des noeuds représentant des lumières, des fonds d'écran, des comportements (animation et réaction aux événements), des sources de sons,...
Les classes représentant un groupe dérivent des classes javax.media.j3d.Node et javax.media.j3d.Group.
Les classes représentant une feuille dérivent des classes javax.media.j3d.Node et javax.media.j3d.Leaf.
- java.lang.Object
- javax.media.j3d.SceneGraphObject
- javax.media.j3d.Node
- javax.media.j3d.Group
- javax.media.j3d.BranchGroup
- javax.media.j3d.OrderedGroup
- javax.media.j3d.SharedGroup
- javax.media.j3d.Switch
- javax.media.j3d.TransformGroup
- javax.media.j3d.Leaf
- javax.media.j3d.Background
- javax.media.j3d.Behavior
- javax.media.j3d.BoundingLeaf
- javax.media.j3d.Clip
- javax.media.j3d.Fog
- javax.media.j3d.Light
- javax.media.j3d.Link
- javax.media.j3d.Morph
- javax.media.j3d.Shape3D
- javax.media.j3d.Sound
- javax.media.j3d.Soundscape
- javax.media.j3d.ViewPlatform
- javax.media.j3d.NodeComponent
- ...
Globalement, une scène 3D est documentée par la représentation graphique de son arbre. Il est vivement conseillé de dessiner un tel arbre quand vous créez vos scènes 3D : ceci permet d'effectuer mentalement l'assemblage des différentes formes d'une scène 3D, et ce type de documentation est bien plus lisible que des centaines de lignes de programme.
Faites attention à la cohérence de votre arbre :
- Si vous tentez d'affecter deux parents à un noeud, Java 3D déclenchera une exception MultipleParentException.
- Si vous créez des branches inutiles, Java 3D ne signalera aucune erreur à l'exécution et le résultat ne correspondra pas à vos attentes : Ce type d'erreur survient quelques fois à la suite d'un copier/coller trop rapide d'une instruction addChild () pour ajouter un groupe de transformation à une branche existante.
Si la modification du parent a été oubliée, vous pourrez obtenir par exemple ceci :// Ajout d'une nouvelle transformation transform2 root.addChild (transform2); // ... root.addChild (transform1); transform1.addChild (object);root n'a pas été changé en transform2. Ainsi l'instruction root.addChild (transform2); crée une nouvelle branche inutile puisque la transformation transform2 est seule sur cette branche, et n'est pas appliquée à transform1.
Optimisations Java 3D
Java 3D utilise principalement deux optimisations pour améliorer les performances des calculs d'affichage 3D : La compilation des noeuds d'une scène 3D et la capacité d'un noeud.
Compilation
La compilation de chacun des noeuds d'une scène 3D permet d'obtenir une représentation interne que Java 3D manipule de manière optimum.
La méthode compile () de la classe BranchGroup compile tous les noeuds d'un arbre à partir de sa racine et la méthode isCompiled () de la classe SceneGraphObject de savoir si un noeud a été compilé.
La classe Applet3D peut être optimisée en ajoutant l'instruction scene.compile (); dans la méthode init ().Capacité d'un noeud
Il n'est pas possible d'interroger ou de modifier une propriété d'un noeud compilé ou vivant (noeud utilisé dans une scène attachée à un univers), si ce noeud n'en a pas la capacité (capability).
Cette capacité peut être donnée à un noeud non compilé et pas encore vivant en appelant la méthode setCapability () de la classe SceneGraphObject dont héritent toutes les classes des objets manipulés dans une scène 3D. Les classes dérivées de SceneGraphObject définissent un ensemble de constantes de capacité ALLOW_..._READ, ALLOW_..._WRITE ou ENABLE_.... Ces constantes sont passées en paramètre à la méthode setCapability () pour autoriser la lecture ou la modification de la propriété correspondante d'un noeud quand il sera compilé ou vivant.
Par exemple, pour autoriser la modification d'un groupe de transformation vivant, il faut appeler setCapability (TransformGroup.ALLOW_TRANSFORM_WRITE) sur celui-ci : cette capacité permet d'appeler la méthode setTransform () pour changer la transformation et animer une forme 3D à l'écran. Si le groupe de transformation n'a pas la capacité ALLOW_TRANSFORM_WRITE, une exception de classe CapabilityNotSetException sera déclenchée à l'appel de setTransform ().Quand la racine de l'arbre d'une scène 3D est rattachée à un univers avec la méthode addBranchGraph (), Java 3D vérifie les différentes capacités de chacun des noeuds en utilisant la méthode getCapability () et optimise la représentation interne des objets 3D.
Dans ce manuel, les capacités associées aux méthodes des classes dérivées de SceneGraphObject sont indiquées entre parenthèses après chacune des méthodes auxquelles elles s'appliquent.
Ce paragraphe présente les principales classes utilisées au cours de ce chapitre pour construire une scène 3D.
Les classes Canvas3D qui dérive de la classe java.awt.Canvas et com.sun.j3d.utils.universe.SimpleUniverse qui dérive de la classe javax.media.j3d.VirtualUniverse et leurs méthodes ne sont pas documentées ici : elles permettent de configurer finement l'environnement Java 3D.
Toutes les classes Java 3D d'exceptions héritent de la classe RuntimeException.La classe javax.media.j3d.SceneGraphObject
Cette classe abstract est la super classe des classes Node et NodeComponent, elles-mêmes les super classes des classes utilisées pour construire l'arbre d'une scène 3D et pour décrire la construction géométrique et l'apparence d'une forme 3D.
La classe SceneGraphObject intègre les principes utilisés par Java 3D pour améliorer les performances des calculs d'affichage 3D : La compilation des noeuds d'une scène 3D et la capacité d'un noeud.Principales méthodes
public final boolean isCompiled ()
public final boolean isLive ()Ces méthodes renvoient true si un noeud a été compilé ou s'il est vivant (s'il appartient à une scène 3D rattachée à un univers).
public final boolean getCapability (int capability)
public final void setCapability (int capability) throws RestrictedAccessException public final void clearCapability (int capability) throws RestrictedAccessExceptionCes méthodes permettent d'interroger, d'activer ou de désactiver la capacité capability d'un noeud, en passant en paramètre une des constantes ALLOW_..._READ, ALLOW_..._WRITE ou ENABLE_... définies dans les classes dérivées. Ces constantes correspondent aux méthodes de ces classes qu'il est possible d'appeler quand un noeud est compilé ou vivant. Par exemple, il faut appeler setCapability (Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE) sur une instance de la classe Appearance pour pouvoir appeler setColoringAttributes () et modifier la couleur d'une forme déjà affichée.
Les méthodes setCapability () et clearCapability () doivent être appelées avant de compiler ou afficher un noeud sinon elles déclenchent une exception RestrictedAccessException.
Un nouveau noeud n'a aucune capacité à sa création. N'activez sur un noeud que les capacités dont vous aurez effectivement besoin une fois que ce noeud sera vivant.
- Il n'est pas possible de passer en paramètre à la méthode setCapability () la combinaison de plusieurs capacités (group.setCapability (TransformGroup.ALLOW_TRANSFORM_READ | TransformGroup.ALLOW_TRANSFORM_WRITE); n'active pas les deux capacités).
- Ce n'est pas parce qu'un noeud a une capacité en modification (ALLOW_..._WRITE) qu'il a la capacité en lecture (ALLOW_..._READ).
public java.lang.Object getUserData ()
public void setUserData (java.lang.Object userData)Ces méthodes permettent d'interroger ou de modifier l'objet userData associé à ce noeud. Libre à vous de l'utiliser ou non pour stocker les informations supplémentaires que vous voulez associer à ce noeud.
La classe javax.media.j3d.Node
Cette classe abstract dérive de la classe SceneGraphObject et représente un noeud utilisé dans l'arbre d'une scène 3D. C'est la super classe des classes Leaf et Group, et regroupe les capacités en rapport avec le calcul des limites (bounds), l'interception par la souris et la collision avec les autres formes 3D.
Chaque noeud ne peut être utilisé qu'une seule fois dans un arbre. En cas de besoin, il est possible d'utiliser les méthodes cloneNode () ou cloneTree () de cette classe pour copier facilement un noeud ou un arbre dont la racine est ce noeud.Principaux champs (constantes de capacité)
public static final int ALLOW_COLLIDABLE_READ
public static final int ALLOW_COLLIDABLE_WRITE public static final int ALLOW_PICKABLE_READ public static final int ALLOW_PICKABLE_WRITE public static final int ALLOW_BOUNDS_READ public static final int ALLOW_BOUNDS_WRITE public static final int ALLOW_AUTO_COMPUTE_BOUNDS_READ public static final int ALLOW_AUTO_COMPUTE_BOUNDS_WRITECes capacités sont passées en paramètre aux méthodes setCapability () et clearCapability () pour autoriser ou interdire l'appel aux méthodes correspondantes de la classe Node (setCapability (ALLOW_AUTO_COMPUTE_BOUNDS_READ) autorise l'appel de la méthode getBoundsAutoCompute () quand le noeud sera affiché).
public static final int ENABLE_PICK_REPORTING public static final int ENABLE_COLLISION_REPORTINGPrincipales méthodes
public Node getParent () throws RestrictedAccessExceptionRenvoie le parent de ce noeud ou null s'il n'en a pas. Si le noeud est compilé ou vivant une exception de classe RestrictedAccessException est déclenchée.
public Node cloneTree () throws RestrictedAccessExceptionRenvoie une copie de l'arbre dont la racine est ce noeud.
public Node cloneNode (boolean forceDuplicate) throws RestrictedAccessExceptionRenvoie une copie de ce noeud. Cette méthode peut être éventuellement être appelée par la méthode cloneTree (). Toutes les classes dérivées SubClassNode qui ne sont pas abstract doivent implémenter cette méthode comme suit :
public Node cloneNode (boolean forceDuplicate) { SubClassNode node = new SubClassNode (); node.duplicateNode (this, forceDuplicate); return node; }
public boolean getCollidable () (capacité ALLOW_COLLIDABLE_READ) public void setCollidable (boolean collidable) (capacité ALLOW_COLLIDABLE_WRITE) Ces méthodes permettent d'interroger ou de modifier la sensibilité d'un noeud et tous ses enfants à la collision avec d'autres formes (true par défaut).
public boolean getPickable () (capacité ALLOW_PICKABLE_READ) public void setPickable (boolean pickable) (capacité ALLOW_PICKABLE_WRITE) Ces méthodes permettent d'interroger ou de modifier la sensibilité d'un noeud et tous ces enfants pour pouvoir l'intercepter avec la souris ou un autre périphérique (true par défaut).
La classe javax.media.j3d.Leaf
Cette classe abstract dérive des classes SceneGraphObject, Node et représente une feuille dans l'arbre d'une scène 3D. C'est la super classe des classes représentant les formes 3D, les fonds d'écran, les comportements, les sources de lumière, les sources sonores.
Elle ne définit qu'un constructeur par défaut public.La classe javax.media.j3d.Group
Cette classe dérive des classes SceneGraphObject, Node et représente un groupe dans l'arbre d'une scène 3D. C'est la super classe des classes utilisées comme groupe et comme transformation.
Champs (constantes de capacité)
public static final int ALLOW_CHILDREN_READ public static final int ALLOW_CHILDREN_WRITE public static final int ALLOW_CHILDREN_EXTENDCes capacités permettent d'autoriser l'interrogation et la modification de la liste des enfants dont ce groupe est le parent.
public static final int ALLOW_COLLISION_BOUNDS_READ public static final int ALLOW_COLLISION_BOUNDS_WRITECes capacités permettent d'autoriser l'interrogation et la modification des limites utilisées pour la collision de l'objet 3D représenté par ce groupe.
Principales méthodes
public void addChild (Node child) (capacité ALLOW_CHILDREN_EXTEND) public void insertChild (Node child, int index) (capacité ALLOW_CHILDREN_EXTEND) public void setChild (Node child, int index) (capacité ALLOW_CHILDREN_WRITE) Ces méthodes permettent d'ajouter, d'insérer ou de modifier l'enfant child à l'indice index de ce groupe.
public void removeChild (int index) (capacité ALLOW_CHILDREN_WRITE)
Retire l'enfant de ce groupe à l'indice index.
public Node getChild (int index) (capacité ALLOW_CHILDREN_READ) public java.util.Enumeration getAllChildren () (capacité ALLOW_CHILDREN_READ) public int numChildren () (capacité ALLOW_CHILDREN_READ) Ces méthodes permettent d'interroger sur ce groupe l'enfant à l'indice index, la liste de tous les enfants sous forme d'énumération ou le nombre d'enfants.
public Bounds getCollisionBounds () (capacité ALLOW_COLLISION_BOUNDS_READ) public void setCollisionBounds (Bounds bounds) (capacité ALLOW_COLLISION_BOUNDS_WRITE) Ces méthodes permettent d'interroger ou de modifier les limites utilisées pour la collision de l'objet 3D représenté par ce groupe.
Exemples
Applets MultiCubes, Clown, WaterGlass, TextTranslation.
La classe javax.media.j3d.BranchGroup
Cette classe dérive des classes SceneGraphObject, Node, Group et représente le groupe utilisé comme racine de l'arbre d'une scène 3D. Un groupe de cette classe peut être utilisé plusieurs fois dans une scène 3D mais seule une instance de cette classe peut être rattachée à une instance des classes SimpleUniverse ou Locale utilisées dans un univers 3D, avec la méthode addBranchGraph ().
Champ (constante de capacité)
public static final int ALLOW_DETACHCette capacité permet d'autoriser le détachement de ce groupe de son parent.
Principales méthodes
public void compile ()Compile l'arbre dont la racine est ce groupe.
public void detach () (capacité ALLOW_DETACH)Détache ce groupe de son parent.
Exemples
Toutes les applets 3D.
La classe javax.media.j3d.TransformGroup
Cette classe dérive des classes SceneGraphObject, Node, Group et représente un groupe de transformation utilisé pour appliquer une transformation géométrique à tous les enfants de ce groupe. La description géométrique de la transformation est mémorisée dans une instance de la classe Transform3D.
Champs (constantes de capacité)
public static final int ALLOW_TRANSFORM_READ public static final int ALLOW_TRANSFORM_WRITECes capacités permet d'autoriser l'interrogation et la modification de la transformation mémorisée par ce groupe.
Constructeurs
public TransformGroup () public TransformGroup (Transform3D transform)Principales méthodes
public void getTransform (Transform3D transform) (capacité ALLOW_TRANSFORM_READ) Copie la transformation mémorisée par ce groupe dans l'objet transform.
public void setTransform (Transform3D transform) (capacité ALLOW_TRANSFORM_WRITE) Recopie la transformation transform dans celle mémorisée par ce groupe.
Exemples
Applets CubeSides, MultiCubes, SimpleObjects, HelloWorld3D, ObjectFileDemo, Clown, SphereConstruction, WaterGlass, SimpleTexturedObjects, LitPlane, MouseApplet3D, TextTranslation, AlphaTest, Clock3D, SunEarthMoonMotion.
La classe javax.media.j3d.Transform3D
Cette classe mémorise la transformation géométrique appliquée par un groupe de classe TransformGroup.
La classe Transform3D utilise une matrice 4x4 qui permet de stocker toutes les transformations géométriques utiles en 3D : translation, rotation, homothétie, symétrie, projection. Les calculs des points à l'écran utilisent la multiplication de matrices de transformations entre elles et le produit de ces matrices avec les coordonnées (x,y,z) des points 3D.
La classe Transform3D s'adresse autant aux personnes connaissant ces principes d'utilisation des matrices en 3D qu'à celles désirant créer des transformations géométriques sans se soucier de leur implémentation. Les méthodes décrites ci-dessous s'adressent aux néophytes par soucis de simplification. Ils suffit de les appliquer sur la transformation identité créé avec le constructeur par défaut de la classe Transform3D.Principaux constructeurs
public Transform3D () public Transform3D (Transform3D transform)Ces constructeurs créent une instance de Transform3D initialisée avec une transformation identité ou par recopie de transform.
Principales méthodes
public final void setIdentity ()Modifie cette transformation en une transformation identité (qui n'a aucun effet).
public final void setTranslation (Vector3f transl)Modifie cette transformation en une translation utilisant les valeurs sur les trois axes x, y, z de transl.
public void rotX (double angle) public void rotY (double angle) public void rotZ (double angle)Ces méthodes permettent de modifier cette transformation en une rotation d'angle angle radians autour de l'axe x, y ou z. Le sens positif de rotation est donné par la figure de l'orientation d'un repère 3D.
public final void setScale (double scale) public final void setScale (Vector3d scales)Ces méthodes permettent de modifier cette transformation soit en une homothétie de facteur scale sur les trois axes x, y, z (agrandissement si scale > 1 ou réduction si scale < 1), soit en une homothétie utilisant les facteurs sur les trois axes x, y, z de scales.
public final void mul (Transform3D transform2)Permet de multiplier la matrice de cette transformation avec celle de l'instance transform2. transform1.mul (transform2) correspond en interne à matriceTransform1 = matriceTransform1 * matriceTransform2. Comme le montre la figure ci-dessous, un groupe de transformation utilisant la multiplication des deux matrices des transformations transform1 et transform2 a le même effet que celui de chaîner deux groupes de transformation utilisant les transformations transform1 et transform2. Faites attention à l'ordre dans lequel vous faites vos multiplications car la multiplication de matrice n'est pas commutative.
Figure 7. Multiplication de matrices de transformation
Les transformations sont toujours relatives au centre du repère. N'oubliez pas ceci surtout pour les rotations ou les homothéties appliquées après une translation !
Les méthodes rotX (), rotY (), rotZ (), setScale () et setTranslation () appelées sur une même instance de la classe Transform3D ne sont pas cumulatives et chaque appel à l'une des méthodes rotX (), rotY (), rotZ () annule la transformation précédente. Par sécurité, il vaut mieux créer deux instances différentes des classes Transform3D et TransformGroup pour cumuler deux transformations ou utiliser la méthode mul ().
Exemples
Applets CubeSides, MultiCubes, SimpleObjects, HelloWorld3D, ObjectFileDemo, Clown, SphereConstruction, WaterGlass, SimpleTexturedObjects, LitPlane, TextTranslation, Clock3D, SunEarthMoonMotion.
Les classes algébriques
Certaines des classes fournies avec Java 3D sont utiles pour représenter les vecteurs, les coordonnées d'un point ou les matrices. Comme ces classes ont un intérêt pour le calcul algébrique plus vaste que le seul domaine de la 3D, elles appartiennent à un package indépendant javax.vecmath.
Comme le montre la hiérarchie de ce package ci-dessous, la plupart de ces classes manipulent des coordonnées ayant 2, 3 ou 4 valeurs de type float ou double, voir de type byte ou int pour certaines classes. Le nombre de valeurs stockées et leur type est utilisé comme suffixe du nom de la classe : par exemple, une instance de classe Point4f stocke 4 valeurs de type float et une instance classe Vector3d stocke 3 valeurs de type double.
- java.lang.Object
- javax.vecmath.AxisAngle4d
- javax.vecmath.AxisAngle4f
- javax.vecmath.GMatrix
- javax.vecmath.GVector
- javax.vecmath.Matrix3d
- javax.vecmath.Matrix3f
- javax.vecmath.Matrix4d
- javax.vecmath.Matrix4f
- javax.vecmath.Tuple2d
- javax.vecmath.Point2d
- javax.vecmath.Vector2d
- javax.vecmath.Tuple2f
- javax.vecmath.Point2f
- javax.vecmath.TexCoord2f
- javax.vecmath.Vector2f
- javax.vecmath.Tuple3b
- javax.vecmath.Color3b
- javax.vecmath.Tuple3d
- javax.vecmath.Point3d
- javax.vecmath.Vector3d
- javax.vecmath.Tuple3f
- javax.vecmath.Tuple3i
- javax.vecmath.Point3i
- javax.vecmath.Tuple4b
- javax.vecmath.Color4b
- javax.vecmath.Tuple4d
- javax.vecmath.Point4d
- javax.vecmath.Quat4d
- javax.vecmath.Vector4d
- javax.vecmath.Tuple4f
- javax.vecmath.Color4f
- javax.vecmath.Point4f
- javax.vecmath.Quat4f
- javax.vecmath.Vector4f
- javax.vecmath.Tuple4i
- javax.vecmath.Point4i
Les classes Point3f, Vector3f et Color3f représentant un point et un vecteur, ainsi que leur super classe Tuple3f utilisant le type float sont décrites ci-dessous brièvement. La classe Tuple3d et ses classes dérivées Point3d et Vector3d utilisées par certaines méthodes Java 3D décrites dans ce manuel déclarent les mêmes champs et méthodes.
La classe javax.vecmath.Tuple3f
Cette classe abstract qui implémente l'interface java.io.Serializable est la super classe des classes Point3f, Vector3f, Color3f et TexCoord3f. Elle mémorise 3 coordonnées dans les champs public x, y, z de type float et fournit un ensemble de méthodes pour effectuer des opérations mathématiques de base (addition, soustraction, valeur opposée, encadrement,...).
Champs
public float x public float y public float zLa classe javax.vecmath.Point3f
Cette classe dérive de la classe Tuple3f et représente les coordonnées (x, y, z) d'un point 3D.
Principaux constructeurs
public Point3f () public Point3f (float x, float y, float z) public Point3f (float [ ] p1) public Point3f (Point3f point)Ces constructeurs créent un point initialisé à partir des paramètres x, y, z, p1 ou point. Le constructeur par défaut initialise à 0 les champs x, y et z du point.
Principales méthodes
public final float distance (Point3f p1)
public final float distanceSquared (Point3f p1)Ces méthodes renvoient la distance ou la distance au carré entre ce point et le point p1.
Exemples
Applets Pyramid, LightEffect, TextTranslation.
Classe AxisShape.La classe javax.vecmath.Vector3f
Cette classe dérive de la classe Tuple3f et représente les coordonnées (x, y, z) d'un vecteur 3D.
Constructeurs
public Vector3f () public Vector3f (float x, float y, float z) public Vector3f (float [ ] v1) public Vector3f (Vector3f vector)Ces constructeurs créent un vecteur initialisé à partir des paramètres x, y, z, v1 ou vector. Le constructeur par défaut initialise à 0 les champs x, y et z du vecteur.
Principales méthodes
public final float length () public final float lengthSquared ()Ces méthodes renvoient la longueur (norme) ou la longueur au carré de ce vecteur.
public final void normalize ()Normalise ce vecteur, pour que ce vecteur soit de même direction avec une norme égale à 1.
public final float dot (Vector3f v1)Renvoie le produit scalaire entre ce vecteur et v1.
public final void cross (Vector3f v1, Vector3f v2)Mémorise dans ce vecteur le produit vectoriel entre v1 et v2.
public final float angle (Vector3f v1)Renvoie l'angle en radian entre ce vecteur et v1.
Exemples
Applets MultiCubes, SimpleObjects, Clown, SphereConstruction, SimpleTexturedObjects, LightEffect, LitApplet3D, SunEarthMoonMotion.
La classe javax.vecmath.Color3f
Cette classe dérive de la classe Tuple3f et représente les composantes RGB Rouge, Vert, Bleu d'une couleur exprimées entre 0.f et 1.f (correspondant au champs x, y, z).
Constructeurs
public Color3f () public Color3f (float r, float g, float b) public Color3f (float [ ] c1) public Color3f (Color3f color)Ces constructeurs créent une couleur initialisée à partir des paramètres r, g, b, c1 ou color. Le constructeur par défaut initialise à 0 les champs x, y et z de la couleur.
Exemples
Applets Pyramid, LightEffect, LitApplet3D, SunEarthMoonMotion.
|