用PyOpenGL让摄像机以适当的方式进行偏航、俯仰和滚转?

2024-10-02 14:16:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经挣扎了一段时间,试图实现一个相机可以在任何一个轴上自由旋转(即当增加偏航、俯仰和横摇时)。我已经成功地设置了摄像机,根据当前的前向、右和上方向向量来适当地改变它的位置,这通常不会搞乱(通常我是指当我忽略滚动时)。简单地说,相机向前移动,但问题是当我尝试旋转相机时,我不知道如何正确设置。在

我生成一个摄影机来与该类一起使用:

import math
import numpy


class Camera:
    def __init__(self, position=(0, 0, 0), pitch=0, yaw=0, roll=0):
        self.position = list(position)
        self.yaw = yaw
        self.pitch = pitch
        self.roll = roll
        self.direction = [0.0, 0.0, -1.0]
        self.right = [1.0, 0.0, 0.0]
        self.up = [0.0, 1.0, 0.0]

    # Calculates where each camera vector (front, right, up) is facing given the current pitch, yaw, roll.
    # The derived vectors are the camera's own coordinate system, while the pitch, yaw and roll are world-based so far.
    def cameraVectors(self):
        x = math.sin(math.radians(self.yaw))*math.cos(math.radians(self.pitch))
        y = math.sin(math.radians(self.pitch))
        z = math.cos(math.radians(self.yaw))*math.cos(math.radians(self.pitch))
        self.direction = [x, y, z]

        x = math.sin(math.radians(self.yaw + 90))*math.cos(math.radians(self.roll))
        y = math.sin(math.radians(self.roll))
        z = math.cos(math.radians(self.yaw + 90))*math.cos(math.radians(self.roll))
        self.right = [x, y, z]

        self.up = numpy.cross(self.direction, self.right)

    # Simply increases the rotation when told to. Stuff below function is irrelevant (maybe) as it works alright.
    def cameraRotate(self, rotX, rotY, rotZ):
        self.yaw += rotX
        self.pitch += rotY
        self.roll += rotZ
        self.cameraVectors()

    def cameraMoveF(self, value):
        self.position[0] += value * self.direction[0]
        self.position[1] += value * self.direction[1]
        self.position[2] += value * self.direction[2]
        self.cameraVectors()

    def cameraMoveB(self, value):
        self.position[0] -= value * self.direction[0]
        self.position[1] -= value * self.direction[1]
        self.position[2] -= value * self.direction[2]
        self.cameraVectors()

    def cameraMoveL(self, value):
        self.position[0] += value * self.right[0]
        self.position[1] += value * self.right[1]
        self.position[2] += value * self.right[2]
        self.cameraVectors()

    def cameraMoveR(self, value):
        self.position[0] -= value * self.right[0]
        self.position[1] -= value * self.right[1]
        self.position[2] -= value * self.right[2]
        self.cameraVectors()

    def cameraMoveU(self, value):
        self.position[0] += value * self.up[0]
        self.position[1] += value * self.up[1]
        self.position[2] += value * self.up[2]
        self.cameraVectors()

    def cameraMoveD(self, value):
        self.position[0] -= value * self.up[0]
        self.position[1] -= value * self.up[1]
        self.position[2] -= value * self.up[2]
        self.cameraVectors()

    def getPosition(self):
        return self.position

    def getDirection(self):
        return self.direction

    def getRight(self):
        return self.right

    def getUp(self):
        return self.up

    def getPitch(self):
        return self.pitch

    def getYaw(self):
        return self.yaw

    def getRoll(self):
        return self.roll

我使用这个ViewMatrix创建每一帧:

^{pr2}$

在渲染视图时,变换矩阵、投影和视图矩阵都能完美地工作-所有对象都能正确地渲染,但问题是我正在努力建立相机自己的坐标系,并使其根据自己的坐标系滚动、俯仰和偏航。我显然在代码的某个地方错了,但我真的不知道问题出在哪里。我放了一个简短的视频,展示了相机如何在不同的摄影机旋转中渲染对象(例如,当我向下看时,我右转时,相机和它的目标都是根据世界Y轴旋转的,而不是我想要的相机,当我滚动时,会发生更多奇怪的事情)。轴表示为方形,旋转后面向摄影机。在

https://www.youtube.com/watch?v=aBaLkE1cUSo

一开始我用偏航和俯仰来演示正常的旋转。你可以注意到我的俯仰和偏航越多,旋转就越变成滚动(因为偏航与世界坐标系有关)。当然,当相机翻转时也会反转)。然后我会在0:48左右表演。在1点的时候,我会告诉你滚动是怎么搞得一团糟,整个场景都是古怪的。在

拜托,如果有人能找到我所缺少的东西,如果你能分享你的想法,我会很高兴的!我把头发拔了,我就是找不到我缺少的东西。有人提到要改造相机什么的,但我真的不明白怎么做这一切,我确实参考了很多资源。。。在

提前谢谢你!在


Tags: selfrightreturnvaluedefpositionmathcos
1条回答
网友
1楼 · 发布于 2024-10-02 14:16:30

在一天结束的时候,没有办法使用我刚才使用的简单的欧拉旋转来进行这样的旋转。即使通过尝试以多种方式旋转向上、向右和向前的向量,最终我还是求助于使用四元数来实现我的目标。现在轮换就像一个符咒!在

相关问题 更多 >

    热门问题