我正在尝试在简单的Metal应用程序中实现四元数,但遇到了问题。我仔细检查了所有内容,从数学角度看似乎是正确的,但结果根本不正确。
所以基本上,这应该产生一个转换矩阵,我将其应用于顶点
static func FromEuler(_ eul: simd_float3) -> simd_quatf{
let yaw = eul[0]
let pitch = eul[1]
let roll = eul[2]
let cy = cos(yaw * 0.5);
let sy = sin(yaw * 0.5);
let cp = cos(pitch * 0.5);
let sp = sin(pitch * 0.5);
let cr = cos(roll * 0.5);
let sr = sin(roll * 0.5);
let qw = cr * cp * cy + sr * sp * sy;
let qx = sr * cp * cy - cr * sp * sy;
let qy = cr * sp * cy + sr * cp * sy;
let qz = cr * cp * sy - sr * sp * cy;
return simd_quatf(ix:qx, iy:qy, iz:qz, r:qw)
}
func ToMat4x4()-> matrix_float4x4{
let qx = self.imag.x
let qy = self.imag.y
let qz = self.imag.z
let qw = self.real
return matrix_float4x4(rows: [
simd_float4(1 - 2*qy*qy - 2*qz*qz, 2*qx*qy - 2*qz*qw, 2*qx*qz + 2*qy*qw, 0),
simd_float4(2*qx*qy + 2*qz*qw, 1 - 2*qx*qx - 2*qz*qz, 2*qy*qz + 2*qx*qw, 0),
simd_float4(2*qx*qz - 2*qy*qw, 2*qy*qz - 2*qx*qw, 1 - 2*qx*qx - 2*qy*qy, 0),
simd_float4(0, 0, 0, 1)
])
}
这是我的变换矩阵
func Transform() -> matrix_float4x4{
//Perform Translation matrix
let translate : matrix_float4x4 = matrix_float4x4(rows: [
simd_float4(1, 0, 0, self.position[0]),
simd_float4(0, 1, 0, self.position[1]),
simd_float4(0, 0, 1, self.position[2]),
simd_float4(0, 0, 0, 1)
])
//Scale matrix
let scale : matrix_float4x4 = matrix_float4x4(rows: [
simd_float4(self.scale[0], 0, 0, 0),
simd_float4(0, self.scale[1], 0, 0),
simd_float4(0, 0, self.scale[2], 0),
simd_float4(0, 0, 0, 1)
])
//Rotation
//Get quaternion from euler
let quaternion = simd_quatf.FromEuler(self.rotation)
return translate * quaternion.ToMat4x4() * scale
}
然后在着色器中,我只需执行Matrix * VertexPosition The Triangle rotated 90 degrees z axis变成了飞机!