#!/usr/bin/env python # # Copyright (C) 2006 Chris Skalenda # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # #imports to get OpenGL and other things we need import string from math import * from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import sys name = 'Imagine it\'s a Borg cube or something. Scary!' rotate_x = 0 rotate_y = 0 rotate_z = 0 coords_x = 0 coords_y = 0 coords_z = 0 mouse_x = 0 mouse_y = 0 mouse_z = 0 mouse_start_x = 0 mouse_start_y = 0 coord_last_x = 0 coord_last_y = 0 azimuth_x = 10 azimuth_z = 10 polar = 0 azimuth = 0 incidence = 0 def main(): glutInit(sys.argv) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) glutInitWindowSize(400,400) glutCreateWindow(name) glClearColor(0.,0.,0.,1.) glEnable(GL_CULL_FACE) # Setup callback functions glutDisplayFunc(display) glutKeyboardFunc(processKeys) glutMouseFunc(processMouse) glMatrixMode(GL_PROJECTION) gluPerspective(40.,1.,10.,160.) glMatrixMode(GL_MODELVIEW) glutMainLoop() return def display(): global rotate_x, rotate_y, rotate_z global coords_x, coords_y, coords_z global mouse_x, mouse_y, mouse_z global azimuth_x, azimuth_z, incidence global azimuth glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) glPushMatrix() # Translate based on the accumulated mouse movements glTranslatef(mouse_x*-.1,mouse_y*.1,mouse_z*.1) # Translate based on keyboard input glTranslatef(coords_x,coords_y,coords_z) # The azimuth rotation is handled by rotating the camera location, # while maintaining the same eye location gluLookAt(azimuth_x, 0, azimuth_z, 0, 0, 0, 0, 1, 0) # Cross the azimuth vector (which is pointed toward the camera) # with a unit vector along the y axis to gain a vector orthogonal # to the camera rotation vector in the x-z plane. This allows the # object to rotate directly toward the camera despite changes # in the azimuth vector. glRotatef(-incidence, 0*0 - cos(azimuth)*1, # v1y * v2z - v1z * v2y cos(azimuth)*0 - sin(azimuth)*0, # v1z * v2x - v1x * v2z sin(azimuth)*1 - 0*0) # v1x * v2y - v1y * v2x # Rotate based on the accumulated rotation value glRotatef(rotate_x,1.,0.,0.) glRotatef(rotate_y,0.,1.,0.) glRotatef(rotate_z,0.,0.,1.) # Front glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(-2,2,2) glColor3f(0., .5, .5) glVertex3d(-2,-2,2) glColor3f(5., 0., .5) glVertex3d(2,-2,2) glColor3f(5., 5., .2) glVertex3d(2,2,2) glEnd() # Left side glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(-2,-2,-2) glColor3f(0., .5, .5) glVertex3d(-2,-2,2) glColor3f(5., 0., .5) glVertex3d(-2,2,2) glColor3f(5., 5., .2) glVertex3d(-2,2,-2) glEnd() # Right side glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(2,2,-2) glColor3f(0., .5, .5) glVertex3d(2,2,2) glColor3f(5., 0., .5) glVertex3d(2,-2,2) glColor3f(5., 5., .2) glVertex3d(2,-2,-2) glEnd() # Top glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(-2,2,-2) glColor3f(0., .5, .5) glVertex3d(-2,2,2) glColor3f(5., 0., .5) glVertex3d(2,2,2) glColor3f(5., 5., .2) glVertex3d(2,2,-2) glEnd() # Back glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(-2,2,-2) glColor3f(0., .5, .5) glVertex3d(2,2,-2) glColor3f(5., 0., .5) glVertex3d(2,-2,-2) glColor3f(5., 5., .2) glVertex3d(-2,-2,-2) glEnd() # Bottom glBegin(GL_POLYGON) glColor3f(.5, .5, 0.) glVertex3d(-2,-2,-2) glColor3f(0., .5, .5) glVertex3d(2,-2,-2) glColor3f(5., 0., .5) glVertex3d(2,-2,2) glColor3f(5., 5., .2) glVertex3d(-2,-2,2) glEnd() glPopMatrix() glutSwapBuffers() return def processKeys(key, x, y): global rotate_x, rotate_y, rotate_z, coords_x, coords_y, coords_z, polar if key == 'r': rotate_x = (rotate_x + 5)%360 elif key == 'f': rotate_y = (rotate_y + 5)%360 elif key == 'v': rotate_z = (rotate_z + 5)%360 elif key == 't': coords_x += 0.1 elif key == 'g': coords_x -= 0.1 elif key == 'b': coords_y += 0.1 elif key == 'y': coords_y -= 0.1 elif key == 'h': coords_z += 0.1 elif key == 'n': coords_z -= 0.1 elif key == 'p': polar = 1 elif key == 'c': polar = 0 display() return def processMouse(button, state, x, y): global mouse_start_xr, mouse_start_y # Check if button is pressed down, so the motion callbacks can be set # accordingly. This way, different callbacks are set for each button if state == GLUT_DOWN: mouse_start_x = x mouse_start_y = y if button == 0: if polar == 0: glutMotionFunc(processLeftMotion) elif polar == 1: glutMotionFunc(processPolarMotion) elif button == 2: glutMotionFunc(processRightMotion) return def processLeftMotion(x, y): global mouse_x, mouse_y, mouse_z global mouse_start_x, mouse_start_y global coord_last_x, coord_last_y if coord_last_y == 0: coord_last_x = mouse_start_x coord_last_y = mouse_start_y # Handling x mouse movements if coord_last_x < x: mouse_x += 1 elif coord_last_x > x: mouse_x -= 1 # And the same for y if coord_last_y < y: mouse_y += 1 elif coord_last_y > y: mouse_y -= 1 coord_last_x = x coord_last_y = y display() return def processRightMotion(x, y): global mouse_z, mouse_x, mouse_start_y # Zoom! mouse_z = y - mouse_start_y display() return def processPolarMotion(x, y): global azimuth_x, azimuth_z global mouse_start_x, mouse_start_y global coord_last_x, coord_last_y global azimuth, incidence # set the last coordinates initially if coord_last_y == 0: coord_last_x = mouse_start_x coord_last_y = mouse_start_y if coord_last_x < x: # Add 1 to the camera degree rotated around y azimuth -= .05 elif coord_last_x > x: # Remove 1 from the camera degree rotated around y azimuth += .05 if coord_last_y < y: incidence += 2 elif coord_last_y > y: incidence -= 2 # finding a constant magnitude vector to move the camera to the end of. # yay trig! azimuth_x = sin(azimuth)*15 azimuth_z = cos(azimuth)*15 coord_last_x = x coord_last_y = y display() return if __name__ == '__main__': main()