从蒙皮位置计算未蒙皮位置

Calculating unskinned pos from skinned pos

大家好,我正在尝试根据蒙皮 pos 计算未蒙皮 pos。

一个蒙皮的pos是这样计算的:

FMatrix Matrices[3];
float Weights[3];
FVector Pos;
FVector NewPos;
for( int i = 0; i < 3; i++)
{
   NewPos += Matrices[i].TransformPosition(Pos) * Weights[i];
}

当矩阵、权重和 NewPos 已知时,如何计算 Pos?

我知道对于单个转换它是:

 Pos = Matrices[0].InverseTransformPosition(NewPos / Weights[0]);    

是否可以重新计算 Pos,如果可以,应该怎么做?

您可以将此 TransformPosition 调用视为矩阵乘以向量乘法。权重也可以应用于矩阵。所以你有

M1*pos*w1 + M2*pos*w2 + M3*pos*w3 = (w1*M1 + w2*M2 + w3*M3)*pos

换句话说,您可以使用权重对矩阵进行缩放,然后将矩阵相加。结果将是一个结合了您的整个操作的单一矩阵。然后你可以使用它的逆变换。

FMatrix Combined;
for( int i = 0; i < 3; i++) {
   Combined += Matrices[i] * Weights[i];
}
Combined *= 1 / Combined.M[3][3];
Pos = Combined.InverseTransformPosition(NewPos);

如果引擎正确处理了齐次坐标,那么我除以右下角元素的标准化步骤应该是不必要的,但显然情况并非如此。因此,如果矩阵 可能 表示 non-affine 投影变换(最后一行不是 0 0 0 *),则不应使用 FVector,而是使用 FVector4 代替。如果要使用 FVector,则必须像上面那样缩放矩阵以形成最后一行 0 0 0 1