[TOC]
Max导出的fbx模型文件加载到客户端,对变换矩阵做了如下的转换,把Z-up右手坐标系的变换矩阵换到Y-up左手坐标系的变换矩阵。咋一看相当懵逼~
FORCEINLINE void _DxMatrixToApexMatrix(physx::PxMat44& matrix, const XMFLOAT4X4& xmMatrix)
{
XMFLOAT4X4 mat = xmMatrix;
std::swap(mat._21, mat._31);
std::swap(mat._22, mat._32);
std::swap(mat._23, mat._33);
std::swap(mat._24, mat._34);
std::swap(mat._12, mat._13);
std::swap(mat._22, mat._23);
std::swap(mat._32, mat._33);
std::swap(mat._42, mat._43);
memcpy((void*)matrix.front(), &mat._11, sizeof(float) * 16);
}
max max里面是Z朝上的右手坐标系,如图(a)所示.
DX11 客户端用的DX11是Y轴朝上的左手坐标系,如图(b)所示.
一开始想的是把Y和Z换一下就好了,那么矩阵里面把第二行和第三行换一下不就行了。代码应该是这样:
FORCEINLINE void _DxMatrixToApexMatrix(physx::PxMat44& matrix, const XMFLOAT4X4& xmMatrix)
{
XMFLOAT4X4 mat = xmMatrix;
std::swap(mat._21, mat._31);
std::swap(mat._22, mat._32);
std::swap(mat._23, mat._33);
std::swap(mat._24, mat._34);
memcpy((void*)matrix.front(), &mat._11, sizeof(float) * 16);
}
结果为什么还要换一下第二列和第三列呢? 把Y和Z换一下这个是对的,比如一个向量(x, y, z)变成(x, z, y)。但是,变换矩阵却不能这样操作!我的理解是,矩阵里面有旋转、缩放、平移,针对的是模型上的所有点。只换第二行和第三行是包括了部分缩放和旋转信息,最后对模型上点进行转换的时候都不知道结果是什么。
算一下点P在Z-up右手坐标系变换后的点,和点P1在Y-up左手坐标系变换后的点是不是依旧是同一个点!其中P1=(x, z, y),为P在Y-up坐标系中相同的点,换了一下Y和Z
注意:在Y-up的变换矩阵下P也应该在该坐标系下面,即P1 = (x, z, y)
(1)点P在Z-up右手坐标系变换之后的点为:P*M
(2)点P在错误的Y-up左手坐标系变换之后的点为:P1*M1
(3)点P在正确的Y-up左手坐标系变换矩阵变换之后的嗲哪位:P1*M2
小结:
(1)可以看到,PM和P1M2的结果换一下Y和Z轴就是一样的,这也说明M2才是正确的变换矩阵!
(2)同时,可以看到P1M1的结果和PM的结果是一样的,这就奇怪了,P1在Y-up左手坐标系用这个矩阵变换后又回到了Z-up右手坐标系里面的坐标(等于没有变换了)
参考[1]中给出了说明,翻译一下如下:
M_YZ右手 = ...// 变换YZ坐标得到在Z-up右手坐标系的点
M_YZ左手 = 求逆(M_YZ右手) // 变换YZ坐标重新得到在Y-up左手坐标系的坐标
M右手 = ... // 在Z-up右手坐标系下的一个变换矩阵
M左手 = M_YZ右手 * M右手 * M_YZ左手
简单说明一下:
M_YZ右手指的是在Z-up右手坐标系里面的把Y和Z换一下,也就是把Z-UP右手坐标系里面的点变换到了Y-up左手坐标系里面的点
[1]Changing a matrix from right-handed to left-handed coordinate system
[TOC]
最近遇到一个问题,模型上面的一个骨骼因为模型缩放之后它的变换矩阵各种不对。搞得有点迷糊,所以这里记录一下
[TOC]
装tensorflow-gpu的时候经常遇到问题,自己装过几次,经常遇到相同或者类似的问题,所以打算记录一下,也希望对其他人有所帮助
[TOC]
想把一个数组存成Object形式,所以索引需要从整形转字符串
[TOC]
今天遇到一个奇怪的问题,vs2015 Debug启动客户端,结果宕机
[TOC]
在stackoverflow看到一个问题,说重载函数试根据参数来的,和返回类型没有关系。然而下面这个模板函数只有返回类型不一样,为什么是正确的,参考[1]。
#include <iostream>
using namespace std;
template<typename T>
T add(double a, double b)
{
return static_cast<T>(a + b);
}
int main()
{
cout << add<int>(1.1, 1) << endl;
cout << add<double>(1.1, 1) << endl;
return 0;
}