2017-10-19 20 views
1

J'essaie de faire glisser un nœud exactement là où mon doigt est sur l'écran sur l'axe y. Mais je ne trouve aucun moyen de le faire, voici mon code actuel. Avez-vous une idée?ARKit - Faites glisser un nœud le long d'un axe spécifique (pas sur un plan)

var movedObject:SCNNode? 

    @objc func handlePan(_ recognizer: UIPanGestureRecognizer) { 

     if recognizer.state == .began { 

      let tapPoint: CGPoint = recognizer.location(in: sceneView) 
      let result = sceneView.hitTest(tapPoint, options: nil) 
      if result.count == 0 { 
       return 
      } 
      let hitResult: SCNHitTestResult? = result.first 
      movedObject = hitResult?.node //.parent?.parent 
     } else if recognizer.state == .changed { 

      if (movedObject != nil) { 
       let tapPoint: CGPoint = recognizer.location(in: sceneView) 
       let hitResults = sceneView.hitTest(tapPoint, types: .featurePoint) 
       let result: ARHitTestResult? = hitResults.last 

       if result?.worldTransform != nil{ 

        let matrix: SCNMatrix4 = SCNMatrix4.init((result?.worldTransform)!) 
        let vector: SCNVector3 = SCNVector3Make(matrix.m41, matrix.m42, matrix.m43) 
        movedObject?.position = vector 

       } 

      } 
     } else if recognizer.state == .ended { 
      movedObject = nil 
     } 

} 

Répondre

3

Trouvé la solution! J'ai ajouté quelques explications dans les commentaires.

if (movedObject != nil) { 

    //Normalized-depth coordinate matching the plane I want 
    let projectedOrigin = sceneView.projectPoint((movedObject?.position)!) 

    //Location of the finger in the view on a 2D plane 
    let location2D = recognizer.location(in: sceneView) 

    //Location of the finger in a 3D vector 
    let location3D = SCNVector3Make(Float(location2D.x), Float(location2D.y), projectedOrigin.z) 

    //Unprojects a point from the 2D pixel coordinate system of the renderer to the 3D world coordinate system of the scene 
    let realLocation3D = sceneView.unprojectPoint(location3D) 

    if movedObject?.position != nil { 

     //Only updating Y axis position 
     movedObject?.position = SCNVector3Make((movedObject?.position.x)!, realLocation3D.y, (movedObject?.position.z)!) 
    } 

} 

messages qui aident à comprendre:

unProjectPoint & projectedOrigin

translation & unProjectPoint