Java3D création d`objets visuels
Transcription
Java3D création d`objets visuels
Java3D création d'objets visuels Les objets prédéfinis : box, sphère, cylindre Classes mathématiques Classes géométriques : − − − − Classe GeometryArray Sousclasses de GeometryArray Sousclasses de GeometryStripArray Sousclasses de IndexedGeometryArray Apparence et attributs Classe GeometryInfo d'après le tutoriel de Sun Java3D Création d'objets 3D : géométrie Création d'objets 3D : géométrie 3 façons de créer un contenu géométrique : − Utiliser les classes utilitaires pour les objets box, sphere, cone, cylinder − Spécifier les coordonnées des sommets pour les points, les segments de ligne, les surfaces polygonales − Utiliser un « chargeur de géométrie » Rappel sur l'univers virtuel : − avec un objet Locale, on a un système de coordonnées pour tous les objets dans l'univers virtuel. − Toutes les unités sont données en mètres. Classe Shape3D Une instance de la classe Shape3D définit un objet visuel Shape3D est une sousclasse de Leaf, donc ne peutêtre qu'une feuille dans le graphe de scène L'objet Shape3D ne contient pas d'information de géométrie, ni d'apparence : il faut donc définir ces NodeComponent => objet visuel est l'ensemble de la feuille et des 2 NodeComponent Constructeurs de Shape3D : sans composante, avec la composante géométrie, ou les 2 Shape3D(Geometry geometry, Appearance appearance) Classe Shape3D Méthodes permettant de modifier ou récupérer un des NodeComponent void setGeometry(Geometry geometry) Appearance getAppearance() Capacités des objets Shape3D : − Héritées des classes SceneGraphObject, Node, Leaf − Propres à cette classe : ALLOW_GEOMETRY_READ | WRITE ALLOW_APPEARANCE_READ | WRITE ALLOW_COLLISION_BOUNDS_READ | WRITE Hiérarchie des classes Node et NodeComponent Définir une classe objet visuel Public class VisualObject extends Shape3D { private Geometry voGeometry; private Appearance voAppearance; public VisualObject() { voGeometry = new createGeometry(); voAppearance = new createAppearance(); this.setGeometry(voGeometry); this.setAppearance(voAppearance); } private Geometry createGeometry() { } private Appearance createAppearance() { } } Classes utilitaires dérivées de Group les primitives géométriques Toutes les classes utilitaires pour créer les formes de base sont groupées dans un package com.sun.j3d.utils.geometry.Primitive d'où peut aussi dériver une nouvelle classe que vous aurez créée Classes où la géométrie est fixe mais pas l'apparence (contrairement à ColorCube où tout est fixé) : − une méthode permet de la définir void setAppearance(Appearance app) Pour toutes ces classes une méthode Shape3d getShape(int id) permet de récupérer l'objet Shape3D de n°id composant une partie de la primitive appelante. On pourra définir pour chaque partie (id) sa propre apparence setAppearance(int, Appearance) Box, Cone, Cylinder, Sphere Toutes ces classes ont un constructeur par défaut, et un constructeur permettant de modifier les tailles et d'inclure l'apparence − Box : Par défaut : 2x2x2, centré à l'origine => (1,1,1) → − Cône : Par défaut : rayon=1, hauteur=2, le centre de sa boîte − Cylindre : Par défaut : rayon=1, hauteur=2, le centre de sa boîte − Sphere : (1,1,1) englobante est centrée en (0,0,0) englobante est centrée en (0,0,0) Par défaut : rayon=1, centrée à l'origine − La sphère est composée d'un unique Shape3D donc − Primitives géométriques La géométrie d'une classe « primitive » ne définit pas la couleur => dérivation de la couleur de la composante Appearance. − Par défaut l'objet visuel sera blanc La classe Primitive définit aussi des valeurs par défaut communes aux objets (ex: nb de polygones utilisés pour représenter la surface) Par défaut, toutes les primitives de même taille (ex : 2 sphères de même rayon) partagent le même composant géométrie. On peut éviter cela en construisant la ou les primitives en passant en paramètre le flag GEOMETRY_NOT_SHARED Exemple d'utilisation Yoyo fait à partir de 2 cônes Démo : Yoyo Classes mathématiques Tuple* Classe mathématique javax.vecmath rassemble tous les objets mathématiques tels les matrices, les points, les axes, ... Tuple* représente toutes les classes Point*, Color*, Vector*, TexCoord* où * a la même valeur : − * : 2f, 2d, 2b ; 3f, 3d, 3b, 3i ; 4f, 4d, 4b, 4i 2, 3, et 4 représentent l'espace de travail 2D, 3D, 4D f : flottants, d : doubles, b : bytes, i : integers Pour chacune des classes, il existe : des constructeurs avec par défaut les coordonnées à 0 des méthodes de manipulation (test d'égalité, négation, opérations) Classes mathématiques classes des points Les classes Point* sont généralement utilisées pour définir : les coordonnées d'un sommet La position d'une image raster Position d'une source lumineuse Toute donnée de position * prend les valeurs : 2d, 2f, 3d, 3f, 4d, 4f Méthodes propres : float distance(Point3f p1) : distance euclidienne de p1 à P float distanceSquared(Point3f p1) : carré de la distance p1 à P float distanceL1(Point3f p1) : abs(x1x)+abs(y1y)+abs(z1z) Classes mathématiques classes des couleurs Les classes Color* sont utilisées pour définir une couleur qui peutêtre associée à : un sommet, la propriété du matériel, le brouillard, ... * prend les valeurs : 3d, 3f, 3b : 3 couleurs RGB 4d, 4f, 4b : 3 couleurs + transparence Méthodes propres : void set(Color color) : met la couleur en utilisant l'objet AWT Color get() : récupère la couleur de l'objet AWT Color Classes mathématiques classes des vecteurs Les classes Vector* sont utilisées pour définir : des normales à la surface la direction d'une source lumineuse (ou son) une translation ... * prend les valeurs 2, 3, 4, d et f Méthodes propres, dont : void cross(Vector3f v1, Vector3f v2) : calcule le produit vectoriel de v1 par v2 et met le résultat dans le vecteur appelant void normalize() : normalise le vecteur appelant Classes mathématiques classes des TexCoord Les classes TexCoord* sont utilisées pour représenter un ensemble de coordonnées de texture 2D (resp 3D) alors * prend la valeur 2f (resp 3f) les constructeurs pour ces classes sont similaires aux constructeurs de la classe Tuple*. Pas de méthodes propres : sont héritées de leur superclasse Tuple* Classes géométriques en 3D tout est modélisé et rendu avec des données basées sur des sommets. en Java3D, une superclasse abstraite Geometry est utilisée pour décrire tout objet comme une instance de cette classe. 3 types de sousclasses : − − − géométrie basée sur des sommets non indexés (chaque fois que l'objet est rendu ses sommets ne peuvent pas être utilisés plusieurs fois) géométrie basée sur des sommets indexés autres objets visuels (Raster, Text3D, CompressedGeometry) Classes géométriques classe GeometryArray permet de décrire tous les objets : en maintenant des données par sommet dans des tableaux (array) en spécifiant les points, lignes, polygones pleins (triangles, quadrilatères) exemple : un triangle : un tableau à 3 entrées est spécifié : un élément par sommet 3 autres tableaux peuvent être définis pour stocker respectivement par sommet la couleur, normale à la surface, et coordonnées de texture = « tableaux de données » 3 étapes : construction d'un objet vide remplir l'objet avec des données associer l'objet à partir des objets Shape3D Classe GeometryArray étape 1 : objet vide A la construction de l'objet initial, il faut définir : nombre de sommets nécessaire type de données devant être stockées pour chaque sommet (localisation des points, couleur, normale, coordonnées texture) Une seule méthode de constructeur : void GeometryArray(int vertexCount, int vertexFormat) où vertexFormat permet de positionner des bits associés aux types de données stockées par sommet : − − − − COORDINATES :spécifie que le tableau contient les coordonnées des sommets ; ce bit doit toujours être positionné ! NORMALS : spécifie que les tableaux contiendront les normales à la surface COLOR_3(ou 4) : les tableaux décriront la couleur TEXTURE_COORDINATE_2(ou 3) : les tableaux décriront les coordonnées de texture Classe GeometryArray étape 1 : objet vide Classe GeometryArray étape 2 : associer des données à l'objet Il faut associer des données aux sommets : − soit sommet par sommet : void setCoordinate (int index, Point* coordinate[]) void setColor (int index, float color[]) void setNormal (int index, Vector* normal[]) void setTextureCoordinate (int texCoorSet, int index, TexCoord* coordinate[]) − soit plusieurs sommets à la fois void setCoordinates (int index, float coordinates[]) void setColors (int index, Color* colors[]) void setNormals (int index, float normals[]) void setTextureCoordinates (int texCoorSet, int index, float TexCoordinates[]) Classe GeometryArray étape 2 : associer des données à l'objet Classe GeometryArray étape 2 : associer des données à l'objet Classe GeometryArray étape 3 : associer Shape3D aux objets créés Les objets GeometryArray sont référencés en créant des nouveaux objets Shape3D. Les objets Shape3D sont ensuite ajoutés à un BranchGroup qui pourra être ajouté n'importe où dans le graphe. Classe GeometryArray : exemple Sousclasses de GeometryArray 5 sousclasses : Line/Point/Quad/Triangle Array GeometryStrip Array Sousclasses de GeometryArray Pour les 4 premières sousclasses, il existe des constructeurs semblables à la classe GeometryArray PointArray (int vertexCount, int vertexFormat) Pour la suivante GeometryStripArray et ses sousclasses, les constructeurs sont de la forme − LineStripArray (int vtxCount, int vertexFormat, int stripVtxCounts[]) où stripVtxCounts correspond à l'ensemble du nombre de sommets par « formes » (ou strip) composant l'objet − Exemple : int totalV = 4*(N+1) ; Point3f coords[] = new Pointf3f[totalV]; int stripV[] = {N+1, N+1, N+1, N+1}; TriangleFanArray tfa = new TriangleFanArray(totalV,TriangleFanArray.COORDINATES, stripV); Sousclasses de GeometryArray 2 TriangleFanArray intérieurs circulaires 2 TriangleFanArray cônes Sousclasses des IndexedGeometryArray Les sousclasses précédentes (sauf les GeometryStripArray) déclarent des sommets inutilement (ex : 24 sommets d'un cube pour décrire les 6 faces !) => IndexedGeometryArray 2 types de tableau sont utilisés : « data arrays » et « index arrays » { { front face top face (1, 1, 1) (1, 1, 1) (1, 1, 1) (1, 1, 1) (1, 1, 1) (1, 1, 1) (1, 1, 1) (1, 1, 1) Sousclasses IndexedGeometryArray et IndexedGeometryStripArray Constructeurs IndexedGeometryArray : IndexedGeometryArray (int vc, int vf, int indexCount) − − vc = nombre de sommets (nb éléments dans « data array » ) indexCount = nombre d'éléments dans « index array » Indexed[Point, Line, Triangle, Quad]Array Constructeurs IndexedGeometryStripArray : IndexedGeometryStripArray (int vc, int vf, int indexCount, int stripVertexCounts[]) où − − − vc = nombre de sommets (nb éléments dans « data array » ) indexCount = nombre d'éléments dans « index array » StripVertexCounts[] = nombre de sommets par « strip » Indexed[LineStrip, TriangleStrip, TriangleFan]Array Sousclasses IndexedGeometryArray et IndexedGeometryStripArray Méthodes pour ces classes : void setCoordinateIndex(int index, int coordinateIndex) − − void setCoordinateIndices(int index, int coordinateIndex[]) − « index » : numéro du sommet désigné dans cet objet « coordinateIndex » : numéro d ans le tableau des données des coordonnées qui sera associé au sommet « index » « index » : numéro du sommet de départ à partir duquel on associera le tableau des coordonnées « coordinateIndex[] » Remarque : « Coordinate » peut être remplacé dans les méthodes précédentes par n'importe quelle donnée (« Color », « Normal », « TextureCoordinate ») Remarques : Perte de temps au niveau du rendu Résumé : exemple de programme le Yoyo Apparence et attributs Un objet Apparence ne dit pas comment un objet Shape3D apparaît, mais sait où trouver toutes les informations : peut référencer plusieurs objets d'autres sousclasses de la classe NodeComponent Peut être partagé entre plusieurs objets Shape3D Apparence et attributs Objet Apparence peut référencer plusieurs sous classes appelées des objets d'attributs d'apparence − Aspect de l'objet : Point/Line/Polygon Attributes Coloring/Transparency Attributes RenderingAttributes − Éclairage de l'objet : − Material Texture de l'objet : TextureAttributes Texture TexCoordGeneration Apparence : méthodes Constructeur : Appearance() Points et lignes sont dessinés avec des tailles et des largeurs de 1 pixel et sans antialliassage Couleur = blanc Transparence = non Buffer de profondeur = mis, accessible en R/W Void set*Attributes (*Attributes starAttributes) * = Point, Line, Polygon, Coloring, Transparency, Rendering Apparence : LineAttributes 1/2 Par défaut : trait plein de 1 pixel de large sans antialiassage Modifier les paramètres : Taille du point et antialiassage : semblable au point Void setLinePattern (int linePattern) où linePattern = − − − − − PATTERN_SOLID : ligne pleine PATTERN_DASH : tirets = 8 pixels allumés, 8 pixels éteints PATTERN_DOT : pointillés = 1 pixel allumé, 7 pixels éteints PATTERN_DASH_DOT : 7 pixels allumés, 4 pixels éteints, 1 pixel allumé et 4 pixels éteints PATTERN_USER_DEFINED : défini par l'utilisateur Apparence : LineAttributes 2/2 Pour déterminer un motif de ligne on utilise 2 données : − « Mask » : masque de 16 bits ; 1 = allumé, 0 = éteint ; 1er pixel du motif correspond au bit 0 (ex : 0x00ff => 8 pixels allumés, 8 pixels éteints) − « ScaleFactor » : facteur de répétition de chaque bit du masque (ex : facteur 3 ; mask = 0x0301 => motif = 3 on, 21 off, 6 on, 18 off Apparence : PolygonAttributes Par défaut : polygone rempli, pas de culling, pas de déplacement de polygone Attributs pouvant être modifiés : Nombre de polygones rendu : « cull » = non rendu void setCullFace(int cullFace) avec cullFace = CULL_FRONT, CULL_BACK, CULL_NONE Manière de rendre le polygone : points ou lignes ou plein void setPolygonMode (int polygonMode) où PolygonMode = POLYGON_POINT, POLYGON_LINE, POLYGON_FILL Eviter l'effet visuel de la « couture faitmain » lorsque la représentation « fil de fer » apparaît et disparaît autour de l'arête d'un polygone (car les 2 rendus n'ont pas tout à fait la même distance) void setPolygonOffset (float offset) où « offset » est le déplacement rajouté pour ajuster les 2 profondeurs Rendre les faces arrières des polygones visibles en les rendant négatives (« flipped ») : void setBackFaceNormalFlip (boolean flip) : flip est vrai, le polygone est rendu Apparence : ColoringAttributes Permet de spécifier pour les primitives la couleur, et s'il y a interpolation de couleur à travers elles. Par défaut : couleur blanche, ombrage Gouraud 2 types de données peuvent être modifiées : La couleur : void setColor(Color3f color) L'ombrage entre les primitives : void setShadeModel (int model) où model = − − − − SHADE_GOURAUD : interpolation entre les couleurs des sommets SHADE_FLAT : pas d'interpolation la primtive prend la couleur d'un sommet FASTEST : utilise le rendu le plus rapide (dépendant du hardware), NICEST : utilise le rendu dont l'ombrage donne les meilleurs résultats au sens de l'implémenteur Java3D et donc dépendant également du hardware La couleur intrinsèque définie par cet objet sera sans effet dès qu'une lumière ou des couleurs aux sommets seront définies. Apparence : TransparencyAttributes Par défaut : sans transparence (valeur à 0.0 = opaque et 1.0 = complètement transparent) 4 données modifiables : setTransparency (float t) où 0.0 ≤ t ≤ 1.0 setTransparencyMode (int tMode) où tMode donne la méthode utilisée pour produire la transparence : − − − SCREEN_DOOR : motifd où certains pixels sont complètement transparents et d'autres complètement opaques (% transparents donné par t) FASTEST/NICEST/NONE BLENDED : chaque pixel est doté d'un indice décrivant son degré de transparence. Il est utilisé pour modifier la fonction de mélange qui sera alors déterminée par les attributs srcBlendFunction et dstBlendFunction. Moins rapide que le mode SCREEN_DOOR. Apparence : TransparencyAttributes Dernier mode de transparence : − BLENDED (suite) : Par défaut l'équation est égale à : alphasrc * coulsrc + alphadst * couldst où alphadst = 1 – alphasrc et alphasrc = 1 t sachant que si une composante alphapix a été définie dans la géométrie de l'objet alors alphasrc = alphapix*(1 t) Fonction de mélange : − − − La fonction source spécifie la valeur qui est multipliée à la couleur source : void setSrcBlendFunction (int blendFct) La fonction destination spécifie la valeur qui est multipliée à la couleur destination : void setDstBlendFunction (int blendFct) Dans les 2 cas, blendFct vaut: − BLEND_ZERO la fonction est f = 0. BLEND_ONE la fonction est f = 1. BLEND_SRC_ALPHA la fonction est f = alphasrc. BLEND_ONE_MINUS_SRC_ALPHA la fonction est f = 1 – alphasrc L'équation finale est la somme des 2 produits précédents (source et destination) Apparence : RenderingAttributes 1/2 Contrôle du test alpha quand et comment la composante alpha est utilisée Valeur du test alpha : setAlphaTestValue (float value) Fonction de test alpha : utilisée pour comparer la valeur du test alpha avec la valeur de alpha de chaque pixel. Cette fonction est donnée par setAlphaTestFunction (int fct) où fct est égal à : ALWAYS – pixels sont toujours dessinés qq soit la valeur de alpha. Valeur par défaut NEVER pixels ne sont jamais dessinés qq soit la valeur de alpha . EQUAL pixels sont dessinés si la valeur alpha du pixel = valeur du test alpha NOT_EQUAL / LESS / LESS_OR_EQUAL / GREATER / GREATER_OR_EQUAL pixels sont dessinés si la valeur alpha du pixel ≠ valeur du test alpha. (< , ≤ , > , ≥ ) Définition de la fonction d'opération de rasterisation : SetRasterOpEnable (boolean) pour pouvoir la modifier. SetRasterOp (int opRaster) où l'opération est ROP_COPY DST = SRC. (Opération par défaut) ou ROP_XOR DST = SRC ^ DST. Apparence : RenderingAttributes 2/2 Contrôle du test du tampon de profondeur quand et comment il est utilisé pour l'élimination des surfaces cachées − − setDepthBufferEnable(bool) : autorise ou non le tampon de profondeur setDepthBufferWriteEnable(bool) : écriture dans le tampon Autres spécifications pour le rendu : les couleurs aux sommets définies dans une géométrie peuvent ne pas être prises en compte (ignoreVertexColors est vrai) et s'il y a une lumière => material, sinon ColoringAttributes void setIgnoreVertexColors (boolean ignoreVertexColors) les objets invisibles peuvent ne pas être rendus, mais sont toujours présents en cas de collision ... void setVisible (boolean flag) (vrai par défaut) Exemple de programme « Twisted Strip » polygones ont 2 faces, mais souvent 1 seule face a besoin d'être visible => face avant est visible Généralement une face avant = sens inverse des aiguilles d'une montre En revanche dans les strip les faces avant alternent pour chaque élément du strip. Exemple de programme « Twisted Strip » polygones ont 2 faces, mais souvent 1 seule face a besoin d'être visible => face avant est visible Objet à créer : « strip » tordu qui tourne autour de l'axe Oy => certaines parties disparaissent (ne sont pas visibles, transparentes) lorsque c'est la face arrière du polygone qui est vue => supprimer le culling (CULL_NONE) pour voir les polygones de toutes les faces programme va définir 2 objets (fil de fer, surface solide) et puisque les objets ont la même localisation alors seul le fil de fer sera visible quand la surface ne le sera pas => polygone plein sera en culling arrière et le polygone fil de fer (POLYGON_LINE) sera sans culling ! Exemple : attributs plein = cull ligne = non plein = non ligne = o/n ligne = cull ligne = non Régions (bounds et scope) Bounds : définit une région, un espace pour lequel un noeud est appliqué (on parle de volume fermé convexe permettant de déterminer des intersections, des opérations de culling) Scope : spécifie un groupe d'objets par leur position dans le graphe de scène ; permet de limiter une action à un groupe d'objets plutôt qu'à une région Remarque : l'utilisation des « bounds » est obligatoire pour tous les noeuds tandis que celle de scope est optionnelle Bounds Utilisés pour les lumières, les fonds, les comportements et d'autres applications Java3D NodeComponent est donc référencé par l'objet qui a besoin de spécifier un bounds, et bouge avec l'objet qu'il référence (même système local) Recommandations : utiliser toujours la région la plus petite possible (engendre moins de calculs) Quelques méthodes communes : bounds closestIntersection(Bounds[] objects) : renvoie parmi les « objects » celui le plus proche du bounds appelant void combine(Bounds object) : l'objet résultant englobe l'objet appelant et « object » et est stocké dans l'objet appelant Bounds : 3 principales BoundingSphere : − − BoundingBox : − plus facile Plusieurs constructeurs dont BoundingSphere(Bounds[] objects) construit à partir des objets défini par 2 points (min et max) et les côtés sont parallèles aux axes BoundingPolytope : plus compliquée − − − Définit un polyèdre utilisant l'intersection d'au moins 4 demiespaces (région de l'espace limitée sur un côté par un plan infini) défini par la liste des plans qui créent une région convexe fermée, un demiplan est défini par 4 points (A, B, C, D) tq Ax+By+Cz+D < 0 Par défaut 6 plans définissant le cube unité Bounds : BoundingLeaf Cet objet BoundingLeaf permet d'associer une région à un objet (feuille) plutôt qu'à l'ensemble de la scène − Exemple d'utilisation : scène avec une lumière stationnaire qui éclaire des objets se déplaçant. − − Avec un objet bounds classique il faudra que la région englobe tout l'espace de déplacement Avec un objet BoundingLeaf placé dans la scène avec l'objet visuel, il se déplacera avec lui indépendamment de la source lumineuse Où déclarer la boundingLeaf ? − − Il doit être associé au NodeComponent (background, light, fog, ...) void setApplicationBoundingLeaf (BoundingLeaf bl) Et raccroché à l'objet visuel (addChild (sur le TG appelant)) Shape3D avec plusieurs géométries Plusieurs géométries dans un même Shape3D : ATTENTION lorsqu'un objet Shape3D est construit avec le constructeur par défaut ses pointeurs sur Geometry et Appearance sont null, donc ne pas oublier de faire : − − void removeGeometry(0) : supprime la première géométrie décrite void setGeometry(Geometry og) : indique la géométrie de l'objet void addGeometry (Geometry objectGeometry) : permet d'ajouter des géométries à l'objet La liste des géométries d'un shape3D doit être composées de géométries de classe équivalente : − − − PointGeometryArray : [Indexed]PointArray LineGeometryArray : [Indexed]{LineArray, LineStripArray} PolygonGeometryArray : les autres sauf CompressedGeometry, Raster, text3D (classes indépendantes) Plusieurs géométries : exemple ⇓ GeometryInfo permet de définir des formes sans être obligé de définir tous les triangles du polygones : polygones concaves, non planaires même avec des trous l'objet GeometryInfo, et d'autres classes, permettent de convertir la géométrie créée en géométrie triangulaire indexée pour être rendu en Java3d Exemple : voiture : définir le contour de la voiture comme un polygone dans un objet GeometryInfo subdivision en triangles se fera grâce à l'objet Triangulator Objet Triangulator Java3d ne supporte pas de primitives pleines de plus de 4 faces => c'est le programmeur qui devra utiliser des facettes pour décomposer des polygones plus complexes en objets existants (tfa, ...) classe Triangulator convertit de tels polygones en triangles : Triangulator() : construit un objet Triangulator void triangulate(GeometryInfo gi) : convertit l'objet gi à partir d'une primitive POLYGON_ARRAY en une primitive de type TRIANGLE_ARRAY Exemple : tr.triangulate( gInfo) ; shape.setGeometry(gInfo.getGeometryArray()); Stripifier ; Génération de normales Générateur de normales : NormalGenerator calcule les vecteurs normaux aux surfaces de la géométrie Stripifier : convertit les triangles en triangle strips (calculer les normales avant) void generateNormals(GeometryInfo gi) void stripify(GeometryInfo gi) Pour créer un objet GeometryInfo, il faut spécifier : − le type de géométrie dont on a besoin : POLYGON/QUAD/TRIANGLE( /_FAN /_STRIP)_ARRAY − les coordonnées (et les «strip counts») sans préciser le nombre de sommets GeometryInfo : Exemple GeometryInfo : méthodes Triangulator est seulement utilisé avec une géométrie POLYGON_ARRAY avec les autres primitives on utilise plutôt Stripifier et NormalGenerator Quelques méthodes : void setColorIndices(int [] colorIndices) : met « colorIndices » dans le tableau des couleurs associé à la géométrie void setContourCounts(int[] contourList) : met la liste des contours « contourList » dans la liste des contours Exemple : voiture