본문 바로가기
JAVA

Simple Test Code

by windrises 2007. 7. 17.
package test.simple;


import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.PositionInterpolator;
import javax.media.j3d.Texture;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

/*
 * 이 예제는 sun 유틸리티 클래스인 mainframe과 simpleuniverse를 이용하여
 * 간단한 java 3d 어플리케이션을 만든다.
 * 예제는 배경 이미지 위에서 움직이는 구를 표시하는데,
 * 장면의 시각적 효과를 증가시키기 위하여
 * 텍스쳐 이미지와 하나의 조명을 사용하고 있다.
 */
public class SimpleTest extends JFrame{
  /*
   * 구와 조명, 텍스쳐가 적용된 배경 도형
   * 그리고 x축을 따라서 구를 움직여줄 동작을 포함하는
   * 간단한 java3d환경을 만든다.
   */
  public SimpleTest(){
    //만들려고 하는 장면을 담게 될 SimpleUniverse클래스를 만든다.
    // simpleUniverse는 sun에서 제공하는 헬퍼 클래스(유틸리티)로,
    // java 3d 배포판에 포함되어 있다.
    SimpleUniverse u = new SimpleUniverse();
   
    //BranchGroup을 만든다. BranchGroup은 하위노드를 가질 수 있는
    //트리 데이터 구조 내의 노드이다.
    BranchGroup bgRoot = new BranchGroup();
   
    //Background 노드를 만들고, SimpleUniverse에 추가한다.
    u.addBranchGraph(createBackground());
   
    //x축을 따라 도형을 움직이는 동작을 만든다.
    //bgRoot 노드의 하위 노드로서 동작이 추가된다.
    //tg노드의 하위 노드로서 추가된 것은
    //동작(x축을 따라 움직이는 동작)에 의하여 영향을 받게 된다.
    TransformGroup tg = creatBehaviors(bgRoot);
   
    //tb의 하위 노드로서 Sphere 형태를 추가하면 x축에 따라 움직이게 된다.
    tg.addChild(createSceneGraph());
   
    //0,0,0좌표에서 구가 추가되고, 기본적으로
    //관찰자의 취이가 0,0,0으로 설정되기 때문에
    //관찰자의 위치를 약간 뒤로 움직여야 장면을 볼 수 있게 된다.
    u.getViewingPlatform().setNominalViewingTransform();
   
    //장면에 조명 효과를 넣기 위하여 로트 BranchGroup에 빛을 추가한다.
    addLights(bgRoot);
   
    //마지막으로, 루트 BranchGroup을 SimpleUniverse에 추가하여 모든 것을 연결한다.
    u.addBranchGraph(bgRoot);
  }
  /*
   * 장면에 들어갈 도형을 만든다.
   * 여기에서는 Sphere를 간단하게 만든다.
   * (이미 만들어져 있는 Java 3d 개체)  
   */
  public BranchGroup createSceneGraph(){
    // Sphere를 위한 상위 BranchGroup 노드를 만든다.
    BranchGroup bg = new BranchGroup();
   
    // Sphere를 위한 Appearance를 만든다.
    // Appearance 객체는 Sphere 형태를 위한
    // 다양한 렌더링 옵션을 제어한다.
    Appearance app = new Appearance();
   
    // Material을 Appearance에 할당한다.
    // 장면에서 Sphere가 빛에 반응하도록 만들기 위하여
    // 반드시 Material을 사용해야 한다.
    // 색상을 Material에 할당하고,
    // 표면에 얼마만큼 빛을 반사시킬 것인지를
    // 조절하는 설정을 할당한다.
    Color3f objColor = new Color3f(0.8f, 0.2f, 1.0f);
    Color3f back = new Color3f(0.0f,0.0f,0.0f);
    app.setMaterial(new Material(objColor,back,objColor,back,80.0f));
   
    //0.1의 반지름을 가진 Sphere를 만들고,
    // 묘사하려는 Appearance를 합친다.
    // GENERATE_NORMALS 옵션은 Sphere가 빛에 올바르게
    // 반응하는가를 확인하기 위하여 필요하다.
    Sphere sphere = new Sphere( 0.1f, Primitive.GENERATE_NORMALS, app);
   
    //구를 BranchGroup에 추가하여
    //장면에 연결시킨다.
    bg.addChild(sphere);
    return bg;
  }
  /*
   * 조명을 BranchGroup에 추가한다.
   */
  public void addLights(BranchGroup bg){
    //조명을 위한 색상을 만든다.
    Color3f color = new Color3f(1.0f,1.0f,0.0f);
   
    //조명빛이 반사되는 방향을
    //표현하는 벡터를 만든다.
    Vector3f direction = new Vector3f(-1.0f,-1.0f,-1.0f);
   
    //색상과 방향을 가진 조명빛을 만든다.
    DirectionalLight light = new DirectionalLight(color, direction);
   
    //조명의 영향을 받는 부피를 설정한다.
    //영향을 받는 범위 내의 개체들만이 빛을 받게 된다.
    light.setInfluencingBounds(getBoundingSphere());
   
    //조명빛을 BranchGroup에 추가한다.
    bg.addChild(light);
  }
  /*
   * 어플리케이션에서 배경막으로 사용할 배경 도형을 만든다.
   * 여기에서는 Sphere를 만드는데, 이것은 전체 장면을 포함하고
   * 장면의 그래픽적인 배경막으로써 사용하게 될 Sphere의 내부에
   * 텍스처 이미지를 적용하게 된다.
   */
  public BranchGroup createBackground(){
    //Background를 위한 상위 BranchGroup을 만든다.
    BranchGroup backgroundGroup = new BranchGroup();
   
    //새로운 Background노드를 만든다.
    Background back = new Background();
   
    //배경의 영향이 미치는 범위를 설정한다.
    back.setApplicationBounds( getBoundingSphere() );
   
    //Sphere 도형을 가지게 될 BranchGroup을 만든다.
    BranchGroup bgGeometry = new BranchGroup();
   
    //Sphere를 위한 외형을 만든다.
    Appearance app = new Appearance();
   
    //Java 3d 텍스처로더를 사용하여 텍스처 이미지를 읽어온다.
    Texture tex = new TextureLoader("back.jpg", this).getTexture();
   
    //텍스처를 외형에 적용한다.
    app.setTexture(tex);
   
    //반지름 1.0의 sphere도형을 만든다.
    //텍스쳐 이미지의 표현이 가능하도록 텍스처의 좌표를 만들고,
    //현재의 위치가 Sphere의 내부이기 때문에
    //내부 방향으로 수직 좌표를 만들어야 한다.
    //그렇지 않으면 Sphere가 보이지 않게 된다.
    Sphere sphere = new Sphere(1.0f,Primitive.GENERATE_TEXTURE_COORDS |
                    Primitive.GENERATE_NORMALS_INWARD,app);
   
    //모든것의 연결을 시작하고,
    //Sphere를 상위의 BranchGroup에 추가한다.
    bgGeometry.addChild(sphere);
   
    //BranchGroup을 Background에 할당한다.
    back.setGeometry(bgGeometry);
   
    //Background 노드를 상위의 BranchGroup에 추가한다.
    backgroundGroup.addChild(back);
   
    return backgroundGroup;
  }
 
