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

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

概述我正在创建一个全景视图,允许用户通过旋转智能手机环顾一下球形图像.我将Rajawali的Skybox与TYPE_ROTATION_VECTOR传感器一起使用.我得到了它的工作,但只有当我向前看时(它实际上是基于我的旋转(偏航))这是行为:>期待:yaw=yaw,pitch=pitchandroll=roll>向左看:yaw=yaw,p

我正在创建一个全景视图,允许用户通过旋转智能手机环顾一下球形图像.我将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):

@OverrIDeprotected 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 – Rajawali旋转相机与Sensor.TYPE_ROTATION_VECTOR奇怪的行为全部内容,希望文章能够帮你解决android – Rajawali旋转相机与Sensor.TYPE_ROTATION_VECTOR奇怪的行为所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1113573.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存