Afficher des géométries 3D

 

 


Pré-requis

Les informations qui suivent fournissent brièvement des indications sur les procédures à suivre pour insérer un objet 3D dans une scène 3D.Reportez-vous, si nécessaire, à la documentation Sun de l'API Java3D pour les termes suivants:


Introduction

L'obtention d'un objet (cube, sphère, ou plus compliqué) dans une scène construite avec Java3D peut s'accomplir de 2 manières différentes:

Prenons l'exemple d'un simple cube à visualiser dans une scène 3D. Le premier cas consiste à utiliser un logiciel spécialisé pour modéliser ce cube puis à le sauvegarder dans un format de fichier reconnaissable par un "loader" Java3D. Le loader est un objet Java réalisant au minimum la construction de la géométrie du cube à partir du fichier issu d'un modeleur. Il esiste de nombreux "loaders". Plus de détails sont founis un peu plus bas.

La seconde technique consiste à construire directement la géométrie du cube par programme. Le package d'utilitaires de Java3D (com.sun.j3d.utils.geometry) contient des classes utilitaires pour les géométries de base que sont les sphères, boîtes, cylindres et cônes.

 


Les "loaders"

Un "loader" implémente l'interface Loader du package com.sun.j3d.loaders. Il réalise la lecture d'un fichier d'un type donné et permet de récupérer une Scene qui elle aussi est une interface à partir de laquelle il est possible de récupérer toutes les caractéristiques de la scène 3D (géométrie de tous les objets, points de vue, lumières, sons, ...).

La class Lw3dLoader du package com.sun.j3d.loaders.lw3d est un loader pour Lightwave3D de Newtek. Si vous possédez ce fantastique logiciel vous voilà en mesure d'intégrer vos créations dans une applet ou un programme Java3D. Dans le cas contraire, de nombreux fichiers gratuits sont disponibles sur internet.

La classe ObjectFile du package com.sun.j3d.loaders.objectfile est un loader de fichiers Wavefront qui est aussi un grand classique des logiciels 3D.

D'autres loaders, plus ou moins efficaces et complets, peuvent être récupérés sur Internet. Les plus courants permettent de charger des fichiers Lightwave3D, Wavefront, VRML, 3DS, ou encore DEM. Vous trouverez des liens sur la plupart d'entre-eux sur le site de Bill Day. Si vous en avez développé vous-même je serais trés intéressé de pouvoir les essayer.

Tous les loaders que l'on peut trouver réalisent généralement correctement le chargement de la géométrie des objets 3D décrits dans un fichier. Attention toutefois, le chargement des comportements, d'un point de vue ou d'autres caractéristiques de la scène n'est pas toujours correctement assuré, donc méfiez vous !

 


Construire une géométrie

Le but ici est de construire la géométrie (classe Geometry du package javax.media.j3d.Geometry) à fournir à un objet de classe Shape3D. Pour rappel, un objet Shape3D est une terminaison du "Scene Graph" qui référence une géométrie et son apparence. Donc contrairement à l'utilisation des loaders, la géométrie de l'objet à dessiner est construite par vos propres soins par votre programme ou applet.

Le package com.sun.j3d.utils.geometry contient des classes de création de primitives basiques comme une sphère, une boîte, un cylindre ou un cône. Vous pouvez ne vouloir qu'un demi cylindre par exemple. Dans ce cas, il est nécessaire d'écrire vous même vos fonctions de création de géométrie.

Les objets 3D sont composés de facettes. Voici donc 2 exemples trés simples de classes permettant de créer un objet Shape3D avec une géométrie ne comportant qu'une seule facette. Il est alors possible de s'en inspirer pour écrire des géométries plus compliquées, le principe sera le même.

 

Rectangle coloré, non sensible à l'éclairage de la scène

import javax.media.j3d.*;
import javax.vecmath.*;

public class JoColoredFace extends Shape3D
{
  private Point3f vert[] =
  {
    
// Coordonnées d'un rectangle
    new Point3f( 0.5f, 0.5f, 0.0f),
    new Point3f(-0.5f, 0.5f, 0.0f),
    new Point3f(-0.5f,-0.5f, 0.0f),
    new Point3f( 0.5f,-0.5f, 0.0f),
  };

  
// Création d'un carré de taille 1.0. Apparence par défaut.
  public JoColoredFace(float r, float g, float b)
  {
    this(1.0f, r, g, b, null);
  } 

  
// Création d'un carré de taille, de couleur et d'apparence donnée
  public JoColoredFace(float size, float r, float g, float b, Appearance app)
  {
    this(size, size, r, g, b, app);
  }

  
// Création d'un rectangle de largeur, hauteur, couleur et apparance fixée
  public JoColoredFace(float width, float height, float r, float g, float b, Appearance app)
  {
    int i,
    numVertex = vert.length;
    QuadArray geom = new QuadArray(numVertex,
                                                        QuadArray.COORDINATES |
                                                        QuadArray.COLOR_3);
    Color3f color = new Color3f(r, g, b);

    for (i=0; i<numVertex; i++)
    {
      vert[i].x *= width;
      vert[i].y *= height;
    }

    
// Attribution du tableau de coordonnées à la géométrie de l'objet
    geom.setCoordinates(0, vert);

    // Attribution de la couleur à chaque point de la géométrie
  for (i=0; i<numVertex; i++)
    geom.setColor(i, color);

    if (app != null)
      super.setAppearance(app);

    
// Passage de la géométrie à l'objet Shape3D
    this.setGeometry(geom);
  }
}

Fichier : JoColoredFace.java

Création d'une face colorée (carré ou rectangle) dans le plan XY. La couleur est directement fournie avec la géométrie. Le passage d'un objet Appearance permettra de contrôler des caractéristiques comme la transparence par exemple.

Face triangulaire sensible à l'éclairage de la scène

import javax.media.j3d.*;
import javax.vecmath.*;

public class JoLightedFace extends Shape3D
{
  
// Coordonnées du triangle
  private Point3f vert[] =
  {
    new Point3f(-0.5f,  0.5f, 0.0f),
    new Point3f( 0.5f,  0.0f, 0.0f),
    new Point3f(-0.5f, -0.5f, 0.0f),
  };

  public JoLightedFace(Appearance app)
  {
    TriangleArray geom = new TriangleArray(vert.length,
                                                               TriangleArray.COORDINATES |
                                                               TriangleArray.NORMALS);


    
// Attribution du tableau de coordonnées à la géométrie
    geom.setCoordinates(0, vert);

    // Calcul de la normale au triangle
    Vector3f normal = new Vector3f();
    Vector3f v1    = new Vector3f();
    Vector3f v2    = new Vector3f();

    v1.sub(vert[1], vert[0]);
    v2.sub(vert[2], vert[0]);

    normal.cross(v1, v2);
    normal.normalize();

    
// Attribution de la même normale aux 3 points du triangle
    geom.setNormal(0, normal);
    geom.setNormal(1, normal);
    geom.setNormal(2, normal);

    this.setGeometry(geom);

    if (app != null)
      super.setAppearance(app);
  }

  public JoLightedFace()
  {
    this(null);
  }
}

 Fichier: JoLightedFace.java

Création d'une face triangulaire dans le plan XY.
La couleur sera contrôlée par les caractéristiques matérielles de l'apparance.