I'm trying to make a simple mouse look with standard arrow key movement, and I've got the mouselook working but the translations from the rotated points seem to move along an orthogonal basis, but not one that is aligned with the rotation of the mouselook. I can't tell if my math is off or if opengl is doing something extra to transform the points and I need to adjust. I looked at the modelview matrix and it appears to be following the same order of rotations but I'm just stuck here, I'm not sure if it has something to do with the perspective or what is happening really. I'm not the best with linear algebra so it's got me stuck a bit.
import pygame
import pygameMenu as pgm
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
verticies = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 1),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)
edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7)
)
class OGl():
def three_func(a,b,func):
return (func(a[0],b[0]),func(a[1],b[1]),func(a[2],b[2]))
class GLCamera():
def __init__(self):
self.pos = [0.0,0.0,10.0]
self.rot = [0.0,0.0,0.0]
self.rotating = False
self.mouse_pos = [0,0]
def add_to_scene(self):
#buffer = glGetDouble( GL_MODELVIEW_MATRIX )
#print(buffer)
glRotatef(self.rot[2], 0, 0, 1); # roll
glRotatef(self.rot[1], 0, 1, 0); # heading
glRotatef(self.rot[0], 1, 0, 0); # pitch
glTranslatef(-self.pos[0],-self.pos[1],-self.pos[2]);
def change_of_basis(self):
#skip roll for now
c=np.cos(self.rot[1]*(np.pi/180))
s=np.sin(self.rot[1]*(np.pi/180))
m1=np.array([[c,0,s],[0,1,0],[-s,0,c]])
c=np.cos(self.rot[0]*(np.pi/180))
s=np.sin(self.rot[0]*(np.pi/180))
m2=np.array([[1,0,0],[0,c,-s],[0,s,c]])
m=m1.dot(m2)
return m
def handle_camera_events(self,event):
if event.type == pygame.KEYDOWN:
cb = self.change_of_basis()
if event.key == pygame.K_f:
m=cb.dot(np.array([0,0,-0.5]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.key == pygame.K_g:
m=cb.dot(np.array([0,0,0.5]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.key == pygame.K_LEFT:
m=cb.dot(np.array([-0.5,0,0]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.key == pygame.K_RIGHT:
m=cb.dot(np.array([0.5,0,0]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.key == pygame.K_DOWN:
m=cb.dot(np.array([0,-0.5,0]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.key == pygame.K_UP:
m=cb.dot(np.array([0,0.5,0]))
self.pos=OGl.three_func(self.pos,m, lambda x,y : x+y )
if event.type == pygame.MOUSEMOTION and self.rotating:
tmp_pos = pygame.mouse.get_pos()
x,y = self.mouse_pos[0] - tmp_pos[0], self.mouse_pos[1] - tmp_pos[1]
if x != 0 or y != 0:
self.rot[1] = (self.rot[1] + x)
self.rot[0] = (self.rot[0] + y)
self.mouse_pos = tmp_pos
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
if self.rotating == False:
self.rotating = True
self.mouse_pos = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
self.rotating = False
def Cube():
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
camera = GLCamera()
while True:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
camera.add_to_scene()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
camera.handle_camera_events(event)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube()
pygame.display.flip()
pygame.time.wait(10)
main()