Show 3D model on a business card
Description
In this lesson we are getting a 3d model and placing it on a recognised image in the scene.
We can see in the video that as the orientation of the detected 2d image is changed, the orientation of the 3d model changes as it has been placed relative to the 2d image.
Video
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,
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 = 1
}, 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;
// Yes the root node was called "Null"!
node.AddChildNode(CreateModelNodeFromFile("art.scnassets/porsche-cayman.dae", "Null"));
}
}
public static float ConvertDegreesToRadians(float angle)
{
return (float)(Math.PI / 180) * angle;
}
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.019f, 0.019f, 0.019f);
model.Position = new SCNVector3(0, 0, 0);
float angle = (float)(-Math.PI / 2);
model.EulerAngles = new SCNVector3(angle, angle, 0);
// Set opacity to 0
model.Opacity = 0;
// Animate the opacity to 100% over 0.75 seconds
model.RunAction(SCNAction.FadeIn(0.75));
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)
{
}
}
}
}
Next Step : Gestures
After you have mastered this you should try Gestures