当前位置: 首页 > 知识库问答 >
问题:

编写LookAt函数

艾修然
2023-03-14

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

所以,我的问题是:
我在门户2。我有一个位置坐标为x,y,z的目标,我有我的球员的位置和他的旋转角度(偏航,俯仰,滚动)。当我使用目标坐标作为参数的函数时,我希望我的播放器看到目标<我发现:点看点,但效果不太好,最后的角度从来都不好。

我想这是因为在《传送门2》中,如果我参考这张图片:
对于旋转,偏航轴对应于游戏中的y坐标,俯仰是z(从玩家的后方到前方),滚动是x。

翻译一下:
图像的z轴对应游戏中的z轴,y是x一,x是y一。

我很难根据自己的需要修改在互联网上找到的代码<你能帮我吗?

提前谢谢你。

我目前拥有的代码是:

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 };

共有2个答案

暴才俊
2023-03-14

非常感谢你的回答!它真的帮助了我。

你的帖子帮助我更清楚地知道,为了让这个功能正常工作,我应该做些什么。

我没有使用四元数或旋转maxtrix,因为对于一个如此简单的函数来说,它有点太复杂了。以下是我的代码,供那些想实现它的人使用:

void TasTools::AimAtPoint(float x, float y, float z)
{
    Vector target = { y, x, z };

    //The camera is 64 units higher than the player:
    Vector campos = client->GetAbsOrigin() + client->GetViewOffset();
    campos = { campos.y, campos.x, campos.z };

    // Axis in the game, need to know it to fix up:
    //              : L - R  ; F - B ;  U - D
    // Rotation Axis:   x        z        y
    // Translation  :   y        x        z

    float xdis = target.x - campos.x;
    float ydis = target.z - campos.z;
    float zdis = target.y - campos.y;
    float xzdis = sqrtf(xdis * xdis + zdis * zdis);

    QAngle angles = { RAD2DEG(-atan2f(ydis, xzdis)), RAD2DEG(-(atan2f(-xdis, zdis))), 0 };

    engine->SetAngles(angles);
}

再次感谢大家!

郏实
2023-03-14

我想你想要的相机是一个4x4同质变换矩阵

你需要看的propper实现是:

>

  • 摄像头位置pos

    因为这是给玩家的,所以你的位置是固定的...

    目标位置target

    查看方向dir

    可通过以下公式简单计算:

     dir = target-pos
     dir /= |dir|
    

    一些对齐方向(如UP)

    这个取决于你的游戏...对于基于地形的游戏,您可以使用UP向量(如(0,1,0))或法线到表面等...对于基于6个DOF的应用程序,您可以使用一些玩家本地向量...小心此对齐向量不得与dir平行,否则后者的向量积将无法正常工作。在这种情况下,您可以选择不同的对齐向量,如右侧、NORT等。

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

    -Z =  dir
     Z = -dir
    

    要得到另外两个基向量,只需利用叉积。。。

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

    原点就是摄像机的位置:

    O = pos
    

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

    现在只需将O,X,Y,Z输入单元4x4矩阵即可。如何使用取决于引擎使用的符号。因为相机通常是反转的(也取决于符号),然后反转它,你就得到了你的矩阵。这里是OpenGL布局:

    如果你需要欧拉角,用测角法从矩阵中提取它们。。。

  •  类似资料:
    • 本文向大家介绍编写strcpy 函数相关面试题,主要包含被问及编写strcpy 函数时的应答技巧和注意事项,需要的朋友参考一下 已知strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc);其中strDest是目的字符串, strSrc 是源字符串。 (1)不调用C++/C 的字符串库函数,请编写函数 strcpy 。 (2)str

    • 前面我们已经生成好了一份扩展框架,但它是没有什么实际作用的。一个扩展的作用可大了去了,既可以操作PHP中的变量、常量,还可以定义函数、类、方法、资源等。先让我们从函数说起吧! ZEND_FUNCTION()宏函数 ZEND_FUNCTION()宏函数也可以写成PHP_FUNCTION(),但ZEND_FUNCTION()更前卫、标准一些,但两者是完全相同的。 #define PHP_FUNCTIO

    • 我正在学习OpenGL,其中使用函数构建视图,但我无法理解的工作原理,而且显然没有GLM的详细文档。谁能帮助我理解的参数和工作方式? 我目前的理解是,相机位于并面向。(我不知道是什么)

    • 问题内容: 我有一个函数数组,我试图产生一个由数组中元素组成的函数。我的方法是: 此方法似乎无效,将不胜感激。 (我要反转列表,因为这是我希望函数成为的组合顺序) 问题答案: 它不起作用,因为您在循环中创建的所有匿名函数都引用相同的循环变量,因此共享其最终值。 作为快速解决方案,您可以将分配替换为: 或者,您可以从函数返回lambda: 要了解发生了什么,请尝试以下实验: 这个结果使许多人感到惊讶

    • 我有一个函数数组,我试图生成一个函数,它由数组中的元素组成。我的做法是: 此方法似乎不起作用,请给予帮助。 (我正在反转列表,因为这是我希望函数的组合顺序)

    • 问题内容: 我是节点的新手,并尝试在节点中使用异步和事件行为优势。我以前从节点上了解到,用事件对象处理的所有内容都会异步执行。 然后我尝试了这个,请考虑以下代码: 这是异步执行吗?我认为不!为什么,因为我读了很多这句话: 一个事件被触发了,所以去做点什么,然后当你完成它之后,回来告诉我,但是与此同时,我会做点其他的事情。 就像快餐店的场景。但是上面的代码,当事件工作被触发时,将发生以下顺序: 进入