[Swift5] Démarrez ARKit ~ Capture de mouvement ~

Bonjour. Je suis Sato, qui est banal. Oui c'est moi. Récemment, je me suis soudainement intéressé à la RA. Je veux toucher LIDAR, mais je n'ai pas de terminal avec LIDAR dessus. .. Tout d'abord, découvrez ce que vous pouvez faire avec ARKit! J'ai pensé, tout d'abord, j'ai commencé à étudier! Pourquoi de la capture de mouvement ... Est-il plus facile d'entrer s'il y a du mouvement? Je pense donc je vais l'essayer!


Environnement de développement


ARKit Apple l'explique officiellement, alors veuillez vérifier ici ^^ Apple ARKit4

ARKit 4 présente une toute nouvelle API Depth, créant une nouvelle façon d'accéder aux informations de profondeur détaillées collectées par le scanner LiDAR sur iPhone 12 Pro, iPhone 12 Pro Max et iPad Pro. Location Anchors exploite les données haute résolution d'Apple Maps pour placer l'expérience AR à des endroits spécifiques du monde des applications iPhone et iPad. En outre, la prise en charge du suivi des visages a été étendue à tous les appareils avec Apple Neural Engine et caméra frontale, permettant à encore plus d'utilisateurs de découvrir le plaisir de la RA avec des photos et des vidéos.


Faisons un projet!


Créer un nouveau

Tout d'abord, comme d'habitude, avec Xcode "Bienvenue sur Xcode" Sélectionnez "Créer un nouveau projet Xcode" スクリーンショット 2020-11-08 10.43.41.png


Sélection de modèles

Sélectionnez "Application de réalité augmentée" スクリーンショット 2020-11-08 10.43.59.png


Donnez un nom à l'application

「MotionCapture」 Cette fois, créez un exemple d'application de capture de mouvement comme celui-ci, appuyez sur "Suivant", Vous pouvez enregistrer le projet à n'importe quel emplacement.

スクリーンショット 2020-11-08 10.46.17.png


Modèle de projet

Xcode a été lancé et l'application modèle a été créée. Connectez votre iPhone à votre Mac et essayez "Exécuter". Sélectionnez "OK" pour l'autorisation d'accès à la caméra, déplacez l'iPhone et recherchez la machine à réaction! Si vous le trouvez, vous pouvez vérifier le plan à réaction sous différents angles en modifiant l'angle.

Vous l'avez expliqué pendant longtemps ... Juste au cas où, il peut y avoir des gens qui en ont besoin, alors je l'ai écrit w


Rush dans la capture de mouvement

ARSCNViewDelegate est déjà inclus. ARSCVViewDelegate ajoute, met à jour, supprime, etc. à ARnchor Il est préparé pour gérer l'événement, Puisque je veux capturer le mouvement cette fois, j'utiliserai ARSessionDelegate. Remplacez «ARSCNViewDelegate» par «ARSessionDelegate».

ViewController.swift


class ViewController: UIViewController, ARSCNViewDelegate {
↓
class ViewController: UIViewController, ARSessionDelegate {

SceneView est déjà défini dans le modèle. Bien sûr, il est également disponible dans StoryBoard.

ViewController.swift


    @IBOutlet var sceneView: ARSCNView!

Supprimez le délégué sceneView et Défini sur self dans le délégué de la session de sceneView afin qu'il puisse être manipulé

ViewController.swift


    sceneView.delegate = self
    ↓
    sceneView.session.delegate = self

Définissez un [SCNSScene] vide (https://developer.apple.com/documentation/scenekit/scnscene) sur la scène de la sceneView

ViewController.swift


    sceneView.scene = SCNScene()

Ce n'est pas nécessaire cette fois, vous pouvez donc le supprimer

ViewController.swift


        // Show statistics such as fps and timing information
        //La valeur par défaut est false, mais les informations affichées en bas de l'écran lors de sa mise en marche sur l'avion à réaction sont activées./hors drapeau
        sceneView.showsStatistics = true
        
        // Create a new scene
        //Charger un objet 3D jet
        let scene = SCNScene(named: "art.scnassets/ship.scn")!
        
        // Set the scene to the view
        //Afficher la machine à jet dans sceneView
        sceneView.scene = scene

Changer le paramètre pour suivre le mouvement des personnes

À l'origine dans la vue Remplacez "Configuration de suivi ARWorld" par "Configuration de suivi corporel AR" Réglez sur sceneView.

ARWorldTrackingConfiguration ARBodyTrackingConfiguration

ViewController.swift



        guard ARBodyTrackingConfiguration.isSupported else {
            fatalError("This feature is only supported on devices with an A12 chip")
        }
        // Create a session configuration
        // let configuration = ARWorldTrackingConfiguration()
        // ↓
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)

Implémenter la méthode déléguée d'ARSessionDelegate

Ces deux sont utilisés cette fois ・ ** session (ARSession, didAdd: [ARAnchor]) **, qui est appelée lorsque ARAnchor est ajouté.

https://developer.apple.com/documentation/arkit/arsessiondelegate


func session(ARSession, didAdd: [ARAnchor])

func session(ARSession, didUpdate: [ARAnchor])

Implémenter une session func (ARSession, didAdd: [ARAnchor])

Pour la boucle d'ancres, vérifiez si ARAnchor est ARBodyAnchor, et ne traitez pas autre que ARBodyAnchor cette fois revenir.

ViewController.swift


