swift – Scenekit:旋转并动画一个SCNNode

前端之家收集整理的这篇文章主要介绍了swift – Scenekit:旋转并动画一个SCNNode前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图显示一个指向z轴的金字塔,然后围绕z旋转.
当我的相机在z轴上时,我期待从上方看到金字塔.我设法旋转金字塔以这种方式看到,但是当我添加动画似乎在多轴上旋转时.

这是我的代码

// The following create the pyramid and place it how I want
    let pyramid = SCNPyramid(width: 1.0,height: 1.0,length: 1.0)
    let pyramidNode = SCNNode(geometry: pyramid)
    pyramidNode.position = SCNVector3(x: 0,y: 0,z: 0)
    pyramidNode.rotation = SCNVector4(x: 1,z: 0,w: Float(M_PI / 2))
    scene.rootNode.addChildNode(pyramidNode)

    // But the animation seems to rotate aroun 2 axis and not just z
    var spin = CABasicAnimation(keyPath: "rotation")
    spin.byValue = NSValue(SCNVector4: SCNVector4(x: 0,z: 1,w: 2*Float(M_PI)))
    spin.duration = 3
    spin.repeatCount = HUGE
    pyramidNode.addAnimation(spin,forKey: "spin around")
尝试手动设置和动画相同的属性可能会导致问题.使用byValue动画使得问题更糟 – 连接到当前的变换,所以很难跟踪当前的变换是否是动画期望的开始.

相反,从动画(它绕着它指向的轴旋转)分离金字塔的固定方向(其顶点在-z方向).有两个好办法:

使金字塔节点获得一次旋转的另一个节点的子节点(绕x轴的π/ 2),并将旋转动画直接应用于pyramidNode. (在这种情况下,金字塔的顶点仍然指向其局部空间的y方向,因此您需要旋转该轴而不是z轴.)
>使用pivot属性来转换pyramidNode的内容的本地空间,并相对于其包含的空间生成pyramidNode.

以下是一些代码显示第二种方法

let pyramid = SCNPyramid(width: 1.0,length: 1.0)
let pyramidNode = SCNNode(geometry: pyramid)
pyramidNode.position = SCNVector3(x: 0,z: 0)
// Point the pyramid in the -z direction
pyramidNode.pivot = SCNMatrix4MakeRotation(CGFloat(M_PI_2),1,0)
scene.rootNode.addChildNode(pyramidNode)

let spin = CABasicAnimation(keyPath: "rotation")
// Use from-to to explicitly make a full rotation around z
spin.fromValue = NSValue(SCNVector4: SCNVector4(x: 0,w: 0))
spin.toValue = NSValue(SCNVector4: SCNVector4(x: 0,w: CGFloat(2 * M_PI)))
spin.duration = 3
spin.repeatCount = .infinity
pyramidNode.addAnimation(spin,forKey: "spin around")

一些不相​​关的更改提高代码质量:

>需要进行显式转换以初始化SCNVector组件时使用CGFloat;使用Float或Double专门将会破坏32或64位架构.
>使用.infinity代替传统的BSD数学常量HUGE.这种类型推断了任何类型的spin.repeatCount,并使用为所有浮点类型定义的常量值.
>使用M_PI_2作为π/ 2来精确度.
>为动画使用let而不是var,因为我们从不分配一个不同的值来旋转.

关于CGFloat错误业务的更多信息:在Swift中,数字文字没有类型,直到它们需要一个表达式.这就是为什么你可以做的事情,如spin.duration = 3 – 即使持续时间是一个浮点值,Swift允许你传递一个“整数文字”.但是如果你让d = 3; spin.duration = d你会收到一个错误.为什么?因为变量/常量有明确的类型,Swift不会进行隐式类型转换. 3是无类型的,但是当它分配给d时,类型推断默认为选择Int,因为您没有指定任何其他内容.

如果您看到类型转换错误,您可能有代码混合从函数返回的文字,常量和/或值.您可以通过将表达式中的所有内容转换为CGFloat(或者您将传递该表达式的所有类型)转换为错误,从而使错误消失.当然,这将使您的代码无法读取和丑陋,所以一旦你开始工作,你可能会一次删除一个转换,直到找到一个这样的工作.

原文链接:https://www.f2er.com/swift/318930.html

猜你在找的Swift相关文章