【问题标题】:OpenGL building hierarchy transform systemOpenGL构建层次变换系统
【发布时间】:2021-06-21 13:12:00
【问题描述】:

我正在尝试构建转换系统,模仿 Unity 的。查看我的代码:

void BaseObject::RecalculateTransform()
{
    // For top object
    if (parent.expired())
    {
        worldTransform = localTransform = glm::mat4(1);
        return;
    }

    // bunch of shit
    localTransform = glm::translate(glm::mat4(1), localPosition) * glm::scale(glm::mat4(1), localScale) * glm::mat4(localRotation);

    worldTransform = parent.lock()->GetWorldTransform() * localTransform;
}

这就是我计算局部变换和世界变换的方式。我已经尝试了很多转换矩阵顺序的组合,但没有一个能正常工作。我尝试引用 Unity3d,但找不到有用的东西。

localPositionlocalScaleglm::vec3 类型,localRotationglm::quat 类型。

可能有帮助,我从上面的代码中选择了一个屏幕截图:

auto top = app->GetHierarchy()->GetTopObject();

auto childDepth1 = top->Instantiate().lock();
childDepth1->SetLocalPosition(glm::vec3(0, 1, 0));

// spiral one
auto mesh1 = childDepth1->AddComponent<RandomMesh>().lock();
mesh1->SetVerticeData("l 30");

auto childDepth2 = childDepth1->Instantiate().lock();
childDepth2->SetLocalPosition(glm::vec3(0, 1, 0));

// spherical one
auto mesh2 = childDepth2->AddComponent<RandomMesh>().lock();
mesh2->SetVerticeData("s 100 t");

截图:

如您所见,螺旋形的球体就像它的孩子一样。螺旋形的localPosition(0, 1, 0)worldPosition 也是如此。但它是在-y 位置呈现的。 (我以其他方式确认+y 位置在中线上方。)

此外,球体的 localPosition 也是(0, 1, 0),因此它是worldPosition (0, 2, 0)。保持+y 位置在中间线下方的方向,它必须在螺旋线下方渲染,但它在球体上渲染。通过打印调试,它说球体的worldPosition(0, 0, 0),而不是(0, 2, 0)

经过一些实验,我发现变换矩阵的应用正负取决于子深度的奇偶性。

我想要的只是类似 Unity 的变换系统。 我该如何解决这个问题?

【问题讨论】:

  • 如果worldTransform = localTransform * parent.lock()-&gt;GetWorldTransform(); istead 会怎样?
  • @AlexeyLarionov 我试过了,没有任何改变:(

标签: c++ opengl glm-math


【解决方案1】:

这是由于我的愚蠢错误。当我初始化localRotation四元值时,我在做

localRotation = glm::quat(0, 0, 0, 1);

我不知道确切原因,但是使用调试器时,每次旋转矩阵乘以时,它都会否定位置值。

正确的初始化是

localRotation = glm::identity<glm::quat>();

根本不会应用轮换,顾名思义

这是我的解决方案:

void BaseObject::RecalculateTransform()
{
    isTransformChanged = false;

    // For top object
    if (parent.expired())
    {
        worldTransform = localTransform = glm::mat4(1);
        return;
    }

    const auto& scaled = glm::scale(glm::mat4(1), localScale);
    const auto& rotated = glm::mat4(localRotation) * scaled;
    const auto& translated = glm::translate(glm::mat4(1), localPosition) * rotated;

    localTransform = translated;

    worldTransform = parent.lock()->GetWorldTransform() * localTransform;
}

一切都很好。在韩国已经是午夜了。我终于可以睡觉了。 和我有同样问题的人,请不要傻:(

【讨论】:

    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 2021-07-13
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多