cesium.js통해 운석을 떨군다.

개미는뚠뚠·2023년 11월 18일
0

cesium.js

목록 보기
2/2
post-thumbnail

🚀 개요

지난 시간에는 cesium을 처음 사용하여, 내가 원하는 좌표에 3D 모델로 화면을 띄우는 것을 구현했었다. 그 이후도 나는 꾸준히 cesium을 가지고 공부했다.

오늘은 공부했던 내용 중에서 한반도에 운석을 떨구는 내용을 정리하려고 한다.


🚀 과정

운석을 떨구기 전 고려해야하는 상황을 정해보았다. 오늘은 이 플로우에 맞춰서 글을 작성할 예정이다.

  1. 운석이 떨어질 지구 모델과 관찰 카메라 위치 및 각도
  2. 운석이 떨어지는 과정
  3. 3D 운석 이미지를 표현해줄 gltf 확장자 파일 적용

그렇다면 코드를 통해 한번 살펴보자

🚀🚀 1. 운석이 떨어질 지구 모델과 관찰 카메라 위치 및 각도

	// 0.header-ceisum 연결
    <head>
        <meta charset="utf-8">
        <!-- Include the CesiumJS JavaScript and CSS files -->
        <script src="https://cesium.com/downloads/cesiumjs/releases/1.111/Build/Cesium/Cesium.js"></script>
        <link href="https://cesium.com/downloads/cesiumjs/releases/1.111/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    </head>

	// 1.body-cesiumContainer 준비
    <body>
        <div id="cesiumContainer"></div>
    </body>

	// 2.scirpt를 통한 조작
    <script type="module">
		
      	// 3.토큰 입력
        Cesium.Ion.defaultAccessToken = '발급 받은 토큰 ';

      	// 4.viewer에 다음과 같이 지구 모델을 생성
        const viewer = new Cesium.Viewer('cesiumContainer', {
            terrain: Cesium.Terrain.fromWorldTerrain(),
        });

        // 5.지구 모델을 바라볼 카메라 설정(운석이 떨어지는 모습을 보기 위해 다음과 같이 설정)
        var position = Cesium.Cartesian3.fromDegrees(170.0, 40.0, 25000000); // 경도, 위도, 고도
        var heading = Cesium.Math.toRadians(0); // 방위각
        var pitch = Cesium.Math.toRadians(-90); // 경사각
        var roll = Cesium.Math.toRadians(0); // 롤각

      	// 6. 설정한 카메라 각도에 맞춰 지구 모델 생성
        viewer.scene.camera.setView({
            destination: position,
            orientation: {
                heading: heading,
                pitch: pitch,
                roll: roll
            }
        });
    </script>	

위의 코드에 따라 지구 모형이 생성되었다.

🚀🚀 2. 운석이 떨어지는 과정

이제 도형(운석 이미지 적용 전)을 동적으로 움직여서 지구에 떨어지는 모습을 표현할 것이다.

  • 참고로 아래 코드들은 script 태그 내부에 들어있는 내용이다.
// 운석의 초기 위치 설정 (지구 중심 좌표계)
var initialPosition = Cesium.Cartesian3.fromDegrees(127, 37.0, 10000000); // 초기 위치 (한반도 경도, 위도, 고도 10000000 상공)
var fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame(initialPosition); // 좌표계 변환	

