private void OnFrameUpdate(OutputFrame outputFrame, InputFrame inputFrame, Matrix4x4 displayCompensation) { // world root if (Assembly.RequireWorldCenter && !WorldRootController) { Debug.Log("WorldRoot not found, create from " + typeof(ARSession)); var gameObject = new GameObject("WorldRoot"); WorldRootController = gameObject.AddComponent <WorldRootController>(); if (WorldRootChanged != null) { WorldRootChanged(WorldRootController); } previousWorldRootController = WorldRootController; } if (!Assembly.RequireWorldCenter && CenterMode == ARCenterMode.WorldRoot) { Debug.LogWarning("ARCenterMode.WorldRoot not available for target only tracking"); CenterMode = ARCenterMode.FirstTarget; } // horizontal flip var hflip = HorizontalFlipNormal; using (var cameraParameters = inputFrame.cameraParameters()) { if (cameraParameters.cameraDeviceType() == CameraDeviceType.Front) { hflip = HorizontalFlipFront; } } var worldHFlip = false; var targetHFlip = false; switch (hflip) { case ARHorizontalFlipMode.World: worldHFlip = true; targetHFlip = false; break; case ARHorizontalFlipMode.Target: worldHFlip = false; targetHFlip = true; break; default: break; } foreach (var renderCamera in Assembly.RenderCameras) { renderCamera.SetProjectHFlip(worldHFlip); renderCamera.SetRenderImageHFilp(worldHFlip || targetHFlip); } foreach (var filter in Assembly.FrameFilters) { filter.SetHFlip(targetHFlip); } // dispatch results var results = outputFrame.results(); var motionTrackingStatus = Optional <MotionTrackingStatus> .CreateNone(); if (inputFrame.hasSpatialInformation()) { motionTrackingStatus = inputFrame.trackingStatus(); } var resultControllers = DispatchResults(results, motionTrackingStatus); // get camera pose if available var cameraPose = Optional <Matrix44F> .Empty; if (Assembly.RequireWorldCenter) { if (motionTrackingStatus.OnSome) { if (motionTrackingStatus.Value != MotionTrackingStatus.NotTracking) { cameraPose = inputFrame.cameraTransform(); } } else { foreach (var result in resultControllers) { if (result.Key.OnNone) { cameraPose = result.Value; break; } } } } // get center target pose if available var centerTargetPose = Optional <Matrix44F> .Empty; if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget) { foreach (var result in resultControllers) { if (!CenterTarget) { break; } if (result.Key.OnNone) { continue; } if (result.Key == CenterTarget) { centerTargetPose = result.Value; break; } } if (CenterMode == ARCenterMode.FirstTarget && centerTargetPose.OnNone) { foreach (var result in resultControllers) { if (result.Key.OnNone) { continue; } CenterTarget = result.Key.Value; centerTargetPose = result.Value; break; } } } else { CenterTarget = null; } // set camera transform first if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget) { if (CenterTarget && centerTargetPose.OnSome) { TransformUtil.SetTargetPoseOnCamera(Assembly.CameraRoot, CenterTarget, centerTargetPose.Value, displayCompensation, targetHFlip); } } else if (CenterMode == ARCenterMode.WorldRoot) { if (WorldRootController && cameraPose.OnSome) { TransformUtil.SetCameraPoseOnCamera(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip); } } // set target and world root transform if (CenterMode == ARCenterMode.Camera) { foreach (var result in resultControllers) { if (result.Key.OnSome) { TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip); } } if (WorldRootController && cameraPose.OnSome) { TransformUtil.SetCameraPoseOnWorldRoot(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip); } } else if (CenterMode == ARCenterMode.WorldRoot) { foreach (var result in resultControllers) { if (result.Key.OnSome) { TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip); } } } else if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget) { foreach (var result in resultControllers) { if (result.Key.OnSome && result.Key.Value != CenterTarget) { TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip); } } if (WorldRootController && cameraPose.OnSome) { TransformUtil.SetCameraPoseOnWorldRoot(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip); } } else if (CenterMode == ARCenterMode.ExternalControl) { foreach (var result in resultControllers) { if (result.Key.OnSome) { TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip); } } } // dispose results foreach (var result in results) { if (result.OnSome) { result.Value.Dispose(); } } }