  /*
   * 하위 노드를 X축에 따라 움직이는 동작을 만든다.
   * 동작이 bRANCHgROUP BG에 추가되고,
   * 반면 되돌려지는 tRANSFORMgROUP에 추가되는 노드는
   * 동작에 영향을 받게 될 것이다.
   */
  public TransformGroup creatBehaviors(BranchGroup bg){
    //TransformGroup을 만든다.
    //TransformGroup은 Group노드(이것은 하위노드를 가질 수 있다.)이며
    //Transform3D 멤버를 포함한다.
   
    //Transform3D멤버는 렌더링을 하는동안
    //모든 TransformGroup의 하위 노드에 적용할
    //4x4의 변환행렬을 포함한다. 4x4행렬은
    //하나의 패키지에서 크기 조절, 변환 그리고 회전을 묘사할 수 있다.
   
    //TRANSFORM_WRITE 기능을 이용하면
    //실행시 동작 코드에서 수정할 수 있다.
    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
   
    //움직이려는 방향을 표시하는 새로운 Transform3D를 만든다.
    Transform3D xAxis = new Transform3D();
   
    //Alpha 객체를 만든다.
    //Alpha 객체는 시간에 대한 함수를 나타낸다.
    //Alpha는 time 매개변수(천분의 일초단위)를 사용하여
    //0과 1사이 범위의 값을 출력한다.
    Alpha xAlpha = new Alpha(-1,Alpha.DECREASING_ENABLE | Alpha.INCREASING_ENABLE,
        1000,
        1000,
        5000,
        1000,
        1000,
        10000,
        2000,
        4000);
   
    //PositionInterpolator를 만든다.
    //PositionInterpolator는 Alpha의 출력에 기초한
    //TransformGroup의 Transform3D(objTrans)의 변환 요소를 수정하게 된다.
    //이러한 경우, 움직임의 범위는 Alpha=0에서 X축상의  -0.8부터
    //Alpha=1에서 X=0.8까지가 된다.
    PositionInterpolator posInt = new PositionInterpolator( xAlpha,objTrans,xAxis,-0.8f,0.8f);
   
    //PositionInterpolator의 영향을 받는 범위를 설정한다.
    posInt.setSchedulingBounds(getBoundingSphere());
   
    //PositionInterpolator를 상위의 TransformGroup과 연결한다.
    //노드를 렌더링하는 것처럼 동작은 장면그래프에 추가된다.
    objTrans.addChild(posInt);
   
    //TransformGroup을 상위의 BranchGroup에 추가한다.
    bg.addChild(objTrans);
   
    //동작이 첨부된 TransformGroup을 되돌려주므로
    //노드를 여기에 추가할 수 있다.(PositionInterpolator에 의하여
    //영향을 받게 될 것이다).
    return objTrans;
  }
 
  /*
   * 장면의 부피를 묘사하는 BroundingSphere를 돌려준다.
   */
  BoundingSphere getBoundingSphere(){
    return new BoundingSphere(new Point3d(0.0,0.0,0.0),200.0);
  }
 
  /*
   * 어플리케이션을 위한 주 입력 점
   */
  public static void main(String[] args){
    SimpleTest simpleTest = new SimpleTest();
  }
}

'JAVA' 카테고리의 다른 글

조이스틱 사용 소스  (0) 2007.08.01
JPEG에서 메타정보 추출  (0) 2007.07.19
JME(jmonkeyengine)  (0) 2007.07.16
LWJGL  (0) 2007.07.16
1. Getting started with JOGL  (0) 2007.07.16