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(); } } |