请帮助我正确应用设备旋转数据 [英] Please help me correctly apply device rotation data

查看:43
本文介绍了请帮助我正确应用设备旋转数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I have a bit of a project I am trying to do. I am trying to get the devices rotation relative to gravity, and translation from where it started. So basically getting "tracking" data for the device. I plan to basically apply this by making a 3d pt that will mimic the data I record from the device later on.

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

Anyway to attempt to achieve this I thought it would be best to work with scene kit that way I can see things in 3 dimensions just like the data I am trying to record. Right now I have been trying to get the ship to rotate so that it always looks like its following gravity (like its on the ground or something) no mater what the device rotation is. I figure once I have this down it will be a sinch to apply this to a point. So I made the following code:

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)

    }

当您只运行一条旋转线时,一切都完美无缺.它确实在那个轴上表现得很好.但是,当我同时进行所有三个轴的操作时,它会变得混乱,并且在抖动和所有情况下的表现都远非预期.

When you only run one of the rotation lines then everything is perfectly. It does behave properly on that axis. However when I do all three axis' at once it becomes chaotic and performs far from expected with jitter and everything.

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

I guess my question is: Does anyone know how to fix my code above so that the ship properly stays "upright" no matter what the orientation.

推荐答案

J.Doe!

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

First there is a slight trick. If you want to use the iphone laying down as the default position you have to notice that the axis used on sceneKit are different then those used by the DeviceMotion. Check the axis:


(来源:apple.com)

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

First thing you need to set is the camera position. When you start a SceneKit project it creates your camera in the position (0, 0, 15). There is a problem with that:

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

The values of eulerAngles = (0,0,0) would mean the object would be in the plane xz, but as long as you are looking from Z, you just see it from the side. For that to be equivalent to the iphone laying down, you would need to set the camera to look from above. So it would be like you were looking at it from the phone (like a camera, 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

这样我们就可以从上面看到这艘船了,所以第一部分就完成了.现在我们必须通过设备旋转使船保持静止"(面向地面).

With this we are going to see the ship from above, so the first part is done. Now we gotta make the ship remain "still" (facing the ground) with the device rotation.

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

然后在 viewDidLoad 上:

Then on 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 轴相关联的俯仰、滚转和偏航将被应用为俯仰、偏航和滚转.

Look at the axis: the axis Y and Z are "switched" if you compare the sceneKit axis and the deviceMotion axis. Z is up on the phone, while is to the side on the scene, and Y is up on the scene, while to the side on the phone. So the pitch, roll and yaw, respectively associated to the X, Y and Z axis, will be applied as pitch, yaw and roll.

请注意,我已将滚动值设为正值,这是因为还有其他内容切换"了.有点难以想象.请参阅设备运动的 Y 轴与场景的 Z 轴相关.现在想象一个物体沿着这个轴旋转,在相同的方向(例如顺时针),由于轴的布置,它们将朝着相反的方向前进.(你也可以设置滚动负数,看看它是怎么出错的)

Notice I've put the roll value positive, that's because there is something else "switched". It's kinda hard to visualize. See the Y axis of device motion is correlated to the Z axis of the scene. Now imagine an object rotation along this axis, in the same direction (clock-wise for example), they would be going in opposite directions because of the disposition of the axis. (you can set the roll negative too see how it goes wrong)

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);
    }

希望有帮助!见!

这篇关于请帮助我正确应用设备旋转数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