For example one of the possible option to create AnchorEntity for RealityKit is provided below:
Code Block let imageAnchor = AnchorEntity(.image(group:"group_name", name:"image_name")) self.arView.scene.anchors.append(imageAnchor)
But, is it possible to create AnchorEntity, for example, from ARReferenceImage? Something like that:
Code Block let referenceImage = ARReferenceImage(self.image.cgImage!, orientation: self.getCGOrientationFromUIImage(self.image), physicalWidth: width) let imageAnchor = AnchorEntity(.image(referenceImage))
I want to download image from the internet and use it for creating AnchorEntity. Is there any way for solving such problem?
Begin an ARWorldTrackingConfiguration or ARImageTrackingConfiguration so your users have a responsive experience and see the camera feed immediately.
Create an empty set of ARReferenceImages, which will be used to hold your downloaded images.
Download the necessary images from your web-based resource, using a common URLSession (or any optimal method for downloading images).
Instantiate an ARReferenceImage for each of your downloaded images. Note that you will also need to have awareness of the image's orientation, as well as the image's physical width in the real world (you may want to have some data, such as a JSON file, that contains the URLs of each image, alongside their real-world size, in meters).
Insert each of your new ARReferenceImages to the empty ARReferenceImages set.
Reset your session and configure a new ARWorldTrackingConfiguration or ARImageTrackingConfiguration, setting your newly created ARReferenceImages set to the configuration's detectionImages or trackingImages property, respectively.
Instantiate an AnchorEntity from the ARImageAnchor, which you should receive in a delegate method whenever a tracked image is found.
Set Up A Session For A Responsive Experience
Assuming you already have a RealityKit project going, you could add this in your viewDidLoad method.
Code Block let configuration = ARWorldTrackingConfiguration() sceneView.session.run(configuration)
Create An Empty Set of ARReferenceImages
You could add this to a local function or as a property accessible to your entire ViewController or class.
Code Block var newReferenceImages: Set<ARReferenceImage> = Set<ARReferenceImage>()
Download the Images
You can use an asynchronous URLSession to download your images (and any relevant metadata). This should return each image as a UIImage. As your question focuses more on ARKit/RealityKit, this is being skipped, but you should be able to find plenty of resources with regards to downloading images online.
Instantiate a New ARReferenceImage from Each Downloaded Image
For each downloaded image, you could create a new ARReferenceImage.
Code Block let myImage = ARReferenceImage(downloadedImage.cgImage!, orientation: CGImagePropertyOrientation.up, physicalWidth: width)
In your case, you will want to consider how you are acquiring the CGImagePropertyOrientation (whether that is being determined by a function you already have in your app, as your sample in the question shows, setting to .up as a default, or some other methodology). The same with the physical width of the image; you'll want to acquire that from somewhere prior to this step.
Insert Each ARReferenceImage Into the Empty ARReferenceImages Set
Code Block newReferenceImages.insert(myImage)
Reset Session and Re-Configure
Once you have added each ARReferenceImage to the ARReferenceImages set, you can reset your session and apply this set to the configuration. I would recommend a function like such;
Code Block func resetSession() { let configuration = ARWorldTrackingConfiguration() configuration.detectionImages = newReferenceImages configuration.maximumNumberOfTrackedImages = 1 session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) }
Your choice of maximumNumberOfTrackedImages should be a number suitable for your app's experience.
Create AnchorEntity from Each ARImageAnchor
Presumably, you will have already set an ARSessionDelegate somewhere in your setup. This should allow your delegate to receive a call each time new anchors are added, which will be provided as the more general ARAnchor. Therefore, I would use that delegate function like such;
Code Block func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { for anchor in anchors { if let myAnchor = anchor as? ARImageAnchor { let imageAnchor = AnchorEntity(anchor: myAnchor) /* Do something with the anchor here if necessary, such as adding an Entity to the model. For example; let model = try! Entity.load(named: "myModel") model.position = imageAnchor.position imageAnchor.addChild(model) */ self.scene.addAnchor(imageAnchor) } } }
Note that this example does not take into account efficiency (I.E. instantiating the should probably happen somewhere earlier in your app's lifecycle), but as a whole, this should point you in the general direction of each step necessary to download, build, and set your ARReferenceImages.