본문 바로가기
3D

[Three.js] Scene Graph

by 횰임 2022. 5. 6.

✅ Scene Graph

: 3차원 공간 상의 장면 구성을 위한 데이터 구조. 그래프 또는 트리 구조의 노드 집합으로, 부모의 효과가 모든 자식 노드에 적용되어 그룹에서 수행된 작업이 자동으로 모든 구성원에게 전파된다. 효율적이고 간편

 

 

 

✅ Scene Graph 응용 -- Solar System 구현하기

solarSystem의 scene graph (출처: youtube-GIS DEVELOPER)

- 회색 글자: 클래스

- 검정색 진한 글자 : 해당 클래스의 객체

- 밑에 작은 글자: 객체의 속성

 

🟡 Object3D 클래스의 파생 클래스

- Mesh, Line, Points 가 있다. (즉, Object3D는 geometry 클래스들의 상위 클래스)

- 각 객체는 3차원 공간 상에 놓이게 되며, position, rotation, scale이라는 속성값을 갖는다. 

position은 (x,y,z)좌표, rotation은 x,y,z축에 대한 회전값, scale은 x,y,z 축에 대한 크기의 배수값이다.

 

🟡 코드

 

<setupModel>

  _setupModel () {
        const solarSystem = new THREE.Object3D(); //solarSystem 객체 생ㅓ
        this._scene.add(solarSystem);   //씬에 추가

        //구 모양의 geometry생성
        const radius = 1;
        const widthSegments = 12;
        const heightSegments = 12;
        const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);

        //sun 재질
        const sunMaterial = new THREE.MeshPhongMaterial({
            emissive: 0xffff00, flatShading: true});

        //sunMesh 생성
        const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);
        sunMesh.scale.set(3, 3, 3); //sunMesh의 scale 속성값
        solarSystem.add(sunMesh);   //object3D객체에 썬 추가

        //earthOrbit 객체 생성 및 자식으로 추가
        const earthOrbit = new THREE.Object3D();
        solarSystem.add(earthOrbit);

        //earthMesh 객체 생성
        //재질
        const earthMaterial = new THREE.MeshPhongMaterial({
            color: 0x2233ff, emissive: 0x112244, flatShading: true
        });
        //Mesh
        const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
        earthOrbit.position.x = 10; //태양기준 x축으로 10만큼 떨어진 위치에 지구 배치
        earthOrbit.add(earthMesh);  //earthMesh를 자식으로 추가

        //moonOrbit 객체 생성
        const moonOrbit = new THREE.Object3D();
        earthOrbit.add(moonOrbit);  //earth 자식으로 추가
        moonOrbit.position.x = 2;   //earthOrbit기준으로 x축으로 2만큼 떨어진 거리에 달 배치 (==태양과의 거리는 12가 됨)
        
        //moonMesh 객체 생성
        //재질
        const moonMaterial = new THREE.MeshPhongMaterial({
            color: 0x888888, emissive: 0x222222, flatShading: true
        });
        //Mesh
        const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial);
        moonMesh.scale.set(0.5, 0.5, 0.5);
        moonOrbit.add(moonMesh);    //moonOrbit의 자식으로 추가
        
        this._solarSystem = solarSystem;    //solarSystem을 다른 메서드에서 접근할 수 있도록 필드화
        this._earthOrbit = earthOrbit;
        this._moonOrbit = moonOrbit;
    }

 

<회전 구현>

update(time) {
        time *= 0.001;   //ms -> s 단위로 변경

        //태양의 자전과 태양 중심으로의 공전
        this._solarSystem.rotation.y = time / 2;  //y 축에 대한 회전 값에 time /2을 지정 -> 시간은 계속 변하므로 y축에 대해 연속적으로 회전함
        
        //지구의 자전
        this._earthOrbit.rotation.y = time *2;  //y축 기준 회전
        //달의 자전
        this._moonOrbit.rotation.y = time * 5;
    }