Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARKit RealityKit warning during runtime when placing an object in ARView

I get the following warning during runtime when I tap to load the model in ARView: Warning (secondary thread): in AppendProperty at line 859 of sdf/path.cpp -- Can only append a property 'preliminary:anchoring:type' to a prim path (/) Warning (secondary thread): in AppendProperty at line 859 of sdf/path.cpp -- Can only append a property 'triggers' to a prim path (/)

Anyone have insights why I'm getting this warning? All of the logic is in my ViewController:

import UIKit
import ARKit
import RealityKit
import SwiftUI
import Combine

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate  {

private var modelArray: [String] = []
var selectedModel = ""

@IBOutlet weak var arView: ARView!

@IBOutlet weak var modelCollectionView: UICollectionView!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    loadModelName()
    arView.session.delegate = self
    setupARView()
    //modelArray = getModelNames()
    self.modelCollectionView.dataSource = self
    self.modelCollectionView.delegate = self
    arView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:))))
    
}
 // Dynamically load available files from directory
func loadModelName() {
    
    let fm = FileManager.default
    let path = Bundle.main.resourcePath!

    do {
        let items = try fm.contentsOfDirectory(atPath: path)

        for item in items where item.hasSuffix("usdz"){
            let modelName = item.replacingOccurrences(of: ".usdz", with: "")
            print("Found \(item)")
            modelArray.append(modelName)
        }
    } catch {
        // failed to read directory – bad permissions, perhaps?
    }
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return modelArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! itemCell
        cell.itemImage.image = UIImage(named: self.modelArray[indexPath.row])
        return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.lightGray
    selectedModel = self.modelArray[indexPath.row] + ".usdz"
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.white
}



 func setupARView() {
        arView.automaticallyConfigureSession = false
        let configuration  = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal, .vertical]
        configuration.environmentTexturing = .automatic
        if ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh) {
            print("scene reconstruction supported")
            configuration.sceneReconstruction = .mesh
            configuration.sceneReconstruction = .meshWithClassification
            arView.debugOptions.insert(.showSceneUnderstanding)
        }
        arView.session.run(configuration)
        print("plane detection")
    }



 @objc
    func handleTap(recognizer: UITapGestureRecognizer) {
        //gets the location in the arView
        let location = recognizer.location(in: arView)
        //grab the results of the tap -location: the location of the tap -allowing: tye type of surface to calculate the location -alignment: the type of surface
        let reults = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .any)
        
    //check to see if the raycast returned a result, did it actually hit a horizontal surface
    if let firstResult = reults.first {
        //returns an array of all the things it finds so grab the first
        //in order to add objects into a scene, we have to add objects to anchors, firstResult.worldTransform - add anchor at the orientation and position
        print("tap gesture recognized")
        print("DEBUG: the model is \(selectedModel)")
        let anchor = ARAnchor(name: selectedModel, transform: firstResult.worldTransform)
        arView.session.add(anchor: anchor)
    } else {
        print("object placement failed, couldn't find surface")
    } 
}

func placeObject(named entityName: String, for anchor: ARAnchor) {
let entity = try! ModelEntity.loadModel(named: entityName)

    //add collision to have physiscs for manipulations
    entity.generateCollisionShapes(recursive: true)
    arView.installGestures([.rotation, .translation], for: entity)

    //create an anchor entity
    let anchorEntity = AnchorEntity(anchor: anchor)
    // add the entity to anchor
    anchorEntity.addChild(entity.clone(recursive: true))
    //add the anchor with the entity to the scene
    arView.scene.addAnchor(anchorEntity)
}
}

extension ViewController: ARSessionDelegate {
    func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
        for anchor in anchors {
            if let anchorName = anchor.name, anchorName == selectedModel {
                placeObject(named: anchorName, for: anchor)
            }
        }
    }
}
like image 609
Myoung Avatar asked Jan 26 '21 06:01

Myoung


1 Answers

Warnings

In short, the answer sounds like this: if you declared a preliminary anchoring for USDZ model, then Xcode will not print such warnings. Those warnings come from USD C++ library.

Now let's talk about this in more detail. As you said before, there are two warnings in Xcode's console when running your AR app in debug mode:

// Warning: in AppendProperty at line 859 of sdf/path.cpp - Can only append a 
// property 'preliminary:anchoring:type' to a prim path (/)

// Warning: in AppendProperty at line 859 of sdf/path.cpp - Can only append a
// property 'triggers' to a prim path (/)

You can easily find the C++ statement in Pixar/Apple path.cpp file (just type file's name in Spotlight Search string) that generates those warnings. Here it is:

SdfPath::AppendProperty(TfToken const &propName) const {
    if (ARCH_UNLIKELY(_propPart)) {
        TF_WARN("Can only append a property '%s' to a prim path (%s)",
                propName.GetText(), GetText());
        return EmptyPath();
    }
}

So, what's the point? Let me quote the Apple documentation:

The Preliminary_AnchoringAPI specifies an anchor’s center as the prim’s origin, and the top of the anchor as its normal vector points. The runtime requires an asset to supply a value for this property.


You can read more about preliminary:anchoring:type in USDZ Schemas story.


In other words, if you use files with preliminary generated anchors in your scene, whether they are anchors assigned in Reality Composer or pythonically defined anchors for the .usdz scene, you will not receive such messages.

Reality Composer describes AR features in its USDZ export using these schemas, too...


Turning warnings off

If those messages are really annoying for you, just turn them off.

Go to Xcode's menu Product Scheme Edit Scheme and add you environment variable.

OS_ACTIVITY_MODE = disable

enter image description here

like image 66
Andy Jazz Avatar answered Nov 05 '22 21:11

Andy Jazz