android - 将相机移动到场景中的特定点(旋转/平移时)- OpenGL ES 2

标签 android opengl-es camera

我想知道如何将相机移动到场景中的特定点,即使我已经在所有三个维度上进行了旋转、平移和缩放。对于点 P (x,y,z),我显然不能使用 translate(x,y,z) - 如果我这样做,我将以完全不同的点结束。

我有一栋有楼层和房间的建筑物。我想要两个不同的相机视角。第一个是鸟瞰图,我可以从上面看到特定的位置。它应该类似于:

Desired first View

第二个是 3 维的,我的相机具有特定值(但恒定,例如 30°),并且我正在寻找点(并且我想选择我的“x”旋转)这里)。如下图所示,第二个摄像头 View 应如下所示:

Desired Camera View

就像我说的,我不知道如何将相机移动到特定位置,因为旋转/平移后的值完全不同。除此之外,我不确定我是否在考虑正确的方法。

我的整个平移/旋转/缩放仅与模型有关。我没有改变查看方法中的任何内容。我使用以下方法修改模型(通过触摸手势):

             // translate to world position
             Matrix.setIdentityM(tmpMatrix, 0);
             Matrix.translateM(tmpMatrix, 0, translateX, translateY, translateZ);
             Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
             System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);

            // rotate around center
            Matrix.setIdentityM(tmpMatrix, 0);
            if (rotationX != 0)
                    Matrix.rotateM(tmpMatrix, 0, rotationX, 1.0f, 0.0f, 0.0f);
            if (rotationY != 0)
                    Matrix.rotateM(tmpMatrix, 0, rotationY, 0.0f, 1.0f, 0.0f);
            if (rotationZ != 0)
                    Matrix.rotateM(tmpMatrix, 0, rotationZ, 0.0f, 0.0f, 1.0f);

            Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
            System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);
             
            // scale down
            Matrix.setIdentityM(tmpMatrix, 0);
            Matrix.scaleM(tmpMatrix, 0, r * s, r * s, r * s);
            Matrix.multiplyMM(resMatrix, 0, tmpMatrix, 0, mModelMatrix, 0);
            System.arraycopy(resMatrix, 0, mModelMatrix, 0, 16);


*
             * Set the camera position (View matrix)
             */
            Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ,
                              centerX, centerY, centerZ, upX, upY, upZ);
            
            /*
             * combine the model with the view matrix
             */
            Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

            /*
             * this projection matrix is applied to object coordinates in the
             * onDrawFrame() method
             */
            Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, 1, -1,
                           nearPlaneDistance, farPlaneDistance);

            /*
             * Calculate the projection and view transformation
             */
            float[] mMVPMatrix = new float[16];
            Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);

            /*
             * all the drawing stuff inside the model-object (otherwise
             * translation/rotation wouldn't affect every object)
             */
            model3d.draw(mMVPMatrix);

我还负责在模型旋转时进行 x、y、z 方向的平移(例如,模型旋转 90° - 当我向左滑动时,对象仍应向左移动)。这是由我的 onTouchEvent-Helper 管理的:

 position.add(touchManager.moveDelta(0).rotate(-angle));

我的整个源代码都是开源的,you could have a look into github.

问题

无论我当前的旋转/位置如何,如何将相机平移和旋转到特定点(具有特定距离/角度)?有没有什么好的文献可以引用?有什么好的开源项目我可以研究一下吗? GitHub 上的资源真的很少...

我应该使用“lookAt”方法还是必须对模型进行某种平移/旋转?或者我应该改变我的眼睛和中心?

编辑:假设我不自己翻译模型(我将禁用用户翻译)。我想查看特定点 p (x,y,z) - 无论我如何旋转和缩放模型,我总是想查看这个点 p! - 我该怎么做呢?我是否必须翻译我的模型 - 我是否必须改变我的眼睛或中心?

最佳答案

如果您希望相机的方向和距该点的距离恒定,如果您知道绕 y 轴和俯仰-滚动轴的角度,则可以设置 3D 距离(x、y 和 z 中的距离)轴)距标量距离 d:

Vector3 dist   = Vector3 (    d * sin(yawAngle) * fabs(cos(pitchRollAngle)),
                              d * sin(pitchRollAngle),
                              d * cos(yawAngle) * fabs(cos(pitchRollAngle))    );

其中 yawAngle 的值可以从 -π 到 π,而itchRollAngle 的值可以从 -π/2.0f 到 π/2.0f。因此,您可以将 eyePt 向量定义为:

Vector3 eyePt  = Vector3 (    pnt.x - dist.x,
                              pnt.y - dist.y,
                              pnt.z - dist.z    );

其中 pnt 向量是点的位置。然后,您可以这样设置lookAt向量:

Vector3 lookAt = pnt;

最后,向上向量为:

Vector3 up     = Vector3 (    0.0f,    1.0f,    0.0f    );

希望这对您有帮助。抱歉我的英语不好。

关于android - 将相机移动到场景中的特定点(旋转/平移时)- OpenGL ES 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21092599/

相关文章:

java - 方向改变时保持值(value)

android - 在路径中找不到 ndk-build

opengl-es - 抖动 gouraud 着色的顶点色多边形以去除 strip

java - 相机权限在运行时不起作用

ios - 错误 noCamerasAvailable,仅适用于 iPhone <8+ Swift

iphone - 在 XCode 中模拟加速度计、麦克风和摄像头

android - 如何使此方法通用?将 RelativeLayout 转换为位图图像

java - 为什么 String.format() 在 Android TextView 上不起作用?

iphone - 通过iPhone上的着色器处理视频时捕获视频

android - 了解 Android 中的 android.graphics.Camera 对象