BSB
BSB

Reputation: 277

How to get current position of 3D object while animation is going on in ARKit?

On image marker detection, I want to play animation of walking guy within that marker boundary only using ARKit. For that I want to find out the position of that 3D object while it is walking on marker. Animation is created using external 3D authoring tool and saved in .scnassets as .dae file. I have added node and start animation using below code:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {  


     if let imageAnchor = anchor as? ARImageAnchor {  
          DispatchQueue.main.async { 
              //let translation = imageAnchor.transform.columns.3     
                let idleScene = SCNScene(named: "art.scnassets/WalkAround/WalkAround.dae")!  

             // This node will be parent of all the animation models  
                let node1 = SCNNode()  

                // Add all the child nodes to the parent node  
                for child in idleScene.rootNode.childNodes {  
                     node1.addChildNode(child)  
                }  

               node1.scale = SCNVector3(0.2, 0.2, 0.2)  
               let physicalSize = imageAnchor.referenceImage.physicalSize  
               let size = CGSize(width: 500, height: 500)  

               let skScene = SKScene(size: size)  
               skScene.backgroundColor = .white  

               let plane = SCNPlane(width: self.referenceImage!.physicalSize.width, height: self.referenceImage!.physicalSize.height)  

               let material = SCNMaterial()  
               material.lightingModel = SCNMaterial.LightingModel.constant  
               material.isDoubleSided = true  
               material.diffuse.contents = skScene  
               plane.materials = [material]  
               let rectNode = SCNNode(geometry: plane)  
               rectNode.eulerAngles.x = -.pi / 2  

               node.addChildNode(rectNode)  
               node.addChildNode(node1)  

               self.loadAnimation(withKey: "walking", sceneName: "art.scnassets/WalkAround/SambaArmtr", animationIdentifier: "SambaArmtr-1")  
         }  
    }  
}  
func loadAnimation(withKey: String, sceneName:String, animationIdentifier:String) {  
    let sceneURL = Bundle.main.url(forResource: sceneName, withExtension: "dae")  
    let sceneSource = SCNSceneSource(url: sceneURL!, options: nil)  

    if let animationObject = sceneSource?.entryWithIdentifier(animationIdentifier, withClass: CAAnimation.self) {  
        // The animation will only play once  
        animationObject.repeatCount = 1  
    }  
}

I tried using node.presentation.position in both below methods to get current position of object.

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)          
// Or
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor)

If I will not move device anymore once animation has been started, those methods will not get called and till the time I am getting same position of node. Thats why I am not getting where I am wrong. Or is there any way to get current position of object while animation is going on in ARKit?

Upvotes: 0

Views: 228

Answers (1)

Hermes
Hermes

Reputation: 2898

I don't know of any way to get the current frame within an embedded animation. With that said, the animation embedded within a model uses CoreAnimation to run the animation. You could use the CAAimationDelegate to listen to the start/end events of your animation and run a timer. The timer would give you the best estimate of which frame the animation is on.

References: SceneKit Animating Content Documentation: https://developer.apple.com/documentation/scenekit/animation/animating_scenekit_content

CAAnimationDelegate Documentation: https://developer.apple.com/documentation/quartzcore/caanimationdelegate

Upvotes: 0

Related Questions