第二十二节—GLKMatrix4MakeLookAt
本文为L_Ares个人写作,如需转载请表明原文出处。
本节只是简述GLKMatrix4MakeLookAt
函数的功能和参数理解,有需要的小伙伴可以自行拿走。
感兴趣的小伙伴可以自行improt GLKit
进去学习,里面有关于这个函数的实现思路的代码。
首先看一下它的结构:
GLK_INLINE GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ,
float upX, float upY, float upZ)
参数一共9个,每3个为一组。
前三个参数:
eyeX
,eyeY
,eyeZ
: 非常明显的说明了是眼睛所在位置在世界坐标系中的x,y,z是多少。这三个参数确定了一个观察者的位置,或者说一个视点的位置,也就是你在观察物体的时候,你是在哪里观察的。
中间三个参数:
centerX
,centerY
,centerZ
: 名字是叫做中心点,其实是观测中心点,实际上是你的眼睛正在观察物体的哪里,比如你看一个杯子,你是看的杯子把手,还是看的杯子口,杯子把手和杯子口不可能是同一个位置吧,那么它们就有不同的位置坐标,也有不同的中心点的坐标,这个中心点的坐标,就是你要设置到center里面的。
末尾三个参数:
upX
,upY
,upZ
: 这个是你的头的朝向,就是说你是脑袋正着看物体的,还是斜着看的,还是倒着看的,总之不可能是平行着看的,那你的视线应该是平行的,怎么可能看到你想要观察的物体。
再看一下里面的实现。
GLK_INLINE GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ,
float upX, float upY, float upZ)
{
//这三个我就不说了,上面解释了
GLKVector3 ev = {{ eyeX, eyeY, eyeZ }};
GLKVector3 cv = {{ centerX, centerY, centerZ }};
GLKVector3 uv = {{ upX, upY, upZ }};
GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));
GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));
GLKVector3 v = GLKVector3CrossProduct(n, u);
GLKMatrix4 m = {{ u.v[0], v.v[0], n.v[0], 0.0f,
u.v[1], v.v[1], n.v[1], 0.0f,
u.v[2], v.v[2], n.v[2], 0.0f,
GLKVector3DotProduct(GLKVector3Negate(u), ev),
GLKVector3DotProduct(GLKVector3Negate(v), ev),
GLKVector3DotProduct(GLKVector3Negate(n), ev),
1.0f }};
return m;
}
从上面没说过的开始看,
GLKVector3Negate
: 这个是把向量转换成负的。下面是苹果官方的解释。
GLKVector3Normalize
: 这个是把向量规范化,也就是转成单位向量
GLKVector3CrossProduct
: 向量的叉乘。在3D数学中,向量的叉乘意味着什么我想不用多了,大多都是为了要一个法向量。这个法向量垂直于两个叉乘的向量构成的平面
GLKVector3DotProduct
: 向量的点乘。在3D数学中,点乘的几何意义就是求夹角,或者说向量a在向量b方向上的投影。
所以,第一行:
GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));
就是把视点向量和观察中心点的向量的负向量先相加,再规范化,得到了一个规范化的和向量n
。
第二行 :
GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));
把刚才的到的和的单位向量n
和你的脑袋的正朝向的向量做叉乘,然后再变成单位向量,拿到单位法向量u
第三行
GLKVector3 v = GLKVector3CrossProduct(n, u);
再做和单位向量n
和单位法向量u
再做叉乘,得到了法向量v
,那么n
,u
,v
是不是就又构成了一个三维的坐标系。
自己画了一个图,做的不好,请各位谅解,如有错误,还请大家帮忙指出,万分感谢。
GLKMatrix4MakeLookAt.jpeg这时候,
单位向量n
方向上对应了OpenGL上的z
轴。
单位向量u
方向上对应了OpenGL上的x
轴。
向量v
则在方向上对应了OpenGL的y
轴。
最后,采用了列主序列存储的方式,齐次补全位置,存入4*4矩阵,返回这个矩阵,就是我们用来做变换的模型视图矩阵的初始矩阵。
GLKMatrix4 m = {{ u.v[0], v.v[0], n.v[0], 0.0f,
u.v[1], v.v[1], n.v[1], 0.0f,
u.v[2], v.v[2], n.v[2], 0.0f,
GLKVector3DotProduct(GLKVector3Negate(u), ev),
GLKVector3DotProduct(GLKVector3Negate(v), ev),
GLKVector3DotProduct(GLKVector3Negate(n), ev),
1.0f }};
本文只是自己的理解,如果有错误的地方,还请各位小伙伴帮忙指出,万分感谢哦。