
我正在创建一个全景视图,允许用户通过旋转智能手机环顾一下球形图像.我将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奇怪的行为所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)