scenekit节点的旋转和3D空间中的移动
假设我们有一个SCNNode
,我们想要旋转,改变飞行方向并在空间中移动而没有重力。节点当前只是一个相机。实际上它应该对陀螺仪加速度计数据作出反应。我认为场景更新可以在- (void)renderer:(id <SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time
完成。scenekit节点的旋转和3D空间中的移动
我面临的问题是如何利用陀螺仪&加速度计数据计算飞行方向,以及如何计算旋转方向&移动。我刷新了关于每个轴(x,y,z)的3D旋转矩阵的记忆,但仍然缺少上述提到的部分来解决这个问题。可能会觉得非常复杂,解决方案非常简单。
- (void)viewDidLoad
{
SCNView *scnView = (SCNView *) self.view;
SCNScene *scene = [SCNScene scene];
scnView.scene = scene;
_cameraNode = [[SCNNode alloc] init];
_cameraNode.camera = [SCNCamera camera];
_cameraNode.camera.zFar = 500;
_cameraNode.position = SCNVector3Make(0, 60, 50);
_cameraNode.rotation = SCNVector4Make(1, 0, 0, -M_PI_4*0.75);
[scene.rootNode addChildNode:_cameraNode];
scnView.pointOfView = _cameraNode;
[self setupAccelerometer];
}
- (void)setupAccelerometer
{
_motionManager = [[CMMotionManager alloc] init];
GameViewController * __weak weakSelf = self;
if ([[GCController controllers] count] == 0 && [_motionManager isAccelerometerAvailable] == YES) {
[_motionManager setAccelerometerUpdateInterval:1/60.0];
[_motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
[weakSelf accelerometerDidChange:accelerometerData.acceleration];
}];
}
}
- (void)accelerometerDidChange:(CMAcceleration)acceleration
{
//acceleration.x
//acceleration.y
//acceleration.z
// now we have the data and saved somewhere
}
如果你想陀螺仪和加速度计的数据结合起来,得到一个方向,你可能会更好,让CoreMotion为你做的。在文档Managing Device Motion Updates下列出的方法得到您CMDeviceMotion
对象;从其中一个可以获得表示方向的CMAttitude
,并从中可以获得可应用于场景中节点的旋转矩阵或四元数。 (可能在进一步转换后,以便以您想要的方式适合您场景的中性方向)。
按照您希望的方式定向节点后,从中获取飞行方向应该非常简单:
根据节点的局部坐标空间选择飞行方向并制作一个指向该方向的矢量;例如一个摄像头看着它的节点的-z方向,所以如果你想让相机节点沿着它的飞行路径看,你将使用一个像{0,0,-1}这样的向量。
使用
convertPosition:toNode:
和场景rootNode
将该矢量转换为场景空间。这可以根据场景获得飞行方向,并将节点的方向考虑在内。使用转换后的矢量移动节点,可以通过将节点分配为节点物理体的速度,或通过使用它来创建一个新位置并使用动作或动画移动节点。
谢谢你的清楚解释。当然,我需要进一步阅读尝试。 – 2014-12-07 11:42:35
只是想让你知道我到目前为止使用四元数旋转相机。它需要一些稳定,然后我会尝试解决与飞行方向和距离的部分。 – 2014-12-09 07:10:33