我需要一种传递到这些坐标系的方法,但是我在数学上挣扎着。
基本上,我有一个网格创建的“OpenGL",所以右手XYZ坐标系,我想加载它在一个不同的环境(虚幻引擎4),其中使用左手XZY坐标系。
现在,以这个网格为例,在其原始状态中:
如果负载它离开了所有的顶点,我得到了以下信息:
如果你仔细观察,你会发现它是“镜像”的,蜘蛛的左腿与右腿交换。而且,在图像不是很清楚,但深度是关闭,我可以看到“内部”的蜘蛛(如果你注意到,眼睛是因为这一点)。
现在,如果我用-Y交换每个顶点的Y坐标,结果基本上与原来的结果相同:
现在,我使用的网格格式有对象层次结构,这意味着网格的一个子集可能有另一个子集作为父子集,如果是这样的话,它有一个位置和一个相对于它的父子集的旋转矩阵。这意味着在加载网格时会出现更多的问题,因为在错误的坐标系中也定义了旋转矩阵和位置。为了应用这个变化,我创建了顶点,然后由这些顶点组成的对象,指定它的父对象,然后应用旋转矩阵和位置。
例如,用这种格式定义的这个网格;按照我所描述的方式,组成它的所有部分都是分层的:
如果按原样加载,使用顶点、相对旋转矩阵和在错误坐标系中的位置,我得到如下结果:
哪种看上去是一样的,除了它是沿着一个轴的“镜像”。注意,黄色的东西(不知道怎么称呼它)在图像的最右边:它在原图中的位置相反。另外,如果你看文本"BROKK“(它不是纹理,它是由顶点组成的),它也是相反的。
现在,如果我使用与蜘蛛相同的技巧,将Y切换到-Y,我得到如下结果:
现在它看起来没有镜像,但是机器的“手臂”是错误的,可能是因为我把相对旋转矩阵和位置放在它们的原始坐标系中?我试着和他们捣乱,但我发现所有奇怪的事情都在发生,与解决方案没有任何关系。
我已经看了很多遍,一个在坐标系统之间切换的方法,我找到了对比不同的想法。我试着应用下面的矩阵来切换轴,并将“向前”的轴反转,但是结果是疯狂的错误:
(10 0)
(0 0 1)
(0 -1 0)
我很无助,你有什么想法吗?
编辑:,感谢Ripi2的建议(只将符号倒置到Z坐标),我已经接近了理想的解。其结果是:
尽管它是倒过来的(我可以稍后简单地旋转它),它不再是镜像了。不过,在那张图中,我只是反演网格顶点和儿童位置的Z坐标。在图片中,除手臂外,所有部件都处于正确的方向,因为它们的旋转矩阵是单位矩阵。在手臂上,旋转矩阵不是恒等式,因为我把它留在原来的坐标系中,所以看上去完全不对。
我需要一个矩阵来乘以每个旋转矩阵,但我不知道是什么!
发布于 2017-02-05 16:40:11
矩阵从X+ right, Y+ up, Z- deep
到Y+ right, Z+ up, X+ deep
的转换
0 1 0 0
0 0 1 0
-1 0 0 0
0 0 0 1
及其逆
0 0 -1 0
1 0 0 0
0 1 0 0
0 0 0 1
如果没有矩阵代码,则如下所示:
x2 = -z1
y2 = x1
z2 = y1
编辑
你得到了错误的结果?也许你有一个不同的系统-改变。例如,如果仅仅更改Y符号就足够了,这就是矩阵:
1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1
记住矩阵计算顺序Result = Transform * Origin
。
如果模型由层次结构中的多个对象组成,则过程如下所示:
我们来看看你的模型。它有自己的矩阵T1 (例如,由旋转和平移组成,T1 = T·R)。当它被链接到arm的其余部分(谁有它的T2矩阵)时,它也必须得到主arm转换。因此,应用于手臂末端的结果矩阵是T2·T1 (注意顺序,而不是T1·T2)。如果将整个臂链连接到其他部位,则所需的臂端矩阵为T3·T2·T1。
现在应用视图矩阵(V)、轴变化(A)和投影(P).臂端的合成矩阵为P·A·V·T3·T2·T1。
也许在新的轴系统中很难定义投影。如果只是改变一些符号和交换轴,最好在投影后应用: A·P·V·T3·T2·T1
发布于 2017-02-05 21:13:59
这就是我找到的解决办法。我需要在每个顶点上应用一个矩阵,然后将同样的矩阵应用到每个层次化分量所具有的roto-平移矩阵上。矩阵是这样的:
1 0 0
0 0 1
0 1 0
在代码中(请记住,我使用的是虚幻引擎),如下所示:
// Iterating over all vertices of the mesh
for(int i = 0; i < verticesNumber; i++)
{
FVector4 vertex;
// Getting the coordinates in the original mesh coordinate system.
// Here the method GetX(), GetY(), GetZ() retrieve the coordinates from the mesh file somehow
vertex.X = GetX();
vertex.Y = GetY();
vertex.Z = GetZ();
// Creating the matrix that will transform these coordinates in the new coordinate system
FMatrix mat = FMatrix::Identity;
mat.M[0][0] = 1, mat.M[0][1] = 0, mat.M[0][2] = 0;
mat.M[1][0] = 0, mat.M[1][1] = 0, mat.M[1][2] = 1;
mat.M[2][0] = 0, mat.M[2][1] = 1, mat.M[2][2] = 0;
// Applying the matrix
vertex = mat.TransformFVector4(vertex);
vertices.Add(FVector(vertex.X, vertex.Y, vertex.Z));
}
/* Then I create the indices, normals, and so on. */
// Now I get from the file the roto-translation matrix for the current object and apply the same matrix like this (note that I multiply before and after; this was mainly what I was missing):
rotationTranslationMatrix = mat * rotationTranslationMatrix * mat;
// Then I set the new matrix, relative to the parent of the current object
FVector position;
position.X = rotationTranslationMatrix.M[0][3];
position.Y = rotationTranslationMatrix.M[1][3];
position.Z = rotationTranslationMatrix.M[2][3];
mesh->SetRelativeLocationAndRotation(position, rotationTranslationMatrix.Rotator());
对组成网格的每个部分执行这段代码。最终的结果是,对于我作为示例使用的模型:
注意,它沿着X轴移动了90度。我不知道如何避免这种情况,但是我需要的仅仅是在创建之后旋转网格就足够了,比如:
FRotator rotation;
rotation.Yaw = 0.0f;
rotation.Pitch = 0.0f;
rotation.Roll = -90.0f;
mMesh->SetWorldRotation(rotation);
最终结果:
再次感谢帮助Ripi2!
https://stackoverflow.com/questions/42051965
复制相似问题