【问题标题】:How to rotate a shape in another 3D software so that the rotation matches with the rotation in Blender?如何在另一个 3D 软件中旋转形状以使旋转与 Blender 中的旋转匹配?
【发布时间】:2019-04-10 20:21:00
【问题描述】:

我在 Blender 中导入一个网格,使用设置axis_forward='-Z', axis_up='Y' 导出它,在 NVIDIA 的 FleX 中导入,旋转它并存储在磁盘上;我称这个网格为X。我还在 Blender 中导入网格并旋转相同的量;我称这个网格为Y。在Blender中导入X(设置axis_forward='-Z', axis_up='Y')后,我意识到X具有不同的旋转,这意味着FleX要么使用不同的全局轴(我认为它是-Y向前和Z向上)或它以不同的顺序或两者的组合应用旋转。所以我现在很困惑。我不想改变 FleX 方面的任何东西。但是,我想旋转 Y,使其与旋转后 FleX 导出的内容 (X) 匹配。我也尝试过使用四元数,但我仍然无法弄清楚 FleX 是如何转换对象的。我唯一能凭经验弄清楚的是,rx 旋转的值对 FleX 和 Blender 的应用方式相同。这意味着如果在 Blender 的场景中导入对象 XY 将完全重叠。

我的目标是在 FleX 中旋转对象,以便当我在 Blender 中导入 X 时,对象 Y 的旋转与对象 X 完全匹配。例如,我希望 FleX 旋转对象的方式与 Blender 使用欧拉旋转矢量 [rx, ry, rz] 旋转它的方式相同。我怎样才能做到这一点?

请注意,我不会更改 Blender 中的旋转顺序,而是使用默认的 XYZ 旋转。

这里我是 FleX 和 Blender 对于此类转换的视觉差异的一些图像:

欧拉旋转矢量:[0, 89.9, 0] 在 Blender 中用于对象 Y

在 Blender 中应用旋转后(对象Y):

在 FleX 中应用相同的旋转 ([0, 89.9, 0]) 并在 Blender 中导入对象 X 后:

欧拉旋转矢量:[0, 0, 89.9] 用于 Blender 中的对象 Y

在 FleX 中应用相同的旋转 ([0, 0, 89.9]) 并在 Blender 中导入对象 X 后:

从图像中很容易猜到 FleX 在应用旋转时交换了ryrz。如果我在 Blender 中应用旋转时也交换 ryrz,那么 XY 都会重叠。但是,这仅在旋转矢量的所有分量都为零时才有效,除了其中一个分量。如果旋转矢量类似于 [-43.964176, 20.641195, -1.2689421] XY 不再重叠,就会出现如下所示的差异:

如果我在 FleX 中将布料放在 X 上,在 Blender 中导入布料和 Y 并将 Y 旋转 [-43.964176, -1.2689421, 20.641195],差异会更加明显(请注意,我已经交换了 ry 和 @ 987654386@ 在 Blender 中应用旋转时,而不是在 FleX 中):

请注意,如果我在这里导入X,布料将完美地覆盖它,同时在表面上触摸它:

在对最后一个例子做了一些修改之后,我注意到如果我应用旋转矢量 [-43.964176, 1.2689421, 20.641195] (rx, -rz, ry) 对象几乎完全重叠:

再举个例子,我想在 Blender 中应用旋转 [87.68034, 79.94778, 82.697876],这应该理想地给我这样的结果:

但是,FleX 给了我以下信息(在将旋转矢量传递给 FleX 之前没有交换):

我在想也许在 Blender 中按 (rx, -rz, ry) 的顺序应用旋转会给我上一个示例得到的完全重叠的结果,但是我得到的另一个结果非常奇怪,如下所示。请注意,我想将对象旋转 [87.68034, 79.94778, 82.697876]`:

通过在 Blender 中手动旋转对象,我最终可以使其尽可能接近 Y(从 FleX 导出)。令人惊讶的是,重叠XY 的旋转向量与(rx, ry, rz) 中的[87.68034, 79.94778, 82.697876](rx, -rz, ry) 中的[87.68034 -82.697876, 79.94778] 截然不同。它是在 `(rx, ry, rz) 中的 [5.38, -10.1, 88.6] 周围的东西,如下所示:

