1
Support / [Tips] How to use the orientation sensors to set the JPCT camera to corrispond
« on: August 30, 2010, 08:07:27 pm »
Hello,
after a lot of trial & errors, I was able to use the orientation sensors to set the JPCT camera to correspond to the device movements.
This technique use Camera.setBack method, and it seems to work very well.
The solution comes from this interesting article: http://stackoverflow.com/questions/2881128/how-to-use-onsensorchanged-sensor-data-in-combination-with-opengl
The article is about how to use sensors directly with OpenGL API, so I had to adapt it in order to make it work with jPCT.
First of all, you must get the sensors' values:
I omitted all the code needed to register the SensorManager listeners, because it isn't nothing new respect to the standard.
Note the use of the rootMeanSquareBuffer() function to smooth the device movement.
It's mandatory to obtain an 'stable' camera movement.
After that, in the onDrawFrame, you can use the rotationMatrix calculated in the previous step:
As you can read in the code above, this solution doesn't work when the screen is set in portrait mode, so you must insert the following declaration in the manifest file:
Who is able to find the solution working also in portrait mode is invited to participate to the discussion
Please note that the coordinate system will be that one returned by SensorManager.getRotationMatrix method, as described in the Android API documentation:
(See attached figure)
Take it in account when you move your objects in the scene.
Hope this will help someone
Paolo
P.S.: please forgive the grammatical errors coming from an Italian mother tongue
[attachment deleted by admin]
after a lot of trial & errors, I was able to use the orientation sensors to set the JPCT camera to correspond to the device movements.
This technique use Camera.setBack method, and it seems to work very well.
The solution comes from this interesting article: http://stackoverflow.com/questions/2881128/how-to-use-onsensorchanged-sensor-data-in-combination-with-opengl
The article is about how to use sensors directly with OpenGL API, so I had to adapt it in order to make it work with jPCT.
First of all, you must get the sensors' values:
Code: [Select]
public void onSensorChanged(SensorEvent event) {
final int type = event.sensor.getType();
if (type == Sensor.TYPE_ACCELEROMETER) {
accelGData = event.values.clone();
}
if (type == Sensor.TYPE_MAGNETIC_FIELD) {
magnetData = event.values.clone();
}
if (type == Sensor.TYPE_ORIENTATION) {
orientationData = event.values.clone();
}
rootMeanSquareBuffer(bufferedAccelGData, accelGData);
rootMeanSquareBuffer(bufferedMagnetData, magnetData);
SensorManager.getRotationMatrix(rotationMatrix, null,
bufferedAccelGData, bufferedMagnetData);
}
I omitted all the code needed to register the SensorManager listeners, because it isn't nothing new respect to the standard.
Note the use of the rootMeanSquareBuffer() function to smooth the device movement.
It's mandatory to obtain an 'stable' camera movement.
After that, in the onDrawFrame, you can use the rotationMatrix calculated in the previous step:
Code: [Select]
public void onDrawFrame(GL10 gl) {
Camera cam = world.getCamera();
if (landscape) {
// in landscape mode first remap the
// rotationMatrix before using
// it with camera.setBack:
float[] result = new float[9];
SensorManager.remapCoordinateSystem(
rotationMatrix, SensorManager.AXIS_MINUS_Y,
SensorManager.AXIS_MINUS_X, result);
com.threed.jpct.Matrix mResult = new com.threed.jpct.Matrix();
copyMatrix(result, mResult);
cam.setBack(mResult);
} else {
// WARNING: This solution doesn't work in portrait mode
// See the explanation below
}
// ... Draw here your own 3D world
fb.clear();
world.renderScene(fb);
world.draw(fb);
blitNumber(lfps, 5, 5);
fb.display();
}
private void copyMatrix(float[] src, com.threed.jpct.Matrix dest) {
dest.setRow(0, src[0], src[1], src[2], 0);
dest.setRow(1, src[3], src[4], src[5], 0);
dest.setRow(2, src[6], src[7], src[8], 0);
dest.setRow(3, 0f, 0f, 0f, 1f);
}
As you can read in the code above, this solution doesn't work when the screen is set in portrait mode, so you must insert the following declaration in the manifest file:
Code: [Select]
<activity android:name=".myActivity" ...
android:screenOrientation="landscape">
...
</activity>
Who is able to find the solution working also in portrait mode is invited to participate to the discussion
Please note that the coordinate system will be that one returned by SensorManager.getRotationMatrix method, as described in the Android API documentation:
Quote
- X is defined as the vector product Y.Z (It is tangential to the ground at the device's current location and roughly points East).
- Y is tangential to the ground at the device's current location and points towards the magnetic North Pole.
- Z points towards the sky and is perpendicular to the ground.
(See attached figure)
Take it in account when you move your objects in the scene.
Hope this will help someone
Paolo
P.S.: please forgive the grammatical errors coming from an Italian mother tongue
[attachment deleted by admin]