OpenGL如何通过移动相机实现立方体跟随触屏手指移动
功能实现方案
核心修改思路
要实现立方体跟随手指全方向移动,需要对原有逻辑做两处核心调整:
- 记录上一次触摸事件的坐标,计算两次触摸的横向偏移量
deltaX、纵向偏移量deltaY,用偏移量代替原有的中线判断逻辑,实现位移距离和滑动距离挂钩 - 纵向位移直接沿相机的上向量(
cameraUp)计算,和横向的右向量位移叠加后更新相机位置即可实现双轴跟随
修改后完整代码
首先在类中新增两个成员变量,用于记录上一次触摸的坐标:
// 新增成员变量,记录上一次触摸的坐标 private float mLastX, mLastY; // 可自定义的触摸灵敏度参数,数值越大移动越快 private final float TOUCH_SENSITIVITY = 0.01f;
然后修改触摸事件处理和相关逻辑:
@Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下时记录初始坐标,避免第一次移动出现跳变 mLastX = x; mLastY = y; break; case MotionEvent.ACTION_MOVE: // 计算两次触摸的偏移量 float deltaX = x - mLastX; float deltaY = y - mLastY; // 更新上一次坐标记录 mLastX = x; mLastY = y; float[] cameraPos = renderer.getCameraPos(); float[] cameraFront = renderer.getCameraFront(); float[] cameraUp = renderer.getCameraUp(); // 计算横向移动的右向量 float[] rightVector = normalizar(cross(cameraFront, cameraUp)); // 计算横向位移量 float[] horizontalMove = new float[3]; for (int i = 0; i < 3; i++) { horizontalMove[i] = rightVector[i] * deltaX * TOUCH_SENSITIVITY; } // 计算纵向位移量,沿相机上向量移动 float[] verticalMove = new float[3]; for (int i = 0; i < 3; i++) { verticalMove[i] = cameraUp[i] * (-deltaY) * TOUCH_SENSITIVITY; // 这里deltaY加负号是因为安卓屏幕坐标系Y轴向下为正,和相机上向量方向相反,可根据实际手感调整 } // 叠加横纵位移更新相机位置 float[] newCameraPos = new float[3]; for (int i = 0; i < 3; i++) { newCameraPos[i] = cameraPos[i] + horizontalMove[i] + verticalMove[i]; } renderer.setCameraPos(newCameraPos); requestRender(); break; } return true; } public float[] normalizar(float[] vector) { float[] vectorNormalizado = new float[3]; double length = Math.sqrt(Math.pow(vector[0], 2) + Math.pow(vector[1], 2) + Math.pow(vector[2], 2)); if (length != 0) { vectorNormalizado[0] = (float) (vector[0] / length); vectorNormalizado[1] = (float) (vector[1] / length); vectorNormalizado[2] = (float) (vector[2] / length); } return vectorNormalizado; } public float[] cross(float[] v0, float[] v1) { float[] crossProduct = new float[3]; crossProduct[0] = v0[1] * v1[2] - v0[2] * v1[1]; crossProduct[1] = v0[2] * v1[0] - v0[0] * v1[2]; crossProduct[2] = v0[0] * v1[1] - v0[1] * v1[0]; return crossProduct; }
效果说明
修改后手指滑动多少距离,立方体就会对应移动对应距离,完全跟随手指操作。如果需要调整移动速度,直接修改TOUCH_SENSITIVITY的数值即可,数值越大移动灵敏度越高。
内容的提问来源于stack exchange,提问作者Bocho
相关产品推荐
相关产品推荐