虽然您可能需要更多信息才能准确了解发生了什么,但下面我发布了 FleX 中用于计算其旋转矩阵的代码。使用欧拉角时使用第一个,输入四元数时使用第二个:

// generate a rotation matrix around an axis, from PBRT p74
inline Mat44 RotationMatrix(float angle, const Vec3& axis)
{
    Vec3 a = Normalize(axis);
    float s = sinf(angle);
    float c = cosf(angle);

    float m[4][4];

    m[0][0] = a.x * a.x + (1.0f - a.x * a.x) * c;
    m[0][1] = a.x * a.y * (1.0f - c) + a.z * s;
    m[0][2] = a.x * a.z * (1.0f - c) - a.y * s;
    m[0][3] = 0.0f;

    m[1][0] = a.x * a.y * (1.0f - c) - a.z * s;
    m[1][1] = a.y * a.y + (1.0f - a.y * a.y) * c;
    m[1][2] = a.y * a.z * (1.0f - c) + a.x * s;
    m[1][3] = 0.0f;

    m[2][0] = a.x * a.z * (1.0f - c) + a.y * s;
    m[2][1] = a.y * a.z * (1.0f - c) - a.x * s;
    m[2][2] = a.z * a.z + (1.0f - a.z * a.z) * c;
    m[2][3] = 0.0f;

    m[3][0] = 0.0f;
    m[3][1] = 0.0f;
    m[3][2] = 0.0f;
    m[3][3] = 1.0f;

    return Mat44(&m[0][0]);
}


inline Mat44 RotationMatrix(Quat q)
{
    Matrix33 rotation(q);

    Matrix44 m;
    m.SetAxis(0, rotation.cols[0]);
    m.SetAxis(1, rotation.cols[1]);
    m.SetAxis(2, rotation.cols[2]);
    m.SetTranslation(Point3(0.0f));

    return m;
}

以下是我应用欧拉旋转矢量的方法:

obj->Transform(RotationMatrix(op.rotate.x, Vec3(1.0f, 0.0f, 0.0f)));
obj->Transform(RotationMatrix(op.rotate.y, Vec3(0.0f, 1.0f, 0.0f)));
obj->Transform(RotationMatrix(op.rotate.z, Vec3(0.0f, 0.0f, 1.0f)));

我认为这应该是Transform() 的定义方式:

void Mesh::Transform(const Matrix44& m)
{
    for (uint32_t i=0; i < m_positions.size(); ++i)
    {
        m_positions[i] = m*m_positions[i];
        m_normals[i] = m*m_normals[i];
    }
}

【问题讨论】:

    标签: unity3d graphics 3d rotation blender


    【解决方案1】:

    我只需进行以下更改以 [手动] 将 FleX 的坐标系更改为 Blender 使用的坐标系:

    obj->Transform(RotationMatrix(op.rotate.x, Vec3(1.0f, 0.0f, 0.0f)));
    obj->Transform(RotationMatrix(op.rotate.y, Vec3(0.0f, 0.0f, -1.0f)))
    obj->Transform(RotationMatrix(op.rotate.z, Vec3(0.0f, 1.0f, 0.0f)));
    

    我认为这是我生成了三个旋转向量[90, 0, 0][0, 90, 0][0, 0, 90],并在 FleX 中旋转了形状。然后我在 Blender 中加载形状,并根据经验计算出 Blender 中哪个轴上的旋转与从 FleX 导入的形状相匹配。我了解到,当我在 Blender 中将 Yaxis 上的形状旋转 90 度时,它与 FleX 中 Z 轴上的 90 度旋转相匹配。另外,我了解到在 Blender 中将对象在 Z 轴上旋转 -90 度与在 FleX 中在 Y 轴上旋转 90 度相匹配。

    【讨论】:

      猜你喜欢
      • 2016-06-13
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多