    func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
        for anchor in anchors {
            guard let bodyAnchor = anchor as? ARBodyAnchor else {
                return
            }
            // Next
        }
    }

Nous allons également implémenter func session (ARSession, didUpdate: [ARAnchor]).

Comme pour didAdd, cochez ARAnchor et implémentez-le pour que seule la cible soit traitée.

ViewController.swift


    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
        for anchor in anchors {
            guard let bAnchor = anchor as? ARBodyAnchor else {
                return
            }
            // Next
        }
    }

Extraire des informations d'ARBodyAnchor et dessiner

Utilisons ARBodyAnchor obtenu à partir des deux méthodes de délégué et affichons-le à l'écran. -Récupérez squelette de ARBodyAnchor. squelette est une information physique 3D.

ViewController.swift


        let skeleton = anchor.skeleton

Obtenez les jointsNames du squelette AR SkeletonDefinition dans une boucle for. Les coordonnées de ARBody Anchor sont centrées sur la position de "hips_joint". Utilisez le jointName obtenu et utilisez modelTransform pour obtenir la quantité de mouvement et de rotation à partir du centre. Pour modelTransform, nil est obtenu lorsqu'un jointName inexistant est défini.

ViewController.swift


        for jointName in skeleton.definition.jointNames {
            let jointType = ARSkeleton.JointName(rawValue: jointName)
            if let transform = skeleton.modelTransform(for: jointType) {

Remarques: jointName

J'ai essayé d'obtenir jointName avec un débogueur. 91 pièces. Je me demande s'il y en a plus ...? - 0 : "root" - 1 : "hips_joint" - 2 : "left_upLeg_joint" - 3 : "left_leg_joint" - 4 : "left_foot_joint" - 5 : "left_toes_joint" - 6 : "left_toesEnd_joint" - 7 : "right_upLeg_joint" - 8 : "right_leg_joint" - 9 : "right_foot_joint" - 10 : "right_toes_joint" - 11 : "right_toesEnd_joint" - 12 : "spine_1_joint" - 13 : "spine_2_joint" - 14 : "spine_3_joint" - 15 : "spine_4_joint" - 16 : "spine_5_joint" - 17 : "spine_6_joint" - 18 : "spine_7_joint" - 19 : "left_shoulder_1_joint" - 20 : "left_arm_joint" - 21 : "left_forearm_joint" - 22 : "left_hand_joint" - 23 : "left_handIndexStart_joint" - 24 : "left_handIndex_1_joint" - 25 : "left_handIndex_2_joint" - 26 : "left_handIndex_3_joint" - 27 : "left_handIndexEnd_joint" - 28 : "left_handMidStart_joint" - 29 : "left_handMid_1_joint" - 30 : "left_handMid_2_joint" - 31 : "left_handMid_3_joint" - 32 : "left_handMidEnd_joint" - 33 : "left_handPinkyStart_joint" - 34 : "left_handPinky_1_joint" - 35 : "left_handPinky_2_joint" - 36 : "left_handPinky_3_joint" - 37 : "left_handPinkyEnd_joint" - 38 : "left_handRingStart_joint" - 39 : "left_handRing_1_joint" - 40 : "left_handRing_2_joint" - 41 : "left_handRing_3_joint" - 42 : "left_handRingEnd_joint" - 43 : "left_handThumbStart_joint" - 44 : "left_handThumb_1_joint" - 45 : "left_handThumb_2_joint" - 46 : "left_handThumbEnd_joint" - 47 : "neck_1_joint" - 48 : "neck_2_joint" - 49 : "neck_3_joint" - 50 : "neck_4_joint" - 51 : "head_joint" - 52 : "jaw_joint" - 53 : "chin_joint" - 54 : "left_eye_joint" - 55 : "left_eyeLowerLid_joint" - 56 : "left_eyeUpperLid_joint" - 57 : "left_eyeball_joint" - 58 : "nose_joint" - 59 : "right_eye_joint" - 60 : "right_eyeLowerLid_joint" - 61 : "right_eyeUpperLid_joint" - 62 : "right_eyeball_joint" - 63 : "right_shoulder_1_joint" - 64 : "right_arm_joint" - 65 : "right_forearm_joint" - 66 : "right_hand_joint" - 67 : "right_handIndexStart_joint" - 68 : "right_handIndex_1_joint" - 69 : "right_handIndex_2_joint" - 70 : "right_handIndex_3_joint" - 71 : "right_handIndexEnd_joint" - 72 : "right_handMidStart_joint" - 73 : "right_handMid_1_joint" - 74 : "right_handMid_2_joint" - 75 : "right_handMid_3_joint" - 76 : "right_handMidEnd_joint" - 77 : "right_handPinkyStart_joint" - 78 : "right_handPinky_1_joint" - 79 : "right_handPinky_2_joint" - 80 : "right_handPinky_3_joint" - 81 : "right_handPinkyEnd_joint" - 82 : "right_handRingStart_joint" - 83 : "right_handRing_1_joint" - 84 : "right_handRing_2_joint" - 85 : "right_handRing_3_joint" - 86 : "right_handRingEnd_joint" - 87 : "right_handThumbStart_joint" - 88 : "right_handThumb_1_joint" - 89 : "right_handThumb_2_joint" - 90 : "right_handThumbEnd_joint"

Multipliez les informations de pièce acquises par le point central de l'ARBody Anchor Acquérir la position et la rotation des pièces dans l'espace 3D.

ViewController.swift


        ///Couler la position / rotation du jointType
        let partsPoint = SCNMatrix4(transform)
        ///Lancer la position / rotation de la hanche du point de référence
        let hipPoint = SCNMatrix4(anchor.transform)
        /// func SCNMatrix4Mult(_ a: SCNMatrix4, _ b: SCNMatrix4) ->Lors de la synthèse d'une matrice avec SCNMatrix4, considérez que a à gauche est celui à faire plus tard et b à droite est celui à faire en premier.
        let matrix = SCNMatrix4Mult(partsPoint, hipPoint)
        let position = SCNVector3(matrix.m41, matrix.m42, matrix.m43)

Vérifiez s'il y a déjà la même chose dans SceneeView, mettez à jour s'il y en a, ajoutez si non

À partir de sceneView, recherchez le nom du nœud dans Key et S'il existe, définissez la position du nœud et mettez-le à jour. S'il n'existe pas, créez une sphère avec "SCNSphere (rayon: 0.02)" Créer SCNNode, définir la position et le nom pour la recherche AjoutezChildNode au SCNNode créé dans sceneView.scene.rootNode.

ViewController.swift


        if let nodeToUpdate = sceneView.scene.rootNode.childNode(withName: jointName, recursively: false) {
            ///Puisqu'il a déjà été ajouté, ne mettez à jour que la position
            nodeToUpdate.isHidden = false
            nodeToUpdate.position = position
        } else {
            // GeoSphere
            //Radius Le rayon de la sphère avec une valeur initiale de 1.
            let sphereGeometry = SCNSphere(radius: 0.02)
            //Si coché, la surface du polygone triangulaire sera construite uniformément. La valeur initiale est fausse
            sphereGeometry.isGeodesic = true
            //Couleur de la sphère
            sphereGeometry.firstMaterial?.diffuse.contents = UIColor.green
            //Définir la géométrie de la sphère pour le nœud
            let sphereNode = SCNNode(geometry: sphereGeometry)
            //Réglage de la position d'affichage
            sphereNode.position = position
            //Paramètre de nom pour le nœud
            sphereNode.name = jointName
            //Ajouter au nœud racine
            sceneView.scene.rootNode.addChildNode(sphereNode)
        }

Maintenant c'est fait.

Lançons-le. S'il n'y a personne, regardez une vidéo d'une personne qui marche comme YouTube sur l'écran de votre iPhone. S'il te plait regarde.

Toutes les sources sont transférées vers Github, alors veuillez les prendre. https://github.com/Satoiosdevelop/ExampleMotionCapture

Recommended Posts

[Swift5] Démarrez ARKit ~ Capture de mouvement ~
[Swift] Liste de capture