3 Replies
      Latest reply on Oct 10, 2019 8:12 AM by gchiste
      GerryGGG Level 1 Level 1 (0 points)

        Is there ANY documentation or resource that explains how to implement motion capture in Scenekit?

        • Re: Motion capture in Scenekit
          gchiste Apple Staff Apple Staff (190 points)

          You need to make use of the ARBodyAnchor that is returned in session(_:didUpdate:) during an ARBodyTrackingConfiguration.  Specifically, you would use the jointModelTransforms of the ARSkeleton3D to update the positions of your geometry.

           

          For example, the following snippet places an SCNSphere at every joint:

           

              fileprivate func addSphere(for jointTransform: simd_float4x4) {
                  let node = SCNNode()
                  let geometry = SCNSphere(radius: 0.01)
                  geometry.firstMaterial?.diffuse.contents = UIColor(displayP3Red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), alpha: 1)
                  node.geometry = geometry
                  node.simdTransform = jointTransform
                  bodyNode.addChildNode(node)
                  jointNodes.append(node)
              }
             
              func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
                  let bodyAnchors = anchors.compactMap { $0 as? ARBodyAnchor }
                  guard let bodyAnchor = bodyAnchors.first else { return }
                  print("body anchor")
                  bodyNode = SCNNode()
                  bodyNode.simdWorldTransform = bodyAnchor.transform
                  bodyAnchor.skeleton.jointModelTransforms.forEach {
                      addSphere(for: $0)
                  }
                  sceneView.scene.rootNode.addChildNode(bodyNode)
              }
             
              func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                  let bodyAnchors = anchors.compactMap { $0 as? ARBodyAnchor }
                  guard let bodyAnchor = bodyAnchors.first else { return }
                  bodyNode.simdWorldTransform = bodyAnchor.transform
                  bodyAnchor.skeleton.jointModelTransforms.enumerated().forEach {
                      jointNodes[$0].simdTransform = $1
                  }
              }