OpenGL ES

第二十二节—GLKMatrix4MakeLookAt

2020-10-17  本文已影响0人  L_Ares

本文为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 : 这个是把向量转换成负的。下面是苹果官方的解释。

1.1.png

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,那么nu,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 }};

本文只是自己的理解,如果有错误的地方,还请各位小伙伴帮忙指出,万分感谢哦。

上一篇 下一篇

猜你喜欢

热点阅读