✅ Scene Graph
: 3차원 공간 상의 장면 구성을 위한 데이터 구조. 그래프 또는 트리 구조의 노드 집합으로, 부모의 효과가 모든 자식 노드에 적용되어 그룹에서 수행된 작업이 자동으로 모든 구성원에게 전파된다. 효율적이고 간편
✅ Scene Graph 응용 -- Solar System 구현하기
- 회색 글자: 클래스
- 검정색 진한 글자 : 해당 클래스의 객체
- 밑에 작은 글자: 객체의 속성
🟡 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;
}