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

swift – Scenekit:旋转并动画一个SCNNode,第1张

概述我试图显示一个指向z轴的金字塔,然后围绕z旋转. 当我的相机在z轴上时,我期待从上方看到金字塔.我设法旋转金字塔以这种方式看到,但是当我添加动画似乎在多轴上旋转时. 这是我的代码: // The following create the pyramid and place it how I want let pyramid = SCNPyramid(width: 1.0, height: 我试图显示一个指向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 directionpyramIDNode.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 zspin.fromValue = NSValue(SCNVector4: SCNVector4(x: 0,w: 0))spin.tovalue = NSValue(SCNVector4: SCNVector4(x: 0,w: CGfloat(2 * M_PI)))spin.duration = 3spin.repeatCount = .infinitypyramIDNode.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(或者您将传递该表达式的所有类型)转换为错误,从而使错误消失.当然,这将使您的代码无法读取和丑陋,所以一旦你开始工作,你可能会一次删除一个转换,直到找到一个这样的工作.

总结

以上是内存溢出为你收集整理的swift – Scenekit:旋转并动画一个SCNNode全部内容,希望文章能够帮你解决swift – Scenekit:旋转并动画一个SCNNode所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1028490.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存