使用SensorManager在OpenGL中旋转?
我正在构建一个非常标准的 AR 应用程序,它会覆盖相机上的内容,但在使用 SensorManager 时遇到问题。我基本上试图从传感器管理器获取旋转矩阵,然后调用 glMultMatrix 相应地旋转所有内容。在 SensorManager.getRotationMatrix 的文档中看起来这是可能的。然而,当我与旋转矩阵相乘时,一切都会变得扭曲并且四处移动,这与您在其他 AR 应用程序中所期望的不同。我得到了下面的一些代码:
private float[] gravity = new float[3];
private float[] geomagnetic = new float[3];
private float filteringFactor = 0.01f;
private float[] rotationMatrixOut = new float[16];
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic[0] = event.values[0] * filteringFactor + geomagnetic[0] * (1.0f - filteringFactor);
geomagnetic[1] = event.values[1] * filteringFactor + geomagnetic[1] * (1.0f - filteringFactor);
geomagnetic[2] = event.values[2] * filteringFactor + geomagnetic[2] * (1.0f - filteringFactor);
} else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity[0] = event.values[0] * filteringFactor + gravity[0] * (1.0f - filteringFactor);
gravity[1] = event.values[1] * filteringFactor + gravity[1] * (1.0f - filteringFactor);
gravity[2] = event.values[2] * filteringFactor + gravity[2] * (1.0f - filteringFactor);
}
SensorManager.getRotationMatrix(rotationMatrixOut, null, gravity, geomagnetic);
}
我也尝试过使用 SensorManager.remapCooperativeSystem 但没有运气。我的绘图代码如下,这是非常标准的东西,我注释掉了,因为我不确定这是否造成了麻烦,
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//GLU.gluLookAt(gl, mCamera.position.x, mCamera.position.y, mCamera.position.z,
// mCamera.target.x, mCamera.target.y, mCamera.target.z,
// mCamera.up.x, mCamera.up.y, mCamera.up.z);
gl.glMultMatrixf(rotationMatrixOut, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glLineWidth(1.0f);
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glDrawArrays(GL10.GL_LINES, 0, 2 * 201 * 2);
如果有人可以提供帮助,我将不胜感激。 谢谢
I'm building a pretty standard AR app that overlays stuff on the camera and am having trouble working with the SensorManager. I'm basically trying to get the rotation matrix from the sensor manager and then call glMultMatrix to rotate everything accordingly. It looks like in the documentation for SensorManager.getRotationMatrix that this is possible. However when I do multiply with the rotation matrix everything just gets screwy and moves around not like you'd expect from seeing other ar apps. I got some code below:
private float[] gravity = new float[3];
private float[] geomagnetic = new float[3];
private float filteringFactor = 0.01f;
private float[] rotationMatrixOut = new float[16];
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic[0] = event.values[0] * filteringFactor + geomagnetic[0] * (1.0f - filteringFactor);
geomagnetic[1] = event.values[1] * filteringFactor + geomagnetic[1] * (1.0f - filteringFactor);
geomagnetic[2] = event.values[2] * filteringFactor + geomagnetic[2] * (1.0f - filteringFactor);
} else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity[0] = event.values[0] * filteringFactor + gravity[0] * (1.0f - filteringFactor);
gravity[1] = event.values[1] * filteringFactor + gravity[1] * (1.0f - filteringFactor);
gravity[2] = event.values[2] * filteringFactor + gravity[2] * (1.0f - filteringFactor);
}
SensorManager.getRotationMatrix(rotationMatrixOut, null, gravity, geomagnetic);
}
I have also tried using SensorManager.remapCoordinateSystem but with no luck. My code for drawing is below, it's pretty standard stuff, I commented out lookat cause I wasn't sure if that was causing trouble
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//GLU.gluLookAt(gl, mCamera.position.x, mCamera.position.y, mCamera.position.z,
// mCamera.target.x, mCamera.target.y, mCamera.target.z,
// mCamera.up.x, mCamera.up.y, mCamera.up.z);
gl.glMultMatrixf(rotationMatrixOut, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glLineWidth(1.0f);
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glDrawArrays(GL10.GL_LINES, 0, 2 * 201 * 2);
I been losing way too much sleep over this if anyone can help that be greatly appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只是猜测,但您从 SensorManager 收到的数据是否按行主要顺序排列? OpenGL 期望数据采用列主序,因此如果您将行主序矩阵传递给 OpenGL,则会将其解释为转置。
你是对的,你不需要 gluLookAt 那里(假设你,即原点的设备,并显示它周围的世界)。
Just guessing, but could it be, that the data you receive from SensorManager is in row major order? OpenGL expects the data in column major order, so if you have a row major order matrix passed to OpenGL it were interpreted transposed.
And you're right, you don't need gluLookAt there (assuming you, i.e. the device at the origin, and displaying the world around it).