ユーザーがスマートフォンを回転させて球状の画像を見回すことができるパノラマ ビューを作成しています。これには、Rajawali の Skybox と TYPE_ROTATION_VECTOR センサーを使用しました。
私はそれを機能させましたが、私が前を見ているときだけです(それは文字通り私の回転(ヨー)に基づいています)
これは動作です:
- 楽しみ: ヨー = ヨー、ピッチ = ピッチ、ロール = ロール
- 左を見て: ヨー = ヨー、ピッチ = ロール、ロール = ピッチ
- 後ろから見ると、ヨー = ヨー、ピッチ = ピッチ * -1、ロール = ロール * -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);
}
}
}