People occlusion

Share on Twitter Share on Facebook Share on LinkedIn

People occlusion

Description

Until fairly recently, the depth of other real world items in a scene (for example people) wasn't taken into account when ARKit was placing nodes in the scene. Therefore the AR nodes would always appear in front of anything between them and the camera.

In more recent versions of ARKit, we can turn on a setting that will take the depth of other real world objects into account.

This feature is only supported by more recent phones and will crash the app if not supported by the phone. So if you intend to use this feature, you should programatically check whether the phone supports it (see code).

To enable this, on the ARWorldTrackingConfiguration, set the property FrameSemantics to ARFrameSemantics.PersonSegmentationWithDepth as can be seen in the code below.


Video

No video yet


Code

using ARKit;
using SceneKit;
using System;
using UIKit;

namespace XamarinArkitSample
{
    public partial class ViewController : UIViewController
    {
        private readonly ARSCNView sceneView;

        public ViewController(IntPtr handle) : base(handle)
        {
            this.sceneView = new ARSCNView
            {
                AutoenablesDefaultLighting = true,
                DebugOptions = ARSCNDebugOptions.ShowWorldOrigin
            };

            this.View.AddSubview(this.sceneView);
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            this.sceneView.Frame = this.View.Frame;
        }

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);

            var config = new ARWorldTrackingConfiguration();
            config.AutoFocusEnabled = true;
            config.PlaneDetection = ARPlaneDetection.Horizontal;
            config.LightEstimationEnabled = true;
            config.WorldAlignment = ARWorldAlignment.GravityAndHeading;

            if (ARWorldTrackingConfiguration.SupportsFrameSemantics(ARFrameSemantics.PersonSegmentationWithDepth))
            {
                config.FrameSemantics = ARFrameSemantics.PersonSegmentationWithDepth;
            }

            this.sceneView.Session.Run(config, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors);

            var size = 0.25f;
            var cubeNode = new CubeNode(size, UIColor.Green)
            {
                Position = new SCNVector3(0.8f, 0, 0)
            };

            this.sceneView.Scene.RootNode.AddChildNode(cubeNode);
        }

        public override void ViewDidDisappear(bool animated)
        {
            base.ViewDidDisappear(animated);

            this.sceneView.Session.Pause();
        }

        public override void DidReceiveMemoryWarning()
        {
            base.DidReceiveMemoryWarning();
        }
    }

    public class CubeNode : SCNNode
    {
        public CubeNode(float size, UIColor color)
        {
            var rootNode = new SCNNode
            {
                Geometry = CreateGeometry(size, color)
            };

            AddChildNode(rootNode);
        }

        private static SCNGeometry CreateGeometry(float size, UIColor color)
        {
            var material = new SCNMaterial();
            material.Diffuse.Contents = color;

            var geometry = SCNBox.Create(size, size, size, 0);
            geometry.Materials = new[] { material };

            return geometry;
        }
    }
}

Next Step : Place nodes at regular intervals

After you have mastered this you should try Place nodes at regular intervals