我得到了它的工作,但只有当我向前看时(它实际上是基于我的旋转(偏航))
这是行为:
>期待: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.negz); } } catch (Exception e) { e.printstacktrace(); } finally { odd = !odd; } } public void setAccelerometerValues(float x,float y,float z) { mAccValues.setAll(-x,-y,-z); } } }
解决方法
解决磁铁问题
解决方案可以是使用加速度计和陀螺仪的组合.幸运的是,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,R,0); Quaternion q = getQuaternion(R); getCurrentCamera().setCameraOrientation(q); }