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

如何不将枢轴对齐物体中心,实现相机围绕该物体旋转

实现思路

核心逻辑非常简单:你要的效果本质是临时用选中物体作为旋转枢轴执行轨道旋转,全程不修改全局枢轴参数,旋转结束后全局枢轴仍保持原有值,自然就满足「无需将旋转枢轴移至物体中心」的要求。

你只需要在原有代码基础上做很小的改动:

  • 首先在点击物体触发旋转的瞬间,新增两个仅用于本次旋转的临时变量,不要覆盖你的全局枢轴参数:
    1. 临时枢轴点:取选中物体的世界坐标 objWorldPos = selectedObj.position
    2. 临时旋转距离:计算初始相机位置到该物体的直线距离 tempPivotDist = glm::length(mInitialCam.getEyePoint() - objWorldPos)
  • 原有旋转逻辑几乎不用改,只需要把原代码中用到全局mInitialPivotDistance的地方替换为上面的tempPivotDist,位置计算时用物体坐标当临时枢轴即可。

修改后的参考代码如下:

void HandleUICameraRotate() {
    // selectedObj 为选中的物体,已提前拿到其世界坐标
    // 旋转开始时已提前存储 mInitialCam(初始相机位姿)、objWorldPos(选中物体世界坐标)、tempPivotDist(初始相机到物体的距离)

    float deltaX = (mMousePos.x - mInitialMousePos.x) / -100.0f;
    float deltaY = (mMousePos.y - mInitialMousePos.y) / 100.0f;

    // 相机方向向量
    glm::vec3 mW = glm::normalize(mInitialCam.getViewDirection());
    bool invertMotion = (mInitialCam.getOrientation() * mInitialCam.getWorldUp()).y < 0.0f;

    // 右轴向量
    vec3 mU = normalize(cross(mInitialCam.getWorldUp(), mW));

    if (invertMotion) {
        deltaX = -deltaX;
        deltaY = -deltaY;
    }

    // 这里把原来的mInitialPivotDistance替换为临时计算的tempPivotDist
    glm::vec3 rotatedVec = glm::angleAxis(deltaY, mU) * (-mInitialCam.getViewDirection() * tempPivotDist);
    rotatedVec = glm::angleAxis(deltaX, mInitialCam.getWorldUp()) * rotatedVec;

    // 这里原来的枢轴位置替换为选中物体的世界坐标objWorldPos
    mCamera.setEyePoint(objWorldPos + rotatedVec);
    mCamera.setOrientation(glm::angleAxis(deltaX, mInitialCam.getWorldUp()) * glm::angleAxis(deltaY, mU) * mInitialCam.getOrientation());
}

修改后旋转过程中,选中物体始终会保持你点击时它在屏幕上的位置,且全程不会改动你的全局相机枢轴参数,完全符合需求。

内容的提问来源于stack exchange,提问作者ashesofphoenix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:45:03