Use physics in scene
Description
We will use physics in the scene. i.e gravity.
To do this we add a 2d horizontal plane to the scene and set PhysicsBody = SCNPhysicsBody.CreateKinematicBody()
.
Then we add 3d cubes at the location the user touches the screen and make it so they mimic gravity using PhysicsBody = SCNPhysicsBody.CreateDynamicBody()
.
We can see that the cubes are able to fall off the 2d plane.
Video
Code
using ARKit;
using Foundation;
using SceneKit;
using System;
using System.Linq;
using UIKit;
namespace XamarinArkitSample
{
public partial class ViewController : UIViewController
{
private readonly ARSCNView sceneView;
public ViewController(IntPtr handle) : base(handle)
{
this.sceneView = new ARSCNView();
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);
this.sceneView.Session.Run(new ARWorldTrackingConfiguration
{
LightEstimationEnabled = true,
WorldAlignment = ARWorldAlignment.Gravity
});
var light = SCNLight.Create();
light.LightType = SCNLightType.Directional;
light.Intensity = 2000f;
light.ShadowColor = UIColor.Black.ColorWithAlpha(0.5f);
light.ShadowRadius = 4;
light.ShadowSampleCount = 4;
light.CastsShadow = true;
var lightNode = new SCNNode();
lightNode.Position = new SCNVector3(0, 1f, 0);
lightNode.Light = light;
lightNode.EulerAngles = new SCNVector3((float)-Math.PI / 2, 0, 0);
lightNode.Opacity = 0;
this.sceneView.Scene.RootNode.AddChildNode(lightNode);
var planeNode = new PlaneNode(width:0.5f, length:0.5f, UIColor.DarkGray);
this.sceneView.Scene.RootNode.AddChildNode(planeNode);
}
public override void TouchesEnded(NSSet touches, UIEvent evt)
{
base.TouchesEnded(touches, evt);
if (!(touches.AnyObject is UITouch touch))
return;
var point = touch.LocationInView(this.sceneView);
var hits = this.sceneView.HitTest(point, new SCNHitTestOptions());
var hit = hits.FirstOrDefault();
if (hit == null)
return;
var node = hit.Node;
if (node == null)
return;
var cubeNode = new CubeNode(0.05f, UIColor.Green)
{
Position = new SCNVector3(
hit.WorldCoordinates.X,
hit.WorldCoordinates.Y + 0.1f,
hit.WorldCoordinates.Z
)
};
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 PlaneNode : SCNNode
{
public PlaneNode(float width, float length, UIColor color)
{
Geometry = CreateGeometry(width, length, color);
PhysicsBody = SCNPhysicsBody.CreateKinematicBody();
EulerAngles = new SCNVector3((float)(-Math.PI / 2), 0, 0);
CastsShadow = true;
}
private static SCNGeometry CreateGeometry(float width, float length, UIColor color)
{
var material = new SCNMaterial();
material.Diffuse.Contents = color;
material.DoubleSided = true;
var geometry = SCNPlane.Create(width, length);
geometry.Materials = new[] { material };
return geometry;
}
}
public class CubeNode : SCNNode
{
public CubeNode(float size, UIColor color)
{
Geometry = CreateGeometry(size, color);
Position = new SCNVector3(0, size / 2, 0);
PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
}
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 : 3d photo gallery surround
After you have mastered this you should try 3d photo gallery surround