簡體   English   中英

SceneKit - 向通過平移手勢旋轉的球體添加漂移

[英]SceneKit - Adding drift to a sphere rotated via a pan gesture

我正在使用SceneKit並允許用戶使用平移手勢旋轉他們在球體內看到的內容。 這很好 - 除了我想讓球體在搖攝手勢的方向上保持稍微旋轉,感覺有點反應。

這是我對場景的設置:

    // Create scene
    let scene = SCNScene()

    sceneView.scene = scene

    let panRecognizer = UIPanGestureRecognizer(target: self,
                                               action: #selector(ViewController.handlePanGesture(_:)))

    sceneView.addGestureRecognizer(panRecognizer)

    //Create sphere
    let sphere = SCNSphere(radius: 50.0)

    // sphere setup

    sphereNode = SCNNode(geometry: sphere)

    sphereNode!.position = SCNVector3Make(0,0,0)
    scene.rootNode.addChildNode(sphereNode!)

    // Create camera
    let camera = SCNCamera()

    // camera setup

    cameraNode = SCNNode()

    cameraNode!.camera = camera
    cameraNode!.position = SCNVector3Make(0, 0, 0)

    cameraOrbit = SCNNode()

    cameraOrbit!.addChildNode(cameraNode!)
    scene.rootNode.addChildNode(cameraOrbit!)

    let lookAtConstraint = SCNLookAtConstraint(target: sphereNode!)
    lookAtConstraint.gimbalLockEnabled = true
    cameraNode!.constraints = [lookAtConstraint]

    sceneView.pointOfView = cameraNode

以下是當前處理平移手勢的方式(由SCNCamera限制弧形旋轉提供 ):

    let translation = sender.translationInView(sender.view!)
    let widthRatio = Float(translation.x) / Float(sender.view!.frame.size.width) + lastWidthRatio
    let heightRatio = Float(translation.y) / Float(sender.view!.frame.size.height) + lastHeightRatio

    self.cameraOrbit?.eulerAngles.y = Float(-2 * M_PI) * widthRatio
    self.cameraOrbit?.eulerAngles.x = Float(-M_PI) * heightRatio

    if (sender.state == .Ended) {
        lastWidthRatio = widthRatio
        lastHeightRatio = heightRatio
    }

我不知道從哪里開始添加一個輕微的持續旋轉運動。 也許添加一個physicsBody並使用force? 也許激活eulerAngles的變化?

我以前處理這樣的事情的方式是將手勢處理程序分成手勢狀態開始,更改和結束的部分。 如果旋轉對您if (sender.state == .Ended)您只需將代碼添加到if (sender.state == .Ended)語句的底部。

lastHeightRatio = heightRatio您可以使用sender.velocityInView(sender.view!)在視圖中找到平移的速度,然后像以前一樣找到水平分量,然后添加SCNAction以使用EaseOut計時模式旋轉節點。

您可能需要一個乘數來將視圖中的速度(以點為單位)轉換為您希望旋轉的角度(以弧度為單位)。 10點的速度相對較小,將導致非常快的旋轉。

此外,如果您想要觸摸來停止剩余旋轉,則需要在手勢再次開始時從節點中刪除所有操作。

一些樣本代碼將是:

if (sender.state == .Ended) {
  lastWidthRatio = widthRatio
  lastHeightRatio = heightRatio

  // Find velocity
  let velocity = sender.velocityInView(sender.view!)

  // Create Action for whichever axis is the correct one to rotate about.
  // The 0.00001 is just a factor to provide the rotation speed to pan
  // speed ratio you'd like. Play with this number and the duration to get the result you want
  let rotate = SCNAction.rotateByX(velocity.x * 0.00001, y: 0, z: 0, duration: 2.0)

  // Run the action on the camera orbit node (if I understand your setup correctly)
  cameraOrbit.runAction(rotate)
}

這應該足以讓你入門。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM