请帮助我正确应用设备旋转数据
Please help me correctly apply device rotation data
所以我有一些我正在尝试做的项目。我正在尝试让设备相对于重力旋转,并从它开始的地方进行平移。所以基本上是获取设备的 "tracking" 数据。我计划基本上通过制作一个 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)
}
当你只有 运行 一条旋转线时,一切都很完美。它确实在该轴上表现正常。但是,当我同时执行所有三个轴时,它会变得混乱并且性能与抖动和其他方面的预期相去甚远。
我想我的问题是:
有谁知道如何修复我上面的代码,以便无论方向如何,飞船都能正确地保持 "upright"。
J.Doe!
首先有一个小技巧。如果您想使用 iphone 放下作为默认位置,您必须注意 sceneKit 上使用的轴与 DeviceMotion 使用的轴不同。检查轴:
(来源:apple.com)
首先需要设置的是相机位置。当您启动 SceneKit 项目时,它会在位置 (0, 0, 15) 处创建您的相机。有一个问题:
eulerAngles = (0,0,0) 的值意味着该对象将在平面 xz 中,但只要您从 Z 方向看,您只是从侧面看到它。要使其等同于 iphone 躺下,您需要将相机设置为从上方看。所以就像你从 phone(像相机,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
这样我们就可以从上面看到这艘船了,所以第一部分就完成了。
现在我们要让飞船随着设备的旋转保持"still"(面向地面)。
//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轴是"switched"。 Z在phone上,而在场景的侧面,Y在场景上,在phone的侧面。因此,分别与 X、Y 和 Z 轴关联的俯仰、滚动和偏航将应用为俯仰、偏航和滚动。
注意我将滚动值设置为正数,那是因为还有其他东西 "switched"。这有点难以想象。看到设备运动的 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);
}
希望对您有所帮助!再见!
所以我有一些我正在尝试做的项目。我正在尝试让设备相对于重力旋转,并从它开始的地方进行平移。所以基本上是获取设备的 "tracking" 数据。我计划基本上通过制作一个 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)
}
当你只有 运行 一条旋转线时,一切都很完美。它确实在该轴上表现正常。但是,当我同时执行所有三个轴时,它会变得混乱并且性能与抖动和其他方面的预期相去甚远。
我想我的问题是: 有谁知道如何修复我上面的代码,以便无论方向如何,飞船都能正确地保持 "upright"。
J.Doe!
首先有一个小技巧。如果您想使用 iphone 放下作为默认位置,您必须注意 sceneKit 上使用的轴与 DeviceMotion 使用的轴不同。检查轴:
(来源:apple.com)
首先需要设置的是相机位置。当您启动 SceneKit 项目时,它会在位置 (0, 0, 15) 处创建您的相机。有一个问题:
eulerAngles = (0,0,0) 的值意味着该对象将在平面 xz 中,但只要您从 Z 方向看,您只是从侧面看到它。要使其等同于 iphone 躺下,您需要将相机设置为从上方看。所以就像你从 phone(像相机,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
这样我们就可以从上面看到这艘船了,所以第一部分就完成了。 现在我们要让飞船随着设备的旋转保持"still"(面向地面)。
//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轴是"switched"。 Z在phone上,而在场景的侧面,Y在场景上,在phone的侧面。因此,分别与 X、Y 和 Z 轴关联的俯仰、滚动和偏航将应用为俯仰、偏航和滚动。
注意我将滚动值设置为正数,那是因为还有其他东西 "switched"。这有点难以想象。看到设备运动的 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);
}
希望对您有所帮助!再见!