5

所以我有一个我正在尝试做的项目。我试图让设备相对于重力旋转,并从它开始的地方平移。所以基本上得到设备的“跟踪”数据。我计划通过制作一个 3d pt 来应用这一点,该 pt 将模仿我稍后从设备记录的数据。

无论如何,为了实现这一点,我认为最好使用场景工具包,这样我就可以看到 3 维的东西,就像我试图记录的数据一样。现在,我一直在尝试让船旋转,以便无论设备旋转是什么,它总是看起来像它的重力(就像它在地面上或其他东西上)。我想一旦我把它记下来,把它应用到一个点上会很容易。所以我做了以下代码:

if let attitude = motionManager.deviceMotion?.attitude {
        print(attitude)


        ship.eulerAngles.y = -Float(attitude.roll)
        ship.eulerAngles.z = -Float(attitude.yaw)
        ship.eulerAngles.x = -Float(attitude.pitch)

    }

当您只运行其中一条旋转线时,一切都很完美。它确实在该轴上正常运行。但是,当我同时做所有三个轴时,它会变得混乱,并且在抖动和所有事情上都表现得远远超出预期。

我想我的问题是:有谁知道如何修复我上面的代码,以便无论方向如何,船都能正确保持“直立”。

4

1 回答 1

12

J.Doe!

首先有一个小技巧。如果您想使用放下的 iphone 作为默认位置,您必须注意 sceneKit 上使用的轴与 DeviceMotion 使用的轴不同。检查轴:

设备运动轴 场景套件轴
(来源:apple.com

您需要设置的第一件事是相机位置。当您启动 SceneKit 项目时,它会在 (0, 0, 15) 位置创建您的相机。这样做有一个问题:

eulerAngles = (0,0,0) 的值意味着对象将在平面 xz 中,但只要您从 Z 方向看,您就只能从侧面看到它。为了相当于放下 iphone,您需要将相机设置为从上方看。所以这就像你在手机上看它(就像一个相机,idk)

// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)

// place the camera
cameraNode.position = SCNVector3(x: 0, y: 15, z: 0)
// but then you need to make the cameraNode face the ship (the origin of the axis), rotating it
cameraNode.eulerAngles.x = -Float(M_PI)*0.5 //or Float(M_PI)*1.5

有了这个,我们将从上面看到船,所以第一部分完成了。现在我们必须让船在设备旋转时保持“静止”(面向地面)。

//First we need to use SCNRendererDelegate
class GameViewController : UIViewController SCNSceneRendererDelegate{
    private let motion = CMMotionManager();
...

然后在 viewDidLoad 上:

//important if you remove the sceneKit initial action from the ship.
//The scene would be static, and static scenes do not trigger the renderer update, setting the playing property to true forces that:
scnView.playing = true;
if(motion.deviceMotionAvailable){
    motion.startDeviceMotionUpdates();
    motion.deviceMotionUpdateInterval = 1.0/60.0;
}

然后我们去更新方法

查看轴:如果您比较 sceneKit 轴和 deviceMotion 轴,则 Y 轴和 Z 轴是“切换的”。Z在电话上,而在现场的一侧,Y在现场,而在电话的一侧。因此,分别与 X、Y 和 Z 轴相关联的俯仰、滚动和偏航将应用为俯仰、偏航和滚动。

请注意,我将滚动值设为正值,这是因为还有其他东西“切换”了。有点难以想象。看到设备运动的 Y 轴与场景的 Z 轴相关。现在想象一个物体沿着这个轴旋转,在相同的方向(例如顺时针方向),由于轴的布置,它们会朝相反的方向移动。(您也可以将滚动设置为负值,看看它是如何出错的)

func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
    if let rot = motion.deviceMotion?.attitude{
        print("\(rot.pitch) \(rot.roll) \(rot.yaw)")
        ship.eulerAngles.x = -Float(rot.pitch);
        ship.eulerAngles.y = -Float(rot.yaw);
        ship.eulerAngles.z = Float(rot.roll);
    }

希望有帮助!再见!

于 2015-10-23T01:58:18.650 回答