其他分享
首页 > 其他分享> > android – Rajawali旋转相机与Sensor.TYPE_ROTATION_VECTOR奇怪的行为

android – Rajawali旋转相机与Sensor.TYPE_ROTATION_VECTOR奇怪的行为

作者:互联网

我正在创建一个全景视图,允许用户通过旋转智能手机环顾一下球形图像.我将Rajawali的Skybox与TYPE_ROTATION_VECTOR传感器一起使用.

我得到了它的工作,但只有当我向前看时(它实际上是基于我的旋转(偏航))

这是行为:

>期待:yaw = yaw,pitch = pitch and roll = roll
>向左看:yaw = yaw,pitch = roll and roll = pitch
>向后看:yaw = yaw,pitch = pitch * -1和roll = roll * -1.

现在我确实有预感正在发生什么.似乎“相机对象”一直看着相同的方向,即使它看起来不是这样.这意味着俯仰似乎与滚动相同,但是它仍然在俯仰,因为物体没有旋转.我把它比作飞机上的四处看看.

我需要做些什么来解决这个问题?

我有一种感觉,我将不得不用lookAt()旋转相机,但我不知道如何.

public class SkyboxFragment extends RajawaliFragment implements SensorEventListener {

    public static final String TAG = "SkyBoxFragment";
    private SensorManager mSensorManager;
    private float[] orientationVals = new float[3];
    private float[] mRotationMatrix = new float[16];
    private Sensor mRotVectSensor;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        LinearLayout ll = new LinearLayout(getActivity());
        ll.setOrientation(LinearLayout.VERTICAL);
        ll.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
        mSensorManager = (SensorManager) getActivity().getSystemService(
                Context.SENSOR_SERVICE);
        mRotVectSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
        mLayout.addView(ll);
        mSensorManager.registerListener(this,
                mRotVectSensor,
                10000);
        return mLayout;
    }

    @Override
    public AExampleRenderer createRenderer() {
        mRenderer = new SkyboxRenderer(getActivity());
        return ((SkyboxRenderer) mRenderer);
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
            SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
            SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, mRotationMatrix);
            SensorManager.getOrientation(mRotationMatrix, orientationVals);
            orientationVals[0] = (float) Math.toDegrees(orientationVals[0]);
            orientationVals[1] = (float) Math.toDegrees(orientationVals[1]) * -1;
            orientationVals[2] = (float) Math.toDegrees(orientationVals[2]) * -1;
            //Log.d(TAG,  "YAW:" + orientationVals[0] + " PITCH:" + orientationVals[1] + "ROLL:" + orientationVals[2]);
        }

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    private final class SkyboxRenderer extends AExampleRenderer implements View.OnClickListener {

        private final Vector3 mAccValues;
        boolean odd = true;

        public SkyboxRenderer(Context context) {
            super(context);
            mAccValues = new Vector3();
        }

        @Override
        protected void initScene() {
            getCurrentCamera().setFarPlane(1000);
            /**
             * Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se
             */
            try {
                getCurrentScene().setSkybox(R.drawable.posx, R.drawable.negx,
                        R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz);
            } catch (ATexture.TextureException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onRender(long ellapsedRealtime, double deltaTime) {
            super.onRender(ellapsedRealtime, deltaTime);
            getCurrentCamera().setRotation(orientationVals[2], orientationVals[0], orientationVals[1]);
        }

        @Override
        public void onClick(View v) {
            try {
                if (odd) {
                    /**
                     * Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se
                     */
                    getCurrentScene().updateSkybox(R.drawable.posx2, R.drawable.negx2,
                            R.drawable.posy2, R.drawable.negy2, R.drawable.posz2, R.drawable.negz2);
                } else {
                    /**
                     * Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se
                     */
                    getCurrentScene().updateSkybox(R.drawable.posx, R.drawable.negx,
                            R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                odd = !odd;
            }
        }

        public void setAccelerometerValues(float x, float y, float z) {
            mAccValues.setAll(-x, -y, -z);
        }
    }

}

解决方法:

你有两个问题.首先是您要描述的问题,但另一个问题是TYPE_ROTATION_VECTOR的传感器会受到附近磁铁的影响,例如手机外壳中的磁铁.

解决磁铁问题

解决方案可以是使用加速度计和陀螺仪的组合.幸运的是,Google Cardboard SDK已经将其抽象了.

您可以通过使用HeadTracker.createFromContext(this.getActivity())实例化com.google.vrtoolkit.cardboard.sensors.HeadTracker的实例并在其上调用startTracking()来跟踪当前轮换.

现在你不再需要onSensorChanged了.相反,在你的onRender中,你可以这样做:

float[] R = new float[16];
headTracker.getLastHeadView(R, 0);

获得旋转矩阵.这解决了您未说明的磁场问题.

让相机正确环顾四周

使用此旋转矩阵将摄像机指向正确方向的最简单方法是将其转换为org.rajawali3d.math.Quaternion,然后调用getCurrentCamera().setCameraOrientation(quaternion);

从float [16]到四元数的转换可能很难正确,但Google Cardboard SDK再一次为您做到了.在这种情况下,它位于不再使用的旧类的源代码中:HeadTransform.

您可以轻松地调整该代码以返回新的Quaternion(w,x,y,z);.

现在,如果没有将orientationVals [1]和orientationVals [2]乘以-1,则会产生与当前代码相同的问题.

然而,通过反转旋转矩阵可以很容易地解决该问题.这将导致onRender中的以下代码(假设getQuaternion(R)返回org.rajawali3d.math.Quaternion):

@Override
protected void onRender(long ellapsedRealtime, double deltaTime) {
    super.onRender(ellapsedRealtime, deltaTime);

    float[] R = new float[16];
    headTracker.getLastHeadView(R, 0);

    android.opengl.Matrix.invertM(R, 0, R, 0);

    Quaternion q = getQuaternion(R);

    getCurrentCamera().setCameraOrientation(q);
}

标签:android-sensors,android,opengl-es,rotation,rajawali
来源: https://codeday.me/bug/20190727/1555884.html