使用陀螺仪数据旋转虚拟相机-iOS上的OpenGL ES
我创建了一个基于Vuforia平台的增强现实应用程序。我正在对其进行修改,以便在目标丢失时,系统将使用目标的最后一个已知位置,以及CoreMotion提供的设备方向数据,将对象保持在正确的位置 我需要最后一位的帮助-整合CoreMotion数据。我认为最好的方法是基于陀螺输入旋转虚拟摄像机,但我不是OpenGL ES专家。有人能告诉我们最好的方法吗?我知道如何获取设备方向数据,这是OpenGL和矩阵代数,我需要一些指导 下面是我的renderFrame方法使用陀螺仪数据旋转虚拟相机-iOS上的OpenGL ES,ios,opengl-es,gyroscope,Ios,Opengl Es,Gyroscope,我创建了一个基于Vuforia平台的增强现实应用程序。我正在对其进行修改,以便在目标丢失时,系统将使用目标的最后一个已知位置,以及CoreMotion提供的设备方向数据,将对象保持在正确的位置 我需要最后一位的帮助-整合CoreMotion数据。我认为最好的方法是基于陀螺输入旋转虚拟摄像机,但我不是OpenGL ES专家。有人能告诉我们最好的方法吗?我知道如何获取设备方向数据,这是OpenGL和矩阵代数,我需要一些指导 下面是我的renderFrame方法 -(void)renderFrameQ
-(void)renderFrameQCAR {
[self setFramebuffer];
// Clear colour and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render video background and retrieve tracking state
QCAR::State state = QCAR::Renderer::getInstance().begin();
QCAR::Renderer::getInstance().drawVideoBackground();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// Check if any trackables are visible.
int numberOfTrackables = state.getNumActiveTrackables();
QCAR::Matrix44F modelViewMatrix;
// Skip rendering if there is nothing to render.
if (numberOfTrackables > 0 || hasPickedUpTrackablePreviously == YES) {
// If there are none, but one was picked up in the past, use the last pose matrix.
if (numberOfTrackables == 0 && hasPickedUpTrackablePreviously == YES) {
modelViewMatrix = trackablePoseMatrix;
}
else {
// Get the trackable
const QCAR::Trackable* trackable = state.getActiveTrackable(0);
modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackable->getPose());
// Store these variables for use later.
trackablePoseMatrix = modelViewMatrix;
hasPickedUpTrackablePreviously = YES;
}
// Fetch the 3D object to render.
Object3D *obj3D;
if (currentlyChangingTextures == YES || useDummyModel == YES) {
obj3D = dummyObject;
}
else {
obj3D = [objects3D objectAtIndex:0];
}
// Render using the appropriate version of OpenGL
// OpenGL 2
QCAR::Matrix44F modelViewProjection;
// Apply usual transformations here
ShaderUtils::translatePoseMatrix(sideToSideFloat, forwardBackFloat, 0.0f, &modelViewMatrix.data[0]);
ShaderUtils::scalePoseMatrix(kObjectScale * sizeFloat, kObjectScale * sizeFloat, kObjectScale * sizeFloat, &modelViewMatrix.data[0]);
ShaderUtils::rotatePoseMatrix(0.0f + rotationAngleFloat, 0.0f, 0.0f, 1.0f, &modelViewMatrix.data[0]);
// Apply our translation vector here based on gesture info from the buttonOverlayViewController
QCAR::Vec3F translationFromWorldPerspective = SampleMath::Vec3FTransformNormal(translationVectorFromCamerasPerspective, inverseModelViewMatrix);
translationFromWorldPerspective = SampleMath::Vec3FNormalize(translationFromWorldPerspective);
theTranslation.data[0] = theTranslation.data[0] + speed*translationFromWorldPerspective.data[0];
theTranslation.data[1] = theTranslation.data[1] + speed*translationFromWorldPerspective.data[1];
theTranslation.data[2] = 0.0f;
ShaderUtils::translatePoseMatrix(theTranslation.data[0], theTranslation.data[1], theTranslation.data[2], &modelViewMatrix.data[0]);
// Update inverseModelViewMatrix
inverseModelViewMatrix = SampleMath::Matrix44FInverse(modelViewMatrix);
// Multiply modelview and projection matrix as usual
ShaderUtils::multiplyMatrix(&qUtils.projectionMatrix.data[0], &modelViewMatrix.data[0], &modelViewProjection.data[0]);
glUseProgram(shaderProgramID);
glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.vertices);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.normals);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.texCoords);
glEnableVertexAttribArray(vertexHandle);
glEnableVertexAttribArray(normalHandle);
glEnableVertexAttribArray(textureCoordHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, [obj3D.texture textureID]);
glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
glDrawArrays(GL_TRIANGLES, 0, obj3D.numVertices);
ShaderUtils::checkGlError("EAGLView renderFrameQCAR");
}
// Disable these things.
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisableVertexAttribArray(vertexHandle);
glDisableVertexAttribArray(normalHandle);
glDisableVertexAttribArray(textureCoordHandle);
QCAR::Renderer::getInstance().end();
[self presentFramebuffer];
}
谢谢 我还没有使用Vuforia,所以我不完全理解您的代码,但我已经成功创建了一个AR应用程序,使用陀螺仪和指南针控制相机。这是我的相机矩阵代码:
GLKMatrix4 cameraMatrix = GLKMatrix4Identity;
cameraMatrix = GLKMatrix4Rotate(cameraMatrix, GLKMathDegreesToRadians((zenith-90)), 1.0f, 0.0f, 0.0f);
cameraMatrix = GLKMatrix4Rotate(cameraMatrix, GLKMathDegreesToRadians(azimuth), 0.0f, 1.0f, 0.0f);
其中:
天顶=(180-陀螺仪滚动角)[0点直线上升,180点直线下降],和
方位角=罗盘角度(北纬0度,东经90度,南纬180度,西经270度)
在顶点着色器中,glPosition通过以下公式计算:
gl_Position = uProjectionMatrix * uCameraMatrix * vec4(position, 1.0);
我使用的是点精灵,但position保留了我的粒子在3D世界空间中的坐标。在您的情况下,我猜这是您将替换其他矩阵的地方,如modelViewMatrix等
小心你的矩阵乘法顺序 谢谢你的建议。我没能让它工作(我不是专家),我在这方面得到了额外的帮助。如果解决方案不太复杂,我会在这里发布。