Classe Mappemonde3D:
import javax.media.j3d.*; import javax.vecmath.*; import java.awt.*; import java.awt.event.*; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.SimpleUniverse; import java.applet.Applet; import com.sun.j3d.utils.geometry.Sphere; import com.sun.j3d.utils.image.TextureLoader; /** * Test mappemonde 3D pour Java * * @author Philippe Laneres * @version 1.1, 20/06/2003 * @since Mappemonde3D1.1 * * exemple complet : la classe Mappemonde3D * anime en rotation une sphère * avec placage de texture (image de la terre) * et le texte "Java 3D" en orbite (géostationnaire). * Une source lumineuse venant du côté gauche du canvas * simule le soleil. */ public class Mappemonde3D extends Applet implements ActionListener { RotationInterpolator rotator; Button stopButton; Button startButton; /** createSceneGraph retourne une reference * à la branche de contenu du graphe */ public BranchGroup createSceneGraph() { // incline la terre pour correspondre à une vue en été // et l'éloigne de l'observateur de 12 unités BranchGroup contentRoot = new BranchGroup(); Transform3D sceneTrans = new Transform3D(); sceneTrans.rotX(Math.PI/8.0); sceneTrans.setTranslation(new Vector3d(0.0,0.0,-12.0)); TransformGroup contentTransGroup = new TransformGroup(sceneTrans); contentRoot.addChild(contentTransGroup); // ajoute une source de lumière ambiante et // une source directionelle à l'infini Color3f lgtColor1 = new Color3f(1.0f, 1.0f, 1.0f); Vector3f lgtDir = new Vector3f(1.0f, -1.0f, -1.0f); Color3f lgtColor2 = new Color3f(0.2f, 0.2f, 0.2f); BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); AmbientLight ambLgt = new AmbientLight(lgtColor2); ambLgt.setInfluencingBounds(bounds); DirectionalLight dirLgt = new DirectionalLight(lgtColor1, lgtDir); dirLgt.setInfluencingBounds(bounds); contentTransGroup.addChild(ambLgt); contentTransGroup.addChild(dirLgt); // crée la sphère représentant la terre et // lui applique une texture provenant d'une image jpeg Appearance mappemondeApp = new Appearance(); TextureLoader texture = new TextureLoader("mappemonde.jpg", this); mappemondeApp.setTexture(texture.getTexture()); Color3f black = new Color3f(0.0f, 0.0f, 0.0f); Color3f white = new Color3f(1.0f, 1.0f, 1.0f); mappemondeApp.setMaterial(new Material(white, black, white, black, 1.0f)); Sphere mappemonde = new Sphere(1.75f, Sphere.GENERATE_TEXTURE_COORDS | Sphere.GENERATE_NORMALS, mappemondeApp); TransformGroup mappemondeTransGroup = new TransformGroup(); mappemondeTransGroup.addChild(mappemonde); contentTransGroup.addChild(mappemondeTransGroup); // ajoute un interpolateur pour gérer la rotation de la terre et du texte Alpha rotationAlpha = new Alpha(-1, 8000); rotator = new RotationInterpolator(rotationAlpha, mappemondeTransGroup); BoundingSphere rotatorBounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); rotator.setSchedulingBounds(rotatorBounds); mappemondeTransGroup.addChild(rotator); mappemondeTransGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); // crée le texte "Java 3D", fixe par rapport à la terre Font3D f3d = new Font3D(new Font("TestFont", Font.PLAIN, 1), new FontExtrusion()); Text3D textGeom = new Text3D(f3d, new String("Java 3D")); Appearance textApp = new Appearance(); Color3f textColor = new Color3f(0.0f, 0.6f, 1.0f); textApp.setMaterial(new Material(white, black, textColor, white, 120.0f)); Shape3D text = new Shape3D(textGeom, textApp); Transform3D textTrans = new Transform3D(); textTrans.setTranslation(new Vector3d(1.5, 1.0, 0.0)); TransformGroup textTransGroup = new TransformGroup(textTrans); textTransGroup.addChild(text); mappemondeTransGroup.addChild(textTransGroup); // optimise le graphe de scène contentRoot.compile(); return contentRoot; } /* actionPerformed est une action a executer lorsqu'un bouton est pressé; active ou désactive l'interpolateur */ public void actionPerformed (ActionEvent event) { Object source = event.getSource(); if (source == stopButton) { rotator.setEnable(false); } else { rotator.setEnable(true); } } /** Constructeur de Mappemonde3D * Java 3D effectue son affichage dans un objet * de type Canvas3D, qui est une sous-classe * de la classe Canvas d'AWT. * Le constructeur de Canvas3D requiert un objet * GraphicsConfiguration qui décrit les caractéristiques * de l'environnement graphique qui peut s'obtenir * simplement en utilisant la méthode statique * getPreferedConfiguration de SimpleUniverse. * Cette configuration adéquate va permettre à Java 3D * de tirer parti des possibilités du matériel d'accélération * graphique telles que le double-buffer et offre aussi * les caractéristiques requises pour l'indépendance * de la plate-forme du système de fenêtrage. */ public Mappemonde3D() { // initialise le Canvas3D dans lequel ce programme // va effectuer l'affichage GraphicsConfiguration gConfig = SimpleUniverse.getPreferredConfiguration(); Canvas3D c = new Canvas3D(gConfig); // SimpleUniverse est un utilitaire de construction // de graphe de scène agréable car il s'occupe de // quasiment tous les aspects de la branche de point de vue, // laissant tout le loisir au programmeur de se concentrer // sur la branche de contenu géométrique. // La méthode setNominalViewTransform initialise // une transformation de visualisation canonique. // Dans le système de coordonnées du monde virtuel // cette transformation de visualisation place // l'observateur de la scène sur l'axe Z positif, // éloigné de l'origine de quelques unités regardant // vers l'origine. Les axes positifs X et Y sont // dirigés comme usuellement, c'est-à-dire vers la // droite et vers le haut parallèlement aux bords de l'écran. // Utilisation de SimpleUniverse pour créer un graphe // par défaut avec une branche de vue complète SimpleUniverse u = new SimpleUniverse(c); u.getViewingPlatform().setNominalViewingTransform(); // La méthode createSceneGraph retourne une référence // à un objet BranchGroup correspondant à la branche // de contenu géométrique. Cette branche est ajoutée // au graphe de scène par la méthode addBranchGraph. BranchGroup scene = createSceneGraph(); // Finalement, la branche de contenu géométrique de // Mappemonde est ajoutée au graphe de scène qu'a créé // SimpleUniverse. u.addBranchGraph(scene); // Regardons maintenant en détail la méthode createSceneGraph, // qui créée la branche de contenu géométrique. // La scène comporte un éclairage reproduisant // l'illumination du soleil sur la Terre. // construit la disposition des éléments // de cet applet et ajoute le Canvas3D this.setLayout(new BorderLayout()); this.add("Center", c); // ajoute les boutons de contrôle de l'activation de la rotation Panel panel = new Panel(new FlowLayout()); stopButton = new Button("stop rotation"); panel.add(stopButton); startButton = new Button("rotate"); panel.add(startButton); add("South",panel); stopButton.addActionListener(this); startButton.addActionListener(this); } /** Main est appelé lorsque Mappemonde3D * est exécuté comme une application. * MainFrame ajoute l'applet à une Frame. * Ceci permet d'utiliser ce programme * soit comme un applet soit comme une application */ public static void main(String[] args) { new MainFrame(new Mappemonde3D(), 500, 500); } }Documentation