web-dev-qa-db-fra.com

Affichage d'un fichier DAE avec ARKit et suivi d'une ancre dans la scène

J'essaie ARKit, et j'ai mis en place un ARSCNView en utilisant ce tutoriel .

Ensuite, configurez le suivi des plans 3D horizontaux avec la deuxième partie de ce tutoriel.

J'ai créé une application à vue unique, puis j'ai contraint un ARSCNView à la racine avec une sortie à mon ViewController.

Voici le code dans le ViewController:

import UIKit
import ARKit

class ViewController: UIViewController {

    //MARK: Properties
    @IBOutlet weak var arScene: ARSCNView!

    //MARK: ARKit variables
    var realityConfiguration: ARWorldTrackingSessionConfiguration?

    //MARK: Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()         
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.prepare()
    }

    //MARK: Actions      

    //MARK: Overrides
}

extension ViewController {
    func prepare() {
        //Check to see if active reality is supported
        guard ARSessionConfiguration.isSupported else {
            //Custom alert function that just quickly displays a UIAlertController
            AppDelegate.alert(title: "Not Supported", message: "Active Reality is not supported on this device")
            return
        }
        //Set up the ARSessionConfiguration
        self.realityConfiguration = ARWorldTrackingSessionConfiguration()
        //Set up the ARSCNView
        guard let config = self.realityConfiguration else {
            return
        }
        //Run the ARSCNView and set its delegate
        self.arScene.session.run(config)
        self.arScene.delegate = self
    }
}

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        return nil
    }

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let planAnchor = anchor as? ARPlaneAnchor else {
            return
        }

        let plane = SCNPlane(width: CGFloat(planAnchor.extent.x), height: CGFloat(planAnchor.extent.z))
        let planeNode = SCNNode(geometry: plane)
        planeNode.position = SCNVector3Make(planAnchor.center.x, 0, planAnchor.center.z)

        planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)

        node.addChildNode(planeNode)          
    }

    func renderer(_ renderer: SCNSceneRenderer, willUpdate node: SCNNode, for anchor: ARAnchor) {
        print("Will updated Node on Anchor: \(anchor.identifier)")
    }

    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        print("Did updated Node on Anchor: \(anchor.identifier)")
    }

    func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
        print("Removed Node on Anchor: \(anchor.identifier)")
    }
}

J'ai téléchargé Xcode 9 beta, suivi les tutoriels d'Apple et réalisé que mon iPhone 6 n'a pas la puce A9 requise pour l'objet ARWorldTrackingSessionConfiguration.

À mi-chemin dans le premier didacticiel que j'ai lié, Apple dit que vous pouvez toujours créer des expériences AR sans la puce A9. Cependant, elles n'entrent pas dans les détails. Est-ce que quelqu'un d'autre a trouvé un point de départ, et est prêt à fournir un exemple de code d'utilisation d'un fichier .dae et

  • Choisir un point d'ancrage pour l'afficher
  • Suivi de ce point d'ancrage
  • Affichage en fait du fichier .dae
12
Jon Vogel

Il n'y a vraiment rien à voir en utilisant votre code - juste une vue de caméra en direct.

La raison principale pour laquelle vous ne voyez aucune augmentation dans votre réalité est que votre code ajoute du contenu SceneKit à la scène uniquement lorsque des ancres sont ajoutées à ARSession... mais que vous n'ajoutez manuellement aucune ancre, et vous n'avez pas activé la détection des avions, donc ARKit n'ajoute pas automatiquement d'ancres. Si vous activez la détection des avions, vous commencerez à arriver quelque part ...

self.realityConfiguration = ARWorldTrackingSessionConfiguration()
realityConfiguration?.planeDetection = .horizontal

Mais vous ne verrez toujours rien. En effet, votre implémentation ARSCNViewDelegate contient des instructions contradictoires. Cette partie:

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    return nil
}

... signifie qu'aucun noeud SceneKit ne sera créé pour vos ancres. Parce qu'il n'y a pas de nœuds, votre fonction renderer(_:didAdd:for:) n'est jamais appelée, donc votre code dans cette méthode ne crée jamais de contenu SceneKit.

Si vous activez la détection d'avion et supprimez/commentez la méthode renderer(_: nodeFor:), le reste de votre code devrait vous fournir quelque chose comme ceci:

(La zone d'un blanc pur est votre SCNPlane. J'ai dû déplier la couverture de mon iPad sur le tableau blanc pour obtenir suffisamment de détails de scène pour que la détection d'avion trouve quoi que ce soit. De plus, vérifiez l'arrière-plan ... il y a eu un moment à WWDC aujourd'hui, où le magasin de marchandise n'était pas rempli de monde.)

Quant à savoir si vous avez besoin d'un A9, la messagerie d'Apple n'est pas claire ici. Quand ils disent qu'ARKit nécessite A9 ou mieux, ce qu'ils veulent vraiment dire c'est que ARWorldTrackingSessionConfiguration le fait. Et c'est là que réside toute la meilleure magie AR. (Il existe même une touche UIRequiredDeviceCapabilities pour arkit qui couvre en fait les appareils avec prise en charge du suivi mondial, vous pouvez donc restreindre votre application sur l'App Store à être proposée uniquement à ces appareils.)

Il y a toujours certains ARKit sans suivi du monde, cependant. Exécutez une session avec la classe de base ARSessionConfiguration et vous obtenez un suivi d'orientation uniquement. (Pas de suivi de position, pas de détection d'avion, pas de test de frappe.)

Qu'est-ce que cela vous apporte? Eh bien, si vous avez joué à la version actuelle de Pokémon GO, cela fonctionne comme ça: parce qu'il ne suit que l'orientation de l'appareil, pas la position, vous ne pouvez pas vous rapprocher de Pikachu ou vous promener derrière lui - l'illusion qu'il occupe le vrai monde tient tant que vous inclinez ou tournez votre appareil sans le déplacer.

Vous chargez du contenu 3D avec SceneKit et le placez dans AR comme vous le chargez et le placez dans n'importe quelle autre application/jeu SceneKit. Il existe de nombreuses ressources pour cela et de nombreuses façons de le faire. Vous en trouverez un dans le modèle Xcode lorsque vous créez un nouveau projet AR et choisissez SceneKit. La partie de chargement ressemble à ceci:

let scene = SCNScene(named: "ship.scn" inDirectory: "assets.scnassets")
let ship = scene.rootNode.childNode(withName: "ship", recursively: true)

Ensuite pour le placer:

ship.simdPosition = float3(0, 0, -0.5) 
// half a meter in front of the *initial* camera position
myARSCNView.scene.rootNode.addChildNode(ship)

La principale différence à retenir pour placer des objets dans la RA est que les positions sont mesurées en mètres (et que votre contenu doit être conçu de sorte qu'il soit sensiblement dimensionné en mètres).

31
rickster