Play a video on a business card

Share on Twitter Share on Facebook Share on LinkedIn

Play a video on a business card

Description

In this lesson we are detecting an image and playing a video on top of it.

The video seems to be cropped slightly to best fit the dimensions of the detected image.


Video


Code

using ARKit;
using SceneKit;
using SpriteKit;
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,
                Delegate = new SceneViewDelegate()
            };

            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 detectionImages = ARReferenceImage.GetReferenceImagesInGroup("AR Resources", null);

            this.sceneView.Session.Run(new ARWorldTrackingConfiguration
            {
                AutoFocusEnabled = true,
                PlaneDetection = ARPlaneDetection.Horizontal | ARPlaneDetection.Vertical,
                LightEstimationEnabled = true,
                WorldAlignment = ARWorldAlignment.GravityAndHeading,
                DetectionImages = detectionImages,
                MaximumNumberOfTrackedImages = 10

            }, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors);
        }

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

            this.sceneView.Session.Pause();
        }

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

    public class SceneViewDelegate : ARSCNViewDelegate
    {
        public override void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            if (anchor is ARImageAnchor imageAnchor)
            {
                var detectedImage = imageAnchor.ReferenceImage;

                // Add video node
                var videoNode = new SKVideoNode("Videos/leasing-intro.mp4");
                videoNode.YScale = -1;
                videoNode.Play();

                var videoScene = new SKScene();
                videoScene.Size = new CoreGraphics.CGSize(640, 360);
                videoScene.ScaleMode = SKSceneScaleMode.AspectFill;
                videoNode.Position = new CoreGraphics.CGPoint(videoScene.Size.Width / 2, videoScene.Size.Height / 2);
                videoScene.AddChild(videoNode);

                var width = detectedImage.PhysicalSize.Width;
                var length = detectedImage.PhysicalSize.Height;
                var planeNode = new PlaneNode(width, length, new SCNVector3(0, 0, 0), videoScene);

                // Euler angles?
                float angle = (float)(-Math.PI / 2);
                planeNode.EulerAngles = new SCNVector3(angle, 0, 0);

                node.AddChildNode(planeNode);
            }
        }

        public static SCNNode CreateModelNodeFromFile(string filePath, string rootNodeName)
        {
            var sceneFromFile = SCNScene.FromFile(filePath);

            var model = sceneFromFile.RootNode.FindChildNode(rootNodeName, true);

            model.Scale = new SCNVector3(0.01f, 0.2f, 0.01f);
            model.Position = new SCNVector3(0, 0.2f, 0);

            return model;
        }

        public override void DidRemoveNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            if (anchor is ARPlaneAnchor planeAnchor)
            {
            }
        }

        public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            if (anchor is ARPlaneAnchor planeAnchor)
            {
            }
        }
    }

    public class PlaneNode : SCNNode
    {
        public PlaneNode(nfloat width, nfloat length, SCNVector3 position, SKScene videoScene)
        {
            var rootNode = new SCNNode
            {
                Geometry = CreateGeometry(width, length, videoScene),
                Position = position
            };

            AddChildNode(rootNode);
        }

        private static SCNGeometry CreateGeometry(nfloat width, nfloat length, SKScene videoScene)
        {
            var material = new SCNMaterial();
            material.Diffuse.Contents = videoScene;
            material.DoubleSided = false;

            var geometry = SCNPlane.Create(width, length);
            geometry.Materials = new[] { material };

            return geometry;
        }
    }
}

Next Step : Vertical items from business card

After you have mastered this you should try Vertical items from business card