Java 3D (Exercício 4)
Professora: Isabel Harb Manssour
 

O objetivo deste exercício é testar as diferentes fontes de luz existentes na API Java 3D.

Para testar algumas alternativas de iluminação, crie uma nova classe com o nome HelloUniverseSeveralHuts e substitua o código que o BlueJ colocou pelo código apresentado abaixo.

/*
 *  @(#)HelloUniverse.java 1.55 02/10/21 13:43:36
 *
 * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 */

///////////////////////////////////////////////////////////////////////////
// Isabel Harb Manssour
// Junho de 2003
// SeveralHuts.java ilustra como criar duas ou mais huts
// (cabanas) em um universo.
// Este código está baseado no demo HelloUniverse.java

import javax.swing.*;
import java.awt.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class SeveralHuts extends JFrame 
{
    ///////////////////////////////////////////////////////////////////////
    // Atributo da classe SeveralHuts
    //
    private SimpleUniverse universe = null;
    

    ///////////////////////////////////////////////////////////////////////
    // Construtor da classe SeveralHuts
    //
    public SeveralHuts() {
        Container container = getContentPane();
        container.setLayout(new BorderLayout());
        GraphicsConfiguration config =
           SimpleUniverse.getPreferredConfiguration();

        Canvas3D canvas = new Canvas3D(config);
        container.add("Center", canvas);

        // Cria dois grafos e anexa-os no universo virtual
        BranchGroup cena1 = criaGrafoDeCena(0.2,0.5,0.0,0.0,Math.toRadians(30),0.0,0.0);
        BranchGroup cena2 = criaGrafoDeCena(0.4,-0.5,0.0,0.0,Math.toRadians(-20),0.0,0.0);
        BranchGroup cena3 = criaGrafoDeCena(0.6,0.0,0.4,0.0,0.0,0.0,Math.toRadians(45));
        BranchGroup cena4 = criaGrafoDeCena(0.1,0.0,-0.4,-0.5,Math.toRadians(-20),0.0,0.0);
       
        universe = new SimpleUniverse(canvas);

        // O código abaixo faz com que a ViewPlatform seja movida
        // um pouco para trás, para que os objetos possam ser
        // visualizados.
        universe.getViewingPlatform().setNominalViewingTransform();

        universe.addBranchGraph(cena1);
        universe.addBranchGraph(cena2);
        universe.addBranchGraph(cena3);
        universe.addBranchGraph(cena4);
        
        setSize(350,350);
        setVisible(true);
    }
    
    
    ///////////////////////////////////////////////////////////////////////
    // Método responsável pela criação do grafo de cena (ou sub-grafo)
    //    
    public BranchGroup criaGrafoDeCena(double e, double tx, double ty, 
					double tz, double rx, double ry, double rz) {
        
        // Cria o nó raiz 
        BranchGroup objRaiz = new BranchGroup();

        // Cria o nodo TransformGroup e permite que ele possa
        // ser alterado em tempo de execução (TRANSFORM_WRITE).
        // Depois, adiciona-o na raiz do grafo de cena.
        TransformGroup objTrans = new TransformGroup();
        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRaiz.addChild(objTrans);
    
        // Cria o nodo TransformGroup para o cone e permite que ele 
        // possa ser alterado em tempo de execução (TRANSFORM_WRITE).
        // Depois, adiciona-o no objeto objTrans.
        TransformGroup coneTrans = new TransformGroup();
        coneTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objTrans.addChild(coneTrans);      
    
        // Cria o nodo TransformGroup para o cilindro e permite que ele 
        // possa ser alterado em tempo de execução (TRANSFORM_WRITE).
        // Depois, adiciona-o no objeto objTrans.
        TransformGroup cilindroTrans = new TransformGroup();
        cilindroTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objTrans.addChild(cilindroTrans);        
    
        // Cria um "bounds" para o background 
        BoundingSphere bounds =
           new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

        // Especifica um background azul e adiciona-o no grafo
        Color3f bgColor = new Color3f(0.1f, 0.1f, 0.7f);
        Background bg = new Background(bgColor);
        bg.setApplicationBounds(bounds);
        objRaiz.addChild(bg);

        // Especifica as luzes do "ambiente"
        
        // Luz Ambiente
        Color3f corAmb = new Color3f(0.2f, 0.2f, 0.2f);
        AmbientLight luzAmb = new AmbientLight(corAmb);
        luzAmb.setInfluencingBounds(bounds);
        objRaiz.addChild(luzAmb);
                    
        Appearance app = new Appearance();      
        //Color3f ambientColor, Color3f emissiveColor, Color3f diffuseColor, 
        //				Color3f specularColor, float shininess
        Material material = new Material(new Color3f(0.8f,0.8f,0.1f), 
						new Color3f(0.0f,0.0f,0.0f), 
						new Color3f(0.8f,0.8f,0.1f), 
						new Color3f(1.0f,1.0f,1.0f), 100.0f); 
        app.setMaterial(material);
        
        // Cria um novo objeto que irá aplicar as transformações
        // geométricas sobre a "hut" (cone+cilindro) e o adicina 
        // no grafo.
        Transform3D trans = new Transform3D();
        Transform3D t1 = new Transform3D();
        Transform3D t2 = new Transform3D();
        // Aplica rotação
        t1.rotX(rx);
        t2.rotY(ry);
        trans.rotZ(rz);
        trans.mul(t1);
        trans.mul(t2);
        // Aplica escala
        trans.setScale(e);
        // Aplica translação
        trans.setTranslation(new Vector3d(tx,ty,tz));
        objTrans.setTransform(trans);        
    
        // Cria um novo objeto que irá aplicar as transformações
        // geométricas sobre o cone e o adicina no grafo.
        Transform3D coneT = new Transform3D();
        coneT.setTranslation(new Vector3d(0.0,0.7,0.0));
        coneTrans.setTransform(coneT);

        Cone cone = new Cone(0.5f, 0.6f);
        cone.setAppearance(app); 
        coneTrans.addChild(cone);

        // Cria um novo objeto que irá aplicar as transformações
        // geométricas sobre o cilindro e o adicina no grafo.
        Transform3D cilindroT = new Transform3D();
        cilindroTrans.setTransform(cilindroT);
        
        Cylinder cilindro = new Cylinder(0.3f, 0.8f, 1, 20, 10, app);
        cilindroTrans.addChild(cilindro);
        
        // Para o Java 3D realizar otimizações no grafo de cena
        objRaiz.compile();

        return objRaiz;
    }


    ///////////////////////////////////////////////////////////////////////
    // Método principal que permite executar a aplicação
    //
    public static void main(String[] args) 
    {
        SeveralHuts h = new SeveralHuts();
    }

}

