本文介绍了编写 LookAt 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用 Source SDK 用 C++ 编写 LookAt 函数.我做了一些研究,发现了很多链接,但其中很多是关于 Unity 或 Glm 的,并且使用了四元数和旋转矩阵,但我不需要这个.

I'm currently trying to write a LookAt function in C++ with the Source SDK.I did some research and found many links but many of this were about Unity or Glm and were using quaternions and rotation matrix, but I don't need this.

所以,这是我的问题:
我在传送门 2 中.我有一个带有位置坐标 x、y、z 的目标,我有我的玩家的位置和他的旋转度数(偏航、俯仰、滚动).当我以目标坐标为参数使用我的函数时,我希望我的玩家看着目标.
我发现了这个:点看点但效果不太好,最后的角度从来都不好.

So, here is my problem:
I'm in Portal 2. I have a Target with position coordinates x, y, z and I have the position of my player and his rotation in degrees (yaw, pitch, roll). When I use my function with the target coordinates as parameters, I want my player to look at the target.
I found this : Point look at Point but it doesn't work really well, the final angle was never good.

我认为是因为在 Portal 2 中,如果我参考 这张图片:
对于旋转,yaw 轴对应游戏中的 y 坐标,pitch 为 z 一(从玩家的后到前),roll 为 x 一.

I think it's because in Portal 2, if I refer to this image:
For rotation, the yaw axis correspond to the y coordinate in the game, the pitch is the z one (from back to front of the player), and the roll is the x one.

翻译:
图片的z轴对应游戏中的z轴,y为x一,x为y一.

For translation :
The z axis of the image correspond to the z axis in the game, the y is the x one, and the x is the y one.

让我在互联网上找到的代码适应我的需要非常困难.
你能帮我解决这个问题吗?

It's pretty hard for me to adapt codes I found on internet to my needs.
Could you help me for this ?

提前致谢.

我目前拥有的代码是这样的:

The code I currently have is this one :

float xdistance = pos.x - target.x;
float ydistance = pos.y - target.y;
float zdistance = pos.z - target.z;
float xzdistance = sqrtf(xdistance * xdistance + zdistance * zdistance);

//Final angle:
QAngle a = { RAD2DEG((atan2f(ydistance, zdistance))), RAD2DEG(-(atan2f(xdistance, zdistance))), 0 };

推荐答案

我假设您想要的相机是 4x4 同构变换矩阵

I assume you wanted camera is a 4x4 homogenous transform matrix

正确实施look需要的是:

What you need for propper implementing of look at is:

  1. 相机位置pos

因为这是给玩家的所以你的位置是固定的并且是已知的......

as this is for player so your position is fixed and known ...

目标位置target

视图方向dir

可以简单地计算为:

 dir = target-pos
 dir /= |dir|

  • 一些对齐方向(如向上)

    这取决于您的游戏...对于基于地形的游戏,您可以使用 UP 矢量(如 (0,1,0))或法线到表面等...对于基于 6 DOF 的游戏您可以使用某些播放器本地向量的应用程序...注意此对齐向量不能与 dir 平行,否则后者的叉积将无法正常工作.在这种情况下,您可以选择不同的对齐向量,如 RIGHT、NORT 等.

    this one depends on your game ... for terrain based games you can use UP vector (like (0,1,0)) or normal to surface etc ... for 6 DOF based apps you can use some player local vector ... Be careful this align vector must not be parallel to dir otherwise the cross product latter would not work properly. In such case you can chose different align vector like RIGHT,NORT,etc.

    要构造一个 3D 变换矩阵,您需要位置 O 和 3 个基本向量 (X,Y,Z),它们是单位且彼此垂直.位置是 pos 并且基本向量之一是 dir(这取决于您寻找的是哪个轴,例如透视 OpenGL 通常使用 -Z).所以你需要的是计算另外两个基向量.让我们考虑一下我们将在 -Z 方向上查看:

    To construct a 3D transform matrix you need position O and 3 basis vectors (X,Y,Z) which are unit and perpendicular to each other. The position is pos and one of the basis vectors is the dir (which depends on which axis is your looking one for example perspective OpenGL uses usually -Z). So what you need is to compute the other two basis vectors. Let us consider we will be viewing in -Z direction so:

    -Z =  dir
     Z = -dir
    

    要获得其他 2 个基向量,只需利用叉积...

    to get the other 2 basis vectors just exploit cross product ...

    X = cross(UP,Z)
    X /= |X|
    Y = cross(Z,X)
    Y /= |Y|
    

    原点只是相机位置:

    O = pos
    

    cross 中操作数的顺序将决定结果的符号,因此如果您反转了某个轴,只需交换操作数...

    The order of operands inside cross will determine the sign of the result so in case you got reversed some axis just swap the operands ...

    现在只需将 O,X,Y,Z 输入到 4x4 单元矩阵中.如何取决于您的引擎使用的符号.由于相机通常是倒置的(也取决于符号),然后将其倒置即可得到结果矩阵.这里的 OpenGL 布局:

    Now just simply feed O,X,Y,Z into unit 4x4 matrix. How depends on the notation your engine is using. As camera is usually inverted (also depends on notation) then invert it and you got your resulting matrix. Here OpenGL layout:

    如果您需要使用测角法从矩阵中提取欧拉角...

    In case you need Euler angles extract them from the matrix using goniometry...

    这篇关于编写 LookAt 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!