// 운석 도달 위치 설정
var destinationLatitude = 37.0; // 도달 지점의 위도
var destinationLongitude = 127.0; // 도달 지점의 경도
var destinationAltitude = 10000; // 도달 지점의 고도
var destinationPosition = Cesium.Cartesian3.fromDegrees(destinationLongitude, destinationLatitude, destinationAltitude);

		// 도형 생성
        var shape = new Cesium.Entity({
            name: 'Custom Shape',
            position: new Cesium.CallbackProperty(function(time, result) {
                var seconds = Cesium.JulianDate.secondsDifference(time, Cesium.JulianDate.now());
                var newPosition = Cesium.Matrix4.multiplyByPoint(fixedFrameTransform, new Cesium.Cartesian3(0, 0, 1000000 * seconds), new Cesium.Cartesian3());

                var cartographic = Cesium.Cartographic.fromCartesian(newPosition);
                var altitude = cartographic.height;

                // 도달 여부 확인
                if (altitude <= 10000) {
                    // 지구에 도달한 경우, 이전 위치 반환하여 위치 업데이트 중지
                    return destinationPosition;
                }else {
                    // 도달하지 않은 경우, 새로운 위치 반환
                    return newPosition;
                }
            }, false),
            ellipsoid: {
                radii: new Cesium.Cartesian3(100000, 100000, 100000), // 도형의 크기 (x축 반지름: 1000000, y축 반지름: 1000000, z축 반지름: 1000000)
                material: Cesium.Color.RED.withAlpha(0.5) // 도형의 색상 (빨간색, 투명도: 0.5)
            }
        });

// 도형을 뷰어에 추가
viewer.entities.add(shape);

위의 코드처럼 운석의 초기 위치, 도달한 위치 등 설정을 마치고 Cesium.CallbackProperty 를 통해 동적으로 움직일 수 있게 구현하였다.

🚀🚀 3. 3D 운석 이미지를 표현해줄 gltf 확장자 파일 적용

마지막 중요한 운석을 표현해줄 차례이다. 바로 이전에 설명한 내용에서는 빨간 동그라미를 운석으로 대체하였으나, 실제 운석을 통해 리얼리티를 살리고 싶었다. 그러나 3D로 구현된 이 환경에서 2D 이미지를 대체할 것인가? 아니다.

나는 이 문제를 해결하기 위해 많은 구글링을 시도하였고, 그 결과 3D 이미지 대체로는 gltf 파일 확장자로 표현이 가능하다는 것을 알았다. 그리고 오픈 소스를 통해 실제 운석 이미지를 적용하였다.


// 도형 생성
var shape = new Cesium.Entity({
            name: 'Custom Shape',
            position: new Cesium.CallbackProperty(function(time, result) {
                var seconds = Cesium.JulianDate.secondsDifference(time, Cesium.JulianDate.now());
                var newPosition = Cesium.Matrix4.multiplyByPoint(fixedFrameTransform, new Cesium.Cartesian3(0, 0, 1000000 * seconds), new Cesium.Cartesian3());

                var cartographic = Cesium.Cartographic.fromCartesian(newPosition);
                var altitude = cartographic.height;

                // 도달 여부 확인
                if (altitude <= 10000) {
                    // 지구에 도달한 경우, 이전 위치 반환하여 위치 업데이트 중지
                    return destinationPosition;
                }else {
                    // 도달하지 않은 경우, 새로운 위치 반환
                    return newPosition;
                }
            }, false),
            model: {
                uri: '/images/rock-boulder-dry-3d-model/rock_boulder_dry_4k.gltf', // glTF 파일의 경로
                scale: 500000.0
            }
});

// 도형을 뷰어에 추가
viewer.entities.add(shape);

기존에 도형으로 대체 했던 부분(ellipsoid)운석 모델(model)로 변경해주었다.

ellipsoid: {
     		radii: new Cesium.Cartesian3(100000, 100000, 100000), // 도형의 크기 (x축 반지름: 1000000, y축 반지름: 1000000, z축 반지름: 1000000)
            material: Cesium.Color.RED.withAlpha(0.5) // 도형의 색상 (빨간색, 투명도: 0.5)
}
model: {
            uri: '/images/rock-boulder-dry-3d-model/rock_boulder_dry_4k.gltf', // glTF 파일의 경로
            scale: 500000.0
}


cesium 개인적으로 재밌어서 꾸준히 보고 있는 거 같다. 앞으로도 꾸준한 포스팅 이어가면서 자세한 사용법 및 기술들에 대해 서술하도록 하겠다🌍

0개의 댓글