场景包节点在3D空间中的旋转和移动

时间:2014-12-05 08:43:53

标签: ios 3d scenekit

假设我们有一个SCNNode我们想要旋转,改变飞行方向并在没有重力的情况下在太空中移动。节点目前只是一个摄像头。实际上它应该对陀螺仪加速度计数据做出反应。我认为场景更新可以在- (void)renderer:(id <SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time

中完成

我面临的问题是如何使用陀螺仪和放大器。用于计算飞行方向的加速度计数据,以及如何计算旋转方向和运动。我更新了关于每个轴(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

}

1 个答案:

答案 0 :(得分:3)

如果你想结合陀螺仪和加速度计数据来获得方向,你可能最好让CoreMotion为你做这件事。文档中Managing Device Motion Updates下列出的方法可以获得CMDeviceMotion个对象;从其中一个中可以得到一个表示方向的CMAttitude,从中可以得到一个可以应用于场景中节点的旋转矩阵或四元数。 (可能在进一步转换之后,中性方向以您想要的方式适合您的场景。)

在按照自己的方式定位节点后,从中获取飞行方向应该非常简单:

  1. 根据节点的局部坐标空间选择一个飞行方向,并制作一个指向该方向的矢量;例如相机在其节点的-z方向上查看,因此如果您希望相机节点沿其飞行路径查看,您将使用像{0,0,-1}这样的向量。

  2. 使用convertPosition:toNode:和场景rootNode将该矢量转换为场景空间。这将根据场景获取飞行方向,并考虑节点的方向。

  3. 使用转换后的矢量移动节点,方法是将其指定为节点物理体的速度,或者使用它来提出新位置并使用动作或动画移动节点。 / p>