2021-08-31

Problems when rotating the view matrix (OpenGL)

Setting: I have a view matrix which in the beginning is the identity matrix. R,U,F = X, Y, Z axes. I rotate the view matrix by creating a matrix from the given X,Y,Z rotation angles.

Problem: When I first rotate the view matrix by some Z angle (e.g. 45°) and subsequently rotate it by some Y angle, my scene doesn't rotate horizontally (e.g. from left to right), but in the direction given by the view matrix' Y axes.

What I had expected was that the view matrix, which is "tilted sideways" 45° whould then be rotated by my Y angle.

Here is some Python code:

viewer = CCamera ()
viewer.UpdateAngles (0,0,45) # bank 45°, i.e. tilt the scene 
viewer.UpdateAngles (0,10,0) # should rotate the scene sideways, simulating a change of heading

What happens is that the scene is rotated diagonally, i.e. around the Y axis of the "tilted" view angle.

import numpy as np

class CCamera:
    def __init__ (self, name = ""):
        self.orientation = CMatrix ()
        self.position = CVector (0,0,0)

    def Radians (self, a):
        if (a < 0):
            a += 360.0
        return a / 180.0 * np.pi

    def UpdateAngles (self, angles):
        m = CMatrix ()
        radX = self.Radians (angles.x)
        radY = self.Radians (angles.y)
        radZ = self.Radians (angles.z)
        m.CreateFromAngles (np.sin (radX), np.cos (radX), np.sin (radY), np.cos (radY), np.sin (radZ), np.cos (radZ))
        self.orientation *= m

CMatrix class:

class CMatrix:
    def __init__ (self):
        self.data = self.Identity ()

    def __getitem__ (self, index):
        return self.data [index]

    def __setitem__ (self, index, value):
        self.data [index] = value

    def Identity (self):
        return np.array ([CVector (1.0, 0.0, 0.0, 0.0), CVector (0.0, 1.0, 0.0, 0.0), CVector (0.0, 0.0, 1.0, 0.0), CVector (0.0, 0.0, 0.0, 1.0)])

    def Create (self, r, u, f):
        self.data = np.array ([r, u, f, CVector (0.0, 0.0, 0.0, 1.0)])
        return self

    def CreateFromAngles (self, sinX, cosX, sinY, cosY, sinZ, cosZ):
        return self.Create (CVector (cosY * cosZ, -cosY * sinZ, sinY),
                            CVector (sinX * sinY * cosZ + cosX * sinZ, 
                                     -sinX * sinY * sinZ + cosX * cosZ, 
                                     -sinX * cosY),
                            CVector (-cosX * sinY * cosZ + sinX * sinZ, 
                                     cosX * sinY * sinZ + sinX * cosZ, 
                                     cosX * cosY))

    def __imul__ (self, other):
        v = CVector (self [0].x, self [1].x, self [2].x)
        self [0].x = v.DotProduct (other [0])
        self [1].x = v.DotProduct (other [1])
        self [2].x = v.DotProduct (other [2])
        v = CVector (self [0].y, self [1].y, self [2].y)
        self [0].y = v.DotProduct (other [0])
        self [1].y = v.DotProduct (other [1])
        self [2].y = v.DotProduct (other [2])
        v = CVector (self [0].z, self [1].z, self [2].z)
        self [0].z = v.DotProduct (other [0])
        self [1].z = v.DotProduct (other [1])
        self [2].z = v.DotProduct (other [2])
        return self

Here are two pictures for illustration:

Rotation around Z axis (bank)

Rotation around Y axis (yaw)

What is my misunderstanding here? Shouldn't the second rotation rotate the tilted view matrix around the "absolute" Y axis?



from Recent Questions - Stack Overflow https://ift.tt/3zyUiee
https://ift.tt/3gMvKqv

No comments:

Post a Comment