Scene Manager 설명

SceneManager에 대한 설명입니다.

SceneManager에서 필수 구성 요소 얻기

아래는 SceneManager의 필수 구성 요소를 얻는 코드입니다.

필수 구성 요소

  • XRManager

  • XRCamera

  • XRStudioController

  • Trackable

MaxstSceneManager.cs
ARManager arManagr = FindObjectOfType<ARManager>();
if (arManagr == null)
{
    Debug.LogError("Can't find ARManager. You need to add ARManager prefab in scene.");
    return;
}
else
{
    arCamera = arManagr.gameObject;
}


VPSTrackable[] vPSTrackables = FindObjectsOfType<VPSTrackable>(true);
if (vPSTrackables != null)
{
    vPSTrackablesList.AddRange(vPSTrackables);
}
else
{
    Debug.LogError("You need to add VPSTrackables.");
}

foreach (GameObject eachObject in disableObjects)
{
    if(eachObject != null)
    {
        eachObject.SetActive(false);
    }
}

if (XRStudioController.Instance.ARMode)
{
    AndroidRuntimePermissions.Permission[] result = AndroidRuntimePermissions.RequestPermissions("android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION");
    if (result[0] == AndroidRuntimePermissions.Permission.Granted && result[1] == AndroidRuntimePermissions.Permission.Granted)
        Debug.Log("We have all the permissions!");
    else
        Debug.Log("Some permission(s) are not granted...");

    cameraBackgroundBehaviour = arManagr.GetCameraBackgroundBehaviour();
    if (cameraBackgroundBehaviour == null)
    {
        Debug.LogError("Can't find CameraBackgroundBehaviour.");
        return;
    }

    foreach (VPSTrackable vPSTrackable in vPSTrackablesList)
    {
        vPSTrackable.gameObject.SetActive(false);
    }
}
else
{
    this.enabled = false;

    if(startPov != null)
    {
        startPov.StartPlace();
    }
}

XRStudioController로 위치 인식을 위한 서버 이름을 얻습니다.

Occlusion (건물 메쉬에 의한 가려짐) 구현

렌더링하고자 하는 3D 오브젝트가 건물 메쉬에 의해 가려지는 효과를 Occlusion effect라고 합니다. Occlusion은 runtimeBuildingMaterial를 렌더링시 적용함으로써 구현됩니다.

MaxstSceneManager.cs
foreach (GameObject eachGameObject in occlusionObjects)
{
    Renderer[] cullingRenderer = eachGameObject.GetComponentsInChildren<Renderer>();
    foreach (Renderer eachRenderer in cullingRenderer)
    {
        eachRenderer.material.renderQueue = 1900;
        eachRenderer.material = runtimeBuildingMaterial;
    }
}

카메라 시작 / 시뮬레이션 시작

스마트폰과 스마트 글래스와 같은 모바일 기기 환경에서는 아래 코드를 통해 하드웨어 카메라가 시작됩니다. MAC OS X와 Windows 환경에서는 XRStudioController를 통해 선택한 시뮬레이션 데이터가 시작됩니다. 이를 통해 현장에 직접 나가지 않아도 앱 개발이 가능합니다.

MaxstSceneManager.cs
if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
{
    string simulatePath = vPSStudioController.vpsSimulatePath;
    if (Directory.Exists(simulatePath))
    {
        CameraDevice.GetInstance().Start(simulatePath);
        MaxstAR.SetScreenOrientation((int)ScreenOrientation.Portrait);
    }
}
else
{
    if (CameraDevice.GetInstance().IsFusionSupported(CameraDevice.FusionType.ARCamera))
    {
        CameraDevice.GetInstance().Start();
    }
    else
    {
        TrackerManager.GetInstance().RequestARCoreApk();
    }
}

XR Tracker 시작

XR Tracker를 시작해야 AR이 작동하게 됩니다. XRAPI.cs의 SetPlaceIdAndSpotId 함수를 통해서 POI와 Navigation을 얻기 위한 정보를 획득 합니다.

MaxstSceneManager.cs
TrackerManager.GetInstance().StartTracker();

XR 트래킹 결과 얻기

트래킹 결과는 UpdateFrame()과 GetARFrame()을 통해서 얻을 수 있습니다. GetARFrame()을 통해 얻은 ARFrame의 인스턴스에는 현재 트래킹 상태, 이미지, 6자유도 자세를 포함되어 있습니다.

ARFrame의 GetARLocationRecognitionState()를 통해서 현재 위치 인식 상태를 얻을 수 있습니다. 이 상태 정보에 맞춰 증강시킬 3D Object의 활성화 여부를 결정합니다.

MaxstSceneManager.cs
void Update()
{
    UpdateVisibleArrow(arCamera);

    if (!XRStudioController.Instance.ARMode)
    {
        return;
    }

    TrackerManager.GetInstance().UpdateFrame();

    ARFrame arFrame = TrackerManager.GetInstance().GetARFrame();

    TrackedImage trackedImage = arFrame.GetTrackedImage();

    if (trackedImage.IsTextureId())
    {
        IntPtr[] cameraTextureIds = trackedImage.GetTextureIds();
        cameraBackgroundBehaviour.UpdateCameraBackgroundImage(cameraTextureIds);
    }
    else
    {
        cameraBackgroundBehaviour.UpdateCameraBackgroundImage(trackedImage);
    }

    if (arFrame.GetARLocationRecognitionState() == ARLocationRecognitionState.ARLocationRecognitionStateNormal)
    {
        Matrix4x4 targetPose = arFrame.GetTransform();

        arCamera.transform.position = MatrixUtils.PositionFromMatrix(targetPose);
        arCamera.transform.rotation = MatrixUtils.QuaternionFromMatrix(targetPose);
        arCamera.transform.localScale = MatrixUtils.ScaleFromMatrix(targetPose);

        string localizerLocation = arFrame.GetARLocalizerLocation();

        if (currentLocalizerLocation != localizerLocation)
        {
            currentLocalizerLocation = localizerLocation;
            foreach (VPSTrackable eachTrackable in vPSTrackablesList)
            {
                bool isLocationInclude = false;
                foreach (string eachLocation in eachTrackable.localizerLocation)
                {
                    if (currentLocalizerLocation == eachLocation)
                    {
                        isLocationInclude = true;
                        currentLocalizerPlaceId = eachTrackable.placeId;
                        break;
                    }
                }
                eachTrackable.gameObject.SetActive(isLocationInclude);
            }
        }
    }
    else
    {
        foreach (VPSTrackable eachTrackable in vPSTrackablesList)
        {
            eachTrackable.gameObject.SetActive(false);
        }
        currentLocalizerLocation = "";
    }
}

Last updated