Ao executar esta aplicação, observa-se que os objetos não parecem 3D e a cena está escura. Isto ocorre porque apenas a luz ambiente está habilitada.

Para verificar a diferença de utilização das diferentes fontes de luz, inclua no programa, logo abaixo da criação da luz ambiente, os seguintes trechos de código, UM DE CADA VEZ!!! A cada alteração, compile e execute o programa para verificar o resultado! Aproveite também para trocar as cores e posições das fontes de luz para entender o seu funcionamento.

    // Opção 1
    // Luz Direcional
    Color3f corLuz = new Color3f(0.9f, 0.9f, 0.9f);        
    Vector3f direcaoLuz  = new Vector3f(-1.0f, -1.0f, -1.0f);
    DirectionalLight luzDir = new DirectionalLight(corLuz, direcaoLuz);
    luzDir.setInfluencingBounds(bounds);
    objRaiz.addChild(luzDir);

    // Opção 2
    // Luz Pontual (Color3f c, Point3f position, Point3f attenuation)
    Color3f corLuz = new Color3f(0.9f, 0.9f, 0.9f);        
    Point3f posicaoLuz   = new Point3f(0.0f, 2.0f, 0.0f);
    Point3f atenuacaoLuz = new Point3f(0.2f, 0.2f, 0.2f);        
    PointLight luzPont = new PointLight(corLuz, posicaoLuz, atenuacaoLuz);
    luzPont.setInfluencingBounds(bounds);
    objRaiz.addChild(luzPont);

    // Opção 3
    // Luz Spot (Color3f color, Point3f position, Point3f attenuation, 
    //             Vector3f direction, float spreadAngle, float concentration)
    Color3f corLuz       = new Color3f(1.0f, 1.0f, 1.0f);        
    Point3f posicaoLuz   = new Point3f(0.0f, 2.0f, 0.0f);
    Point3f atenuacaoLuz = new Point3f(0.1f, 0.1f, 0.1f);        
    Vector3f direcaoLuz  = new Vector3f(0.0f, -1.0f, 0.0f);
    SpotLight luzSpot = new SpotLight(corLuz, posicaoLuz, atenuacaoLuz, 
    					direcaoLuz, (float)Math.toRadians(12), 60.0f);
    luzSpot.setInfluencingBounds(bounds);
    objRaiz.addChild(luzSpot);             

 ../Imagens/emban15.png(1469 bytes)

../Imagens/E-MAIL.JPG (3237 bytes) Comentários, dúvidas, sugestões, envie um mail para [email protected]

../Imagens/emban15.png(1469 bytes)

[Homepage Java 3D]  [Homepage Isabel H. Manssour]

Última alteração em 11 de outubro de 2003.