如何使用 Android 指南针方向来瞄准 opengl 相机? [英] How do I use the Android compass orientation to aim an opengl camera?

查看:21
本文介绍了如何使用 Android 指南针方向来瞄准 opengl 相机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 libgdx 为 android 开发一个基本的 3d 游戏,并且在给定从指南针提供的三个旋转角度(方位角 - 围绕 Z 的旋转,滚动 - 围绕 Y 的旋转,俯仰 - 旋转)的情况下,我很难正确定位相机关于 X).我在下面的代码中取得了一些小小的成功,因为我可以按照我的预期正确地将虚拟相机对准 Z 轴和 X 轴.(角度以度为单位 [-180,180])

I'm using libgdx to develop a basic 3d game for android and I'm having difficulty properly orienting the camera given three rotation angles provided from the compass (azimuth - rotation about Z, roll - rotation about Y, pitch - rotation about X). I've had some slight success with the following code in that I can properly aim the virtual camera down the Z-axis and X-axis as I expected. (Angles are in degrees [-180,180])

camera.direction.x = 0;
camera.direction.y = 0;
camera.direction.z = 1;
camera.up.x = -1;
camera.up.y = 0;
camera.up.z = 0;

camera.rotate(azimuth,0,0,1);
camera.rotate(roll,0,1,0);
camera.rotate(pitch,1,0,0);

我在这方面也取得了一些成功,但它并没有定位相机的向上矢量.(此版本中角度已转换为弧度)

I've also had some success with this, but it does not orient the camera's up-vector. (Angles have been converted to radians in this version)

float x,y,z;
roll = (float) (roll + Math.PI/2.0);
x = (float) (Math.cos(azimuth) * Math.cos(roll));
y = (float) (Math.sin(azimuth) * Math.cos(roll));
z = (float) (Math.sin(roll));
Vector3 lookat = new Vector3(x,y,z);
camera.lookAt(lookat.x, lookat.y, lookat.z);

有人能解释一下如何从这三个角度正确定位虚拟相机吗?

Can someone shed some light on how to properly orient the virtual camera from these three angles?

另外,我试图让手机处于横向模式,这样手机的顶部在左侧,底部在右侧.因此,相机的默认方向(所有旋转都在 0,手机顶部指向北方)是相机朝向地面(正 Z),向上朝向东方(负 X).

Also, I'm trying to have the phone be in landscape mode such that the top of the phone is to the left and the bottom is to the right. Hence the camera's default direction (all rotations are at 0, top of the phone is aimed north) be the camera aiming toward the ground (positive Z) with the up aiming east (negative X).

推荐答案

通过编码其他东西一段时间,我最终达到了尝试分离渲染、模拟和输入的地步.因此,我想出了以下适合我的解决方案.我没有严格测试它,但它似乎做了我想要的(忽略相机胶卷).

By coding other things for a while, I eventually reached a point where I was trying to separate the rendering, simulation, and input. Because of that I have come up with the following solution that works for me. I haven't tested it rigorously, but it appears to do what I want (ignoring camera roll).

在程序的 android 部分,我需要将方向设置为横向模式:

On the android part of the program, I needed to set the orientation to landscape mode:

<activity android:name=".MySuperAwesomeApplication"
              android:label="@string/app_name"
              android:screenOrientation="landscape">
              >

我创建了一个玩家类来存储偏航、俯仰、滚动和位置

I created a player class to store yaw, pitch, roll, and position

public class Player {
    public final Vector3 position = new Vector3(0,1.5f,0);    
    /** Angle left or right of the vertical */
    public float yaw = 0.0f;
    /** Angle above or below the horizon */
    public float pitch = 0.0f;
    /** Angle about the direction as defined by yaw and pitch */
    public float roll = 0.0f;
}

然后当我根据输入更新播放器时,我会执行以下操作:

And then when I update the player based on input I do the following:

player.yaw = -Gdx.input.getAzimuth();
player.pitch = -Gdx.input.getRoll()-90;
player.roll = -Gdx.input.getPitch();

注意,pitch 映射到 input.roll,roll 映射到 input.pitch.不知道为什么,但它对我有用.最后更新相机:

Note that pitch maps to input.roll and roll maps to input.pitch. Not sure why, but it works for me. Finally update the camera:

camera.direction.x = 0;
camera.direction.y = 0;
camera.direction.z = 1;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 0;
camera.update();

// The world up vector is <0,1,0>
camera.rotate(player.yaw,0,1,0);
Vector3 pivot = camera.direction.cpy().crs(camera.up);
camera.rotate(player.pitch, pivot.x,pivot.y,pivot.z);
camera.rotate(player.roll, camera.direction.x, camera.direction.y, camera.direction.z);
camera.translate(player.position.x, player.position.y, player.position.z);
camera.update();

在代码中添加了相机胶卷.对于我和我的 Droid 2,roll 似乎只有 [-90,90] 中的值,因此如果您旋转超过 -90 或 90,则值开始变回 0.

added camera roll to the code. For me and my Droid 2, roll appears to only have values in [-90,90] such that if you rotate past -90 or 90 the values start changing back towards 0.

这篇关于如何使用 Android 指南针方向来瞄准 opengl 相机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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