[英]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.