You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:27:04