標籤:
旋轉模型是經常遇到了,我們之前用CABasicAnimation 可以旋轉一個view,其實它也可以旋轉一個SCNNode。
首先我們要明白一個概念,每個SCNNode 都有自身的三維座標系,用CABasicAnimation就是讓SCNNode繞自身的立體牆和底板旋轉,所以要特別注意是座標軸,不是這個SCNNode的幾何中心。一般SceneKit 的內建的幾個幾何體的座標系原點(0,0,0)就是這個它的幾何中心,比如說SCNBox;SCNSphere等等,所以看上去跟繞幾何中心旋轉一模一樣。
我們先從Demo 入手,這裡是類比 太陽-地球-月球 天體運動的demo,分以下幾點:
1, 地球,月球自轉
2, 月球繞著地球轉
3, 地月系統繞著太陽轉
如:
第一點 先實現地球,月球自轉
// Rotate the moon animation = [CABasicAnimation animationWithKeyPath:@"rotation"]; animation.duration = 1.5; animation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)]; animation.repeatCount = FLT_MAX; [_moonNode addAnimation:animation forKey:@"moon rotation"];
其實SceneKit 架構有自己的動畫API ,我們這裡地球的旋轉用它,讓大家瞭解一下
[_earthNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]]; //地球自轉
從上面的代碼可以看出來都是繞Y軸旋轉。
第二點 月球繞著地球轉(父子SCNNode技巧)
月球需要繞著地球的Y軸旋轉,我們知道,只有地球才繞自己的Y軸旋轉。所以我們可以讓地球帶著月球繞自己的Y軸旋轉。很簡單,將月球add 到地球上:
[_earthNode addChildNode:_moonNode];
這是就會實現月球繞著地球轉的效果。
但現實中,地球的自轉周期跟月球的公轉周期是不一樣的。所以月球不能添加到地球這個SCNNode 上,我們要重新建立一個SCNNode,位置跟地球一樣,把_moonNode添加到這個建立的SCNNode上,然後旋轉它。
_moonNode.position = SCNVector3Make(3, 0, 0); // Moon-rotation (center of rotation of the Moon around the Earth) SCNNode *moonRotationNode = [SCNNode node]; [moonRotationNode addChildNode:_moonNode]; // Rotate the moon around the Earth CABasicAnimation *moonRotationAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"]; moonRotationAnimation.duration = 1.5; moonRotationAnimation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)]; moonRotationAnimation.repeatCount = FLT_MAX; [moonRotationNode addAnimation:animation forKey:@"moon rotation around earth"];
第三點 地月系統繞著太陽轉
這個時候地球和月球要繞著太陽轉,可以把地月系統看成一個整體。我們建立一個地月系統earthGroupNode,然後將moonRotationNode 和 earthNode 添加進去:
[_earthGroupNode addChildNode:_earthNode]; [_earthGroupNode addChildNode:moonRotationNode];
太陽不自轉,同理,在太陽同樣的位置建立一個SCNNode,讓地月系統earthGroupNode隨著這個節點旋轉
//離太陽的距離 _earthGroupNode.position = SCNVector3Make(10, 0, 0);
// Earth-rotation (center of rotation of the Earth around the Sun) SCNNode *earthRotationNode = [SCNNode node]; [_sunNode addChildNode:earthRotationNode]; // Earth-group (will contain the Earth, and the Moon) [earthRotationNode addChildNode:_earthGroupNode]; // Rotate the Earth around the Sun CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"rotation"]; animation.duration = 10.0; animation.toValue = [NSValue valueWithSCNVector4:SCNVector4Make(0, 1, 0, M_PI * 2)]; animation.repeatCount = FLT_MAX; [earthRotationNode addAnimation:animation forKey:@"earth rotation around sun"];
然後大體流程就結束了。然後我們可以給太陽貼圖添加一些動畫,讓他有岩漿的效果,在加一些光效,整體就更真實了。
整體效果如下:
demo 代碼已上傳到github
https://github.com/pzhtpf/SceneKitRoationDemo
拋磚引玉,關於旋轉持續完善中……
ios 3D引擎 SceneKit 開發(4) --關於旋轉的幾點問題(1)