SpaceSDK
1. 소개
Space SDK는 맥스트에서 제공하는 공간맵을 XR 어플리케이션에 쉽게 적용할 수 있도록 돕는 SDK입니다.
이 SDK는 XR SDK와 호환되어 XR 애플리케이션 개발에 사용됩니다.
1. 특징
- 맥스트의 고유한 공간맵 기반입니다.
- 빠르게 XR 애플리케이션 개발을 할 수 있도록 지원합니다.
- VPS AR을 활용하기 위해서는 XRScene과 XRSDKAuthConfig 파일을 사용해야 하며, 360 VR 콘텐츠를 활용하기 위해서는 StarterScene 과 SpaceSDKSampleAuthConfig 파일을 사용해야 합니다.
2. 시작하기
3. 플로우
Space SDK의 주요 구성 요소는 다음과 같습니다:
- Mesh: 공간맵의 3D 표현을 담당.
- Pov: 위치 및 위치에 해당하는 360 이미지 정보 제공.
- 360 Image: 현재 위치에 해당하는 전방위 이미지.
스페이스 SDK의 주요 프로세스는 제공된 그림을 참조하세요.
2. Configuration
- Space SDK의 기본 Scene 구성은 아래 그림과 같습니다.
1. Bundle Downloader
- 공간맵 콘텐츠를 Addressable을 사용하여 다운로드하는 기능을 수행하는 Prefab입니다.
Setup - 로직 구성을 위해 필요한 BundleDownloadViewModel와 BundleDownloadController를 초기화 합니다.
//BundleDownloadViewModel을 의존성 주입을 합니다.
[DI(DIScope.component, DIComponent.space)] private BundleDownloadViewModel BundleDownloadViewModel { get; }
//Bundle Downloader를 SerializeField로 Setting
[SerializeField] private BundleDownloadController downloadController;Addressable을 다운받는 로직을 위한 Callback들을 정의합니다.
private void OnEnable()
{
BundleDownloadViewModel.NotifyInitialized.AddObserver(this, OnNotifyInitialized);
BundleDownloadViewModel.NotifyCatalogUpdated.AddObserver(this, OnNotifyCatalogUpdated);
BundleDownloadViewModel.NotifyDownloadProgress.AddObserver(this, OnNotifyDownloadProgress);
BundleDownloadViewModel.NotifySizeDownloaded.AddObserver(this, OnNotifySizeDownloaded);
BundleDownloadViewModel.NotifyDownloadFinished.AddObserver(this, OnNotifyDownloadFinished);
}
private void OnDisable()
{
BundleDownloadViewModel.NotifyInitialized.RemoveAllObserver(this);
BundleDownloadViewModel.NotifyCatalogUpdated.RemoveAllObserver(this);
BundleDownloadViewModel.NotifyDownloadProgress.RemoveAllObserver(this);
BundleDownloadViewModel.NotifySizeDownloaded.RemoveAllObserver(this);
BundleDownloadViewModel.NotifyDownloadFinished.RemoveAllObserver(this);
}각 메소드에 아래와 같이 코드를 입력합니다.
private void OnNotifyInitialized(Space space, Spot spot)
{
downloadController.GoNextStatus();
}
private void OnNotifyCatalogUpdated(Space space, Spot spot)
{
downloadController.GoNextStatus();
}
private void OnNotifySizeDownloaded(Space space, Spot spot, long size)
{
if (size > 0)
{
downloadController.GoNextStatus();
return;
}
//contents download not needed
}
private void OnNotifyDownloadProgress(Space space, Spot spot, DownloadProgressStatus status)
{
var cur = FileController.GetSizeFormatString(status.downloadedBytes, FileController.SizeUnits.MB);
var total = FileController.GetSizeFormatString(status.totalBytes, FileController.SizeUnits.MB);
}
private void OnNotifyDownloadFinished(Space space, Spot spot, bool success)
{
downloadController.GoNextStatus();
ProcessNextSceneAsync(space, spot).Forget();
}아래의 코드처럼 맵 리스트를 조회하여 선택후 맵을 다운로드하여 이용할수 있습니다.
var dsv = DynamicSceneView.Instance(gameObject);
var space = await SceneViewModel.GetSpaceAsync(dsv, status.spaceId, false);
var spot = await SceneViewModel.GetSpotAsync(dsv, space, null, true);
downloadController.StartFetchProcessAsync(space, spot);
2. SmoothXRCamera
- 사용자의 현재 위치에 따라 360 이미지를 로드하고 렌더링하는 역할을 담당합니다.
구성요소:
Sphere: 360° 이미지가 설정되는 Prefab
- Sphere는 texturemanager를 통해 ibrCullFront material에 360° 이미지를 설정합니다. 그리고 xrCamera는 Sphere의 영역을 따라 촬영합니다.
- IBR CullFront Material은 pov에 해당하는 360° 이미지를 포함하고 있습니다.
- Sphere는 texturemanager를 통해 ibrCullFront material에 360° 이미지를 설정합니다. 그리고 xrCamera는 Sphere의 영역을 따라 촬영합니다.
Cursor: 마우스 레이가 충돌하는 지점을 나타내는 GameObject 입니다.
- Cursor Material을 변경하여 개발자가 원하는 이미지를 사용할 수 있습니다.
- 또한, CameraManager의 Inspector에서 'Cursor Layer Mask' 설정을 통해 커서의 ray hit 레이어를 조절할 수 있습니다.
- Cursor Material을 변경하여 개발자가 원하는 이미지를 사용할 수 있습니다.
CameraCanvas: 사용자로부터 받는 키보드, 마우스 입력 등을 받는 Object입니다.
키보드 입력, 마우스 클릭/드래그 등의 이벤트가 필요한 경우 CameraCanvas를 수정하여 사용할 수 있습니다.
private IEnumerator InputKeyEvent()
{
yield return new WaitWhile(() =>
{
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D)
|| Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.S))
{
cameraManager.HandleKeyboardNavigation(this);
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
cameraManager.UpdateInputKeyRotate(false);
}
else if (Input.GetKey(KeyCode.RightArrow))
{
cameraManager.UpdateInputKeyRotate();
}
else if (Input.GetKey(KeyCode.UpArrow))
{
cameraManager.UpdateInputKeyUpDown();
}
else if (Input.GetKey(KeyCode.DownArrow))
{
cameraManager.UpdateInputKeyUpDown(false);
}
else
{
}
return true;
});
}
void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
{
switch (eventData.button)
{
case PointerEventData.InputButton.Left:
if (isDrag == false)
{
cameraManager.HandleMouseNavigation(this);
}
break;
case PointerEventData.InputButton.Right:
break;
default:
break;
}
}
void IBeginDragHandler.OnBeginDrag(PointerEventData eventData)
{
switch (eventData.button)
{
case PointerEventData.InputButton.Left:
break;
default:
break;
}
}
void IDragHandler.OnDrag(PointerEventData eventData)
{
switch (eventData.button)
{
case PointerEventData.InputButton.Left:
cameraManager.UpdateInputRotate();
isDrag = true;
break;
default:
break;
}
}
3. XRMap
다운로드된 공간맵 콘텐츠들의 구성요소를 포함하고 있으며, 콘텐츠 로딩에 관한 로직을 담당하는 Prefab입니다. 콘텐츠 관련 옵션을 설정할 수 있습니다.
- TrackbleRoot
- 다운로드된 mesh의 root object입니다.
- 다운로드된 mesh의 root object입니다.
- WorldContent
- 콘텐츠의 root object 입니다.
- 콘텐츠의 root object 입니다.
MinimapContent
Minimap의 표시되는 콘텐츠들의 root object입니다.
Options
- Remove(Add) to NavigationLocationObserver : 콘텐츠의 load 로직을 담당하는 NavigationLocationObserver 컴포넌트를 제거하거나 추가 할 수 있습니다. 제거할 경우 모든 콘텐츠들은 로드가 되지 않습니다.
- Disable(Enable) Poi Loading : POI 콘텐츠를 로드할지 혹은 로드하지 않을지 설정하는 옵션입니다.
- Disable(Enable) Minimap Poi Loading : Minimap에 POI 콘텐츠들을 로드하거나 로드되지 않도록 설정하는 옵션입니다.
4. Minimap
- 맥스트 공간맵에 포함된 미니맵 리소스는 아래와 같이 이미지 형태입니다.
(북촌 공간맵 기준 리소스 위치 : TrackableRoot/map_3d_bukchon_outdoor/ Sphere)
개발자는 필요에 따라 미니맵 이미지나 아이콘을 커스텀 할 수 있습니다.
Minimap 이미지를 Mesh에 맞게 위치를 설정합니다. (기존 minimap 리소스 위에 설정합니다.)
Minimap 이미지의 layer를 minimap으로 변경합니다.
Minimap Icon
기본적으로 제공된 Minimap Icon은 위 그림과 같습니다.
Custom이 필요한 경우 Minimap Icon의 Sprite Renderer 이미지를 변경하시면 됩니다.