I\'m trying to understand and use ARKit. But there is one thing that I cannot fully understand.
Apple said about ARAnchor:
A real-world posit
Updated: July 19, 2020.
ARAnchor
is an invisible null-object that can hold a 3D model at anchor's position in World Space. Think of ARAnchor
just like it's a transform node
with local axis (you can translate, rotate and scale it) for your model. Every 3D model has a pivot point, right? So this pivot point must meet an ARAnchor
.
If you do not use anchors in ARKit
/RealityKit
app, your 3D models may be carried away from where they were placed and this will have influence with user experience. Thus, anchors are crucial elements of your AR scene.
According to ARKit documentation 2017:
ARAnchor
is a real-world position and orientation that can be used for placing objects in AR Scene. Adding an anchor to the session helps ARKit to optimize world-tracking accuracy in the area around that anchor, so that virtual objects appear to stay in place relative to the real world. If a virtual object moves, remove the corresponding anchor from the old position and add one at the new position.
ARAnchor
is a parent class for all other types of anchors existing in ARKit framework, hence all these subclasses inherit from ARAnchor
class but cannot use it directly in your code. I must also say that ARAnchor
and Feature Points
have nothing in common. Feature Points
are rather for debugging.
ARAnchor
doesn't automatically track a real world target. If you need automation, you have to use rendered(...)
or session(...)
instance methods that you can call if you conformed to protocols ARSCNViewDelegate
or ARSessionDelegate
respectively.
Here's an image with visual representation of plane anchor. But keep in mind: by default, you can neither see a detected plane nor its corresponding ARPlaneAnchor
. So, if you wanna see any anchor in your scene, you have to "visualize" it using three thin SCNCylinder
primitives.
In ARKit you can automatically add ARAnchors
to your scene using different scenarios:
ARPlaneAnchor
planeDetection
instance property is ON
, ARKit is able to add ARPlaneAnchors to the current session. Sometimes enabled planeDetection
considerably increases a time required for scene understanding stage.ARImageAnchor (conforms to ARTrackable protocol)
detectionImages
instance property. In ARKit 2.0 you can totally track up to 25 images, in ARKit 3.0 and ARKit 4.0 – up to 100 images, respectively. But, in both cases, not more than just 4 images simultaneously.ARBodyAnchor (conforms to ARTrackable
protocol)
ARBodyTrackingConfiguration()
. You'll get ARBodyAnchor in a Root Joint
of CG Skeleton, or at pelvis position of tracked character.ARFaceAnchor (conforms to ARTrackable
protocol)
ARObjectAnchor
ARReferenceObject
instances for detectionObjects
property of session config.AREnvironmentProbeAnchor
ARParticipantAnchor
true
value for isCollaborationEnabled
instance property in MultipeerConnectivity
framework.ARMeshAnchor
ARGeoAnchor (conforms to ARTrackable
protocol)
There are also other regular approaches to create anchors in AR session:
Hit-Testing methods
ARHitTestResult
class and its corresponding hit-testing methods for ARSCNView and ARSKView will be deprecated in iOS 14, so you have to get used to a Ray-Casting.Ray-Casting methods
Feature Points
ARCamera's transform
Any arbitrary World Position
world anchor
like AnchorEntity(.world(transform: mtx))
found in RealityKit.This code snippet shows you how to use an ARPlaneAnchor in a delegate's method: renderer(_:didAdd:for:)
:
func renderer(_ renderer: SCNSceneRenderer,
didAdd node: SCNNode,
for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor
else { return }
let grid = Grid(anchor: planeAnchor)
node.addChildNode(grid)
}
According to RealityKit documentation 2019:
AnchorEntity
is an anchor that tethers virtual content to a real-world object in an AR session.
RealityKit framework and Reality Composer app were released in WWDC'19. They have a new class named AnchorEntity
. You can use AnchorEntity as the root point of any entities' hierarchy, and you must add it to the Scene anchors collection. AnchorEntity automatically tracks real world target. In RealityKit and Reality Composer AnchorEntity
is at the top of hierarchy. This anchor is able to hold a hundred of models and in this case it's more stable than if you use 100 personal anchors for each model.
Let's see how it looks in a code:
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let modelAnchor = try! Experience.loadModel()
arView.scene.anchors.append(modelAnchor)
return arView
}
AnchorEntity
has three components:
To find out the difference between
ARAnchor
andAnchorEntity
look at THIS POST.
Here are nine AnchorEntity's cases available in RealityKit 2.0 for iOS:
// Fixed position in the AR scene
AnchorEntity(.world(transform: mtx))
// For body tracking (a.k.a. Motion Capture)
AnchorEntity(.body)
// Pinned to the tracking camera
AnchorEntity(.camera)
// For face tracking (Selfie Camera config)
AnchorEntity(.face)
// For image tracking config
AnchorEntity(.image(group: "Group", name: "model"))
// For object tracking config
AnchorEntity(.object(group: "Group", name: "object"))
// For plane detection with surface classification
AnchorEntity(.plane([.any], classification: [.seat], minimumBounds: [1.0, 1.0]))
// When you use ray-casting
AnchorEntity(raycastResult: myRaycastResult) /* no dot notation */
// When you use ARAnchor with a given identifier
AnchorEntity(.anchor(identifier: uuid))
// Creates anchor entity on a basis of ARAnchor
AnchorEntity(anchor: arAnchor) /* no dot notation */
And here are only two AnchorEntity's cases available in RealityKit 2.0 for macOS:
// Fixed world position in VR scene
AnchorEntity(.world(transform: mtx))
// Camera transform
AnchorEntity(.camera)
Also it’s not superfluous to say that you can use any subclass of
ARAnchor
forAnchorEntity
needs:
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
guard let faceAnchor = anchors.first as? ARFaceAnchor
else {
return
}
arView.session.add(anchor: faceAnchor)
let anchor = AnchorEntity(anchor: faceAnchor)
anchor.addChild(model)
arView.scene.anchors.append(anchor)
}