[Swift5] Starten Sie ARKit ~ Motion Capture ~

Hallo. Ich bin Sato, der alltäglich ist. Ja, ich bin es. Vor kurzem habe ich mich plötzlich für AR interessiert. Ich möchte LIDAR berühren, habe aber kein Terminal mit LIDAR. .. Erfahren Sie zunächst, was Sie mit ARKit tun können! Ich dachte, zuerst habe ich angefangen zu studieren! Warum von Motion Capture ... Ist es einfacher einzutreten, wenn es Bewegung gibt? Ich denke, ich werde es versuchen!


Entwicklungsumgebung


ARKit Es gibt eine offizielle Erklärung von Apple, bitte überprüfen Sie hier ^^ Apple ARKit4

ARKit 4 führt eine brandneue Tiefen-API ein, die eine neue Möglichkeit bietet, auf detaillierte Tiefeninformationen zuzugreifen, die von LiDAR-Scannern auf iPhone 12 Pro, iPhone 12 Pro Max und iPad Pro gesammelt wurden. Location Anchors nutzt die hochauflösenden Daten von Apple Maps, um das AR-Erlebnis an bestimmten Orten in der Welt der iPhone- und iPad-Apps zu platzieren. Darüber hinaus wurde die Gesichtsverfolgungsunterstützung auf alle Geräte mit Apple Neural Engine und Frontkamera erweitert, sodass noch mehr Benutzer den Spaß an AR mit Fotos und Videos erleben können.


Lass uns ein Projekt machen!


Erstelle neu

Zuerst wie gewohnt mit Xcode "Willkommen bei Xcode" Wählen Sie "Neues Xcode-Projekt erstellen" スクリーンショット 2020-11-08 10.43.41.png


Vorlagenauswahl

Wählen Sie "Augmented Reality App" スクリーンショット 2020-11-08 10.43.59.png


Geben Sie einen Anwendungsnamen an

「MotionCapture」 Erstellen Sie dieses Mal eine Beispiel-Motion-Capture-App wie diese, und klicken Sie auf "Weiter". Sie können das Projekt an einem beliebigen Ort speichern.

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


Projektvorlage

Xcode wurde gestartet und die Vorlagen-App wurde erstellt. Schließen Sie Ihr iPhone an Ihren Mac an und versuchen Sie "Ausführen". Wählen Sie "OK" für die Zugriffsberechtigung zur Kamera, bewegen Sie das iPhone und suchen Sie nach der Jet-Maschine! Wenn Sie es finden, können Sie die Düsenebene aus verschiedenen Winkeln überprüfen, indem Sie den Winkel ändern.

Du hast es lange erklärt ... Nur für den Fall, dass es Leute gibt, die es brauchen, also habe ich es w geschrieben


Rase in die Bewegungserfassung

ARSCNViewDelegate ist bereits enthalten. ARSCVViewDelegate fügt ARnchor hinzu, aktualisiert, löscht usw. Es ist für die Behandlung des Ereignisses vorbereitet, Da ich die Bewegung dieses Mal erfassen möchte, verwende ich ARSessionDelegate. Ändern Sie "ARSCNViewDelegate" in "ARSessionDelegate".

ViewController.swift


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

SceneView ist bereits in der Vorlage definiert. Natürlich ist es auch in StoryBoard verfügbar.

ViewController.swift


    @IBOutlet var sceneView: ARSCNView!

Entfernen Sie den sceneView-Delegaten und Setzen Sie im Delegaten der Sitzung von sceneView auf self, damit es verarbeitet werden kann

ViewController.swift


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

Setzen Sie eine leere SCNSScene auf die Szene der sceneView

ViewController.swift


    sceneView.scene = SCNScene()

Dies ist diesmal nicht erforderlich, sodass Sie es löschen können

ViewController.swift


        // Show statistics such as fps and timing information
        //Die Standardeinstellung ist false, aber die Informationsanzeige am unteren Bildschirmrand, als sie im Düsenflugzeug ausgegeben wurde, ist aktiviert./aus Flagge
        sceneView.showsStatistics = true
        
        // Create a new scene
        //Laden Sie ein Jet-3D-Objekt
        let scene = SCNScene(named: "art.scnassets/ship.scn")!
        
        // Set the scene to the view
        //Zeigen Sie die Jet-Maschine in sceneView an
        sceneView.scene = scene

Ändern Sie die Einstellung, um die Bewegung von Personen zu verfolgen

Ursprünglich in viewWillAppear Ändern Sie "ARWorld Tracking-Konfiguration" in "AR Body Tracking-Konfiguration". Auf sceneView setzen.

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)

Implementieren Sie die Delegate-Methode von ARSessionDelegate

Diese beiden werden diesmal verwendet

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


func session(ARSession, didAdd: [ARAnchor])

func session(ARSession, didUpdate: [ARAnchor])

Funktionssitzung implementieren (ARSession, didAdd: [ARAnchor])

Überprüfen Sie für eine Ankerschleife, ob ARAnchor ARBodyAnchor ist, und verarbeiten Sie diesmal nur ARBodyAnchor Rückkehr.

ViewController.swift


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

Wir werden auch eine Funktionssitzung implementieren (ARSession, didUpdate: [ARAnchor]).

Überprüfen Sie wie bei didAdd ARAnchor und implementieren Sie es so, dass nur das Ziel verarbeitet wird.

ViewController.swift


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

Extrahieren Sie Informationen aus ARBodyAnchor und zeichnen Sie

Verwenden wir ARBodyAnchor, das von beiden Delegatmethoden erhalten wurde, und zeigen es auf dem Bildschirm an. -Extrahieren Sie Skelett von ARBodyAnchor. Skelett ist physikalische 3D-Information.

ViewController.swift


        let skeleton = anchor.skeleton

Holen Sie sich die gemeinsamen Namen der [AR SkeletonDefinition] des Skeletts (https://developer.apple.com/documentation/arkit/arskeletondefinition) in eine for-Schleife. Die Koordinaten von ARBodyAnchor sind auf die Position von "hips_joint" zentriert. Verwenden Sie den erhaltenen Gelenknamen und verwenden Sie modelTransform, um das Ausmaß der Bewegung und Drehung von der Mitte zu erhalten. Für modelTransform wird nil erhalten, wenn ein nicht vorhandener JointName festgelegt wird.

ViewController.swift


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

Anmerkungen: JointName

Ich habe versucht, einen gemeinsamen Namen mit einem Debugger zu erhalten. 91 Teile. Ich frage mich, ob es noch mehr gibt ...? - 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"

Multiplizieren Sie die erfassten Teileinformationen mit dem Mittelpunkt von ARBody Anchor Erfassen Sie die Position und Drehung von Teilen im 3D-Raum.

ViewController.swift


        ///Wirf die Position / Drehung von JointType
        let partsPoint = SCNMatrix4(transform)
        ///Wirf die Position / Drehung des Referenzpunkts Hüfte
        let hipPoint = SCNMatrix4(anchor.transform)
        /// func SCNMatrix4Mult(_ a: SCNMatrix4, _ b: SCNMatrix4) ->Berücksichtigen Sie beim Synthetisieren einer Matrix mit SCNMatrix4, dass a links später und b rechts zuerst ausgeführt wird.
        let matrix = SCNMatrix4Mult(partsPoint, hipPoint)
        let position = SCNVector3(matrix.m41, matrix.m42, matrix.m43)

Überprüfen Sie, ob SceneeView bereits dasselbe enthält, aktualisieren Sie es, falls vorhanden, und fügen Sie es hinzu, wenn nicht

Suchen Sie in der Szenenansicht in Schlüssel und nach dem Knotennamen Wenn vorhanden, legen Sie die Position des Knotens fest und aktualisieren Sie ihn. Wenn es nicht existiert, erstellen Sie eine Kugel mit "SCNSphere (Radius: 0,02)". Erstellen Sie SCNNode, legen Sie Position und Namen für die Suche fest AddChildNode zum erstellten SCNNode zu sceneView.scene.rootNode.

ViewController.swift


        if let nodeToUpdate = sceneView.scene.rootNode.childNode(withName: jointName, recursively: false) {
            ///Da es bereits hinzugefügt wurde, aktualisieren Sie nur die Position
            nodeToUpdate.isHidden = false
            nodeToUpdate.position = position
        } else {
            // GeoSphere
            //Radius Der Radius der Kugel mit einem Anfangswert von 1.
            let sphereGeometry = SCNSphere(radius: 0.02)
            //Wenn diese Option aktiviert ist, wird die Oberfläche des dreieckigen Polygons gleichmäßig konstruiert. Der Anfangswert ist falsch
            sphereGeometry.isGeodesic = true
            //Kugelfarbe
            sphereGeometry.firstMaterial?.diffuse.contents = UIColor.green
            //Stellen Sie die Kugelgeometrie für den Knoten ein
            let sphereNode = SCNNode(geometry: sphereGeometry)
            //Positionseinstellung anzeigen
            sphereNode.position = position
            //Namenseinstellung für Knoten
            sphereNode.name = jointName
            //Zum Stammknoten hinzufügen
            sceneView.scene.rootNode.addChildNode(sphereNode)
        }

Jetzt ist es geschafft.

Lass es uns laufen. Wenn keine Personen anwesend sind, sehen Sie sich ein Video einer wandelnden Person wie YouTube über den Bildschirm Ihres iPhones an. Bitte sehen Sie.

Alle Quellen werden an Github weitergeleitet. Bitte nehmen Sie sie mit. https://github.com/Satoiosdevelop/ExampleMotionCapture

Recommended Posts

[Swift5] Starten Sie ARKit ~ Motion Capture ~
[Swift] Erfassungsliste