节点坐标和世界坐标的转换

这里不讨论uitransfom里面的convertToXxxx。而是利用 node.matrix, node.WorldMatrix 和向量与四维矩阵的api来进行变换。
比如说我想知道,一个点 Vec3.transformMat4 一个节点的矩阵代表什么意义。我心想应该是转换节点坐标和世界坐标用的,如果一个节点坐标内的向量,专为世界坐标内的,应该怎么算,还有世界转节点坐标怎么算。

把节点内向量乘以节点矩阵的逆矩阵

下面是研究的结果,今天又用到了,分享一下。

在CocosCreator中

对象空间中的点坐标转世界空间中的点坐标

节点node的可以getWorldMatrix得到关于该节点的世界变换矩阵M。

  1. 矩阵$M$乘以 对象空间中任一点p 得到该点世界空间中的坐标。

    this.monkeyNode.getWorldMatrix(_m0); // monkeyNode为对象节点,_m0为对象节点的世界矩阵
    let v = v3(1, 0, 0); // 假设对象坐标系中的一个点
    
    // 方法1:点坐标组装为矩阵,使用矩阵乘法,注意组装为行向量的话使用左乘
    Mat4.multiply(_m1, _m0, new Mat4(v.x, v.y, v.z, 1)); // 组装到矩阵后做乘法,注意一定要有后面的1
    this.spNode.setWorldPosition(_m1.m00, _m1.m01, _m1.m02); // 结果就是世界空间中的位置
    
    // 方法2:使用向量的矩阵变换API
    let v1 = v4(v.x, v.y, v.z, 1).transformMat4(_m0);
    this.spNode.setWorldPosition(v3(v1.x, v1.y, v1.z));
    
    // 方法3:然而直接三维向量直接就有与mat4乘的api,最后一位补1,还有另一个方法是补0的。
    v.transformMat4(_m0);
    this.spNode.setWorldPosition(v);
    
  2. 矩阵的逆$M^{-1}$乘以世界坐标中的任一点p 得到该点在对象空间中的坐标。

    // 矩阵变换方式
    this.monkeyNode.getWorldMatrix(_m0); // monkeyNode为对象节点
    let v = v3(1, 0, 0); // 假设世界坐标系中的一个点
    
    // 方法1:
    Mat4.multiply(_m1, _m0.invert(), mat4(v.x, v.y, v.z, 1));
    this.spNode.setPosition(_m1.m00, _m1.m01, _m1.m02); // 结果就是对象空间中的位置
    
    // 方法2: 如果非要用右乘变换矩阵,那么就都换成转置(实际上是没有必要的)
    Mat4.multiply(_m1, mat4(v.x, v.y, v.z, 1).transpose(), _m0.invert().transpose());
    this.spNode.setPosition(_m1.m00, _m1.m04, _m1.m08);
    
    // 方法三:使用向量的矩阵变换API
    v.transformMat4(_m0.invert());
    this.spNode.setPosition(v);
    
    // 直接使用cocos给封装好的api的方式:
    this.monkeyNode.inverseTransformPoint(_v0, v);
    this.spNode.setPosition(_v0);
    
4赞

感谢分享!