Home > Enterprise >  how to drag camera with the mouse like in blender
how to drag camera with the mouse like in blender

Time:12-18

i've found a program that you can move around the camera with the mouse in pyopengl, by doing some things i dont fully undesthand

from pygame.locals import *
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


def cube():
    vertices = (
        (1,-1,-1),
        (1,1,-1),
        (-1,1,-1),
        (-1,-1,-1),
        (1,-1,1),
        (1,1,1),
        (-1,-1,1),
        (-1,1,1)
    )
    edegs = (
        (0,1),
        (0,3),
        (0,4),
        (2,1),
        (2,3),
        (2,7),
        (6,3),
        (6,4),
        (6,7),
        (5,1),
        (5,4),
        (5,7),
    )
    glBegin(GL_LINES)
    glColor3fv((1,1,1))
    for edeg in edegs:
        for vertex in edeg:
            glVertex3fv(vertices[vertex])
    glEnd()
pygame.init()
screen = (800,600)
pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)
glMatrixMode(GL_PROJECTION)

gluPerspective(45, (screen[0]/screen[1]), 0.1, 50.0)

glTranslate(0.0,0.0,-5)
glMatrixMode(GL_MODELVIEW)  
modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

busy = True
button_down = False
zoom = -0.5
while True:
    glPushMatrix()
    glLoadIdentity()

    for event in pygame.event.get():
        if(event.type == pygame.QUIT):
            pygame.quit()
            busy = False
        elif event.type == pygame.MOUSEMOTION:
            if(button_down):
                glRotatef(event.rel[1], 1, 0, 0)
                glRotatef(event.rel[0], 0, 1, 0)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:
                zoom  = 0.2
            if event.button == 5:
                zoom -= 0.2
    if(not busy): break
    for event in pygame.mouse.get_pressed():
        if pygame.mouse.get_pressed()[0] == 1:
            button_down = True
        elif pygame.mouse.get_pressed()[0] == 0:
            button_down = False
            
    #mouse scroll
    
            
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glMultMatrixf(modelMatrix)
    modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

    glLoadIdentity()
    glTranslatef(0.0,0.0,zoom)
    
    glMultMatrixf(modelMatrix)

    cube()

    
    glPopMatrix()
    
        

    pygame.display.flip()
    pygame.time.wait(10)

But as you drag the object around it starts to lose the top to bottom orientation unlike programs like blender and sketchup, is there a way to fix that or another way to manipulate the camera?

CodePudding user response:

Just sum up the rotation around the x-axis and the rotation around the y-axis. First rotate around the y-axis and than around the x-axis:

modelview = translate * rotateY * raotateX

Complete example:

from pygame.locals import *
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

def cube():
    vertices = (
        (1,-1,-1), (1,1,-1), (-1,1,-1), (-1,-1,-1),
        (1,-1,1), (1,1,1), (-1,-1,1), (-1,1,1)
    )
    edegs = (
        (0,1), (0,3), (0,4), (2,1), (2,3), (2,7),
        (6,3), (6,4), (6,7), (5,1), (5,4), (5,7),
    )
    glBegin(GL_LINES)
    glColor3fv((1,1,1))
    for edeg in edegs:
        for vertex in edeg:
            glVertex3fv(vertices[vertex])
    glColor3fv((1,0,0))    
    glVertex3f(0, -2, 0)  
    glVertex3f(0, 2, 0)    
    glEnd()

pygame.init()
screen = (400, 300)
pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)

glEnable(GL_DEPTH_TEST)

glMatrixMode(GL_PROJECTION)
gluPerspective(45, (screen[0]/screen[1]), 0.1, 50.0)

glMatrixMode(GL_MODELVIEW)  
glTranslate(0.0,0.0,-5)

rot_x, rot_y, zoom = 0, 0, -0.5

clock = pygame.time.Clock()
busy = True
while busy:

    mouse_buttons = pygame.mouse.get_pressed()
    button_down = mouse_buttons[0] == 1
   
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            busy = False
        elif event.type == pygame.MOUSEMOTION:
            if button_down:
                rot_x  = event.rel[1]
                rot_y  = event.rel[0]
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:
                zoom  = 0.2
            if event.button == 5:
                zoom -= 0.2
            
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

    glPushMatrix()
    glTranslatef(0.0,0.0, zoom)
    glRotatef(rot_x, 1, 0, 0)    
    glRotatef(rot_y, 0, 1, 0)    
    cube()
    glPopMatrix()
    
    pygame.display.flip()
    clock.tick(100)

pygame.quit()

See also How to implement alt MMB camera rotation like in 3ds max?, How to implement camera pan like in 3dsMax?, How to implement zoom towards mouse like in 3dsMax?.

  • Related