roc/camera.py
2011-04-24 20:46:22 -06:00

190 lines
4.8 KiB
Python
Executable file

from gameobj import game_object
import math
from quat import *
from py3dutil import vect
from OpenGL.GL import *
import files
class game_camera(game_object):
def __init__(self):
self.tracking = None
game_object.__init__(self)
self.target_pos = self.pos.copy()
self.target_rot = self.rot.copy()
self.real_pos = self.pos.copy()
self.real_rot = self.rot.copy()
self.starbox = None
self.starboxes = []
def track(self, obj):
self.tracking = obj
self.target_at(obj, immediate=True)
def target_at(self, obj, immediate=False):
self.target_pos = obj.pos.copy()
desired_v = -self.get_camera_vector(obj.rot)
self.target_rot = quat(desired_v.x, desired_v.y, desired_v.z, 0.0)
self.target_rot = obj.rot.copy()
if immediate:
self.pos = obj.pos.copy()
self.rot = obj.rot.copy()
self.real_pos = obj.pos.copy()
self.real_rot = obj.rot.copy()
else:
self.camera_slew()
# apply translation vector to current position!
#print "Realrot: %s" % (self.real_rot,) #DELME
self.rot = self.real_rot
self.pos = self.real_pos + self.get_camera_vector(self.rot)
def get_camera_vector(self, rot):
camera_pitch = 15.0
camera_dist = 16.0
camera_pitch_axis = rot.get_conjugate() * vect(0.0, 1.0, 0.0)
camera_pitch_axis.normalize()
#print "Rot: %s" % (rot,) #DELME
# find the direction we want to be pointing (looking forward)
camera_v = (rot.get_conjugate() * vect(1.0, 0.0, 0.0))
# find the angle at which the camera should be pitched
camera_q = get_angle(camera_pitch, camera_pitch_axis)
# rotate the direction to include the pitch component
camera_v = camera_q * camera_v
# apply the distance to turn our unit vector into a translation vector
camera_v = camera_v.normalize() * -camera_dist
#print camera_v
return camera_v
def draw_starbox(self):
return
starbox = 'plain'
#starbox = 'test'
if starbox != self.starbox:
import sprite
self.starbox = starbox
self.starboxes = []
for i in range(6):
fn = 'img/starbox/starbox_%s_%d.png' % (starbox, i + 1)
f = files.mgr.open(fn)
self.starboxes.append(sprite.sprite_tex())
self.starboxes[i].set_file(f)
starbox_locs = [
(90.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 0.0, 1.0),
(270.0, 0.0, 0.0, 1.0),
(180.0, 0.0, 0.0, 1.0),
(90.0, 0.0, 0.0, 1.0),
(270.0, 1.0, 0.0, 0.0)
]
clr = (1.0, 1.0, 1.0, 1.0)
glDisable(GL_LIGHTING)
glDepthMask(0)
glMaterialfv(GL_FRONT, GL_AMBIENT, clr)
glMaterialfv(GL_FRONT, GL_DIFFUSE, clr)
glMaterialfv(GL_FRONT, GL_SPECULAR, clr)
glColor4f(*clr)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
fsize = 0.8
wsize = 1.1
fardist = 100.0
glFrustum(-wsize, wsize, -fsize, fsize, 2.0, fardist * 10.0)
#glOrtho(-1.0, 1.0, -1.0, 1.0, 0.1, fardist * 10.0)
glMatrixMode(GL_MODELVIEW)
for i in range(6):
glPushMatrix()
glRotatef(*starbox_locs[i])
if i == 0:
glRotatef(270.0, 0.0, 1.0, 0.0)
if i == 5:
glRotatef(90.0, 0.0, 1.0, 0.0)
glTranslatef(0.0, fardist, 0.0)
glScalef(fardist, fardist, fardist)
#glTranslatef(0.0, 100.0, 0.0)
#glScalef(100.0, 100.0, 100.0)
self.starboxes[i].render()
glPopMatrix()
glDepthMask(1)
glEnable(GL_LIGHTING)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
def calc_render_pos(self):
self.render_pos = vect(0.0, 0.0, 0.0)
def clear_render_pos(self):
self.render_pos = None
def render(self):
glPushMatrix()
glRotatef(90.0, 0.0, 0.0, 1.0)
glMultMatrixf(self.rot.get_conjugate().get_matrix())
self.draw_starbox()
#glTranslatef(*[-x for x in self.pos])
def update(self):
#return
if self.tracking != None:
self.target_at(self.tracking)
def camera_slew(self):
#return
currv = self.get_camera_vector(self.real_rot)
targv = self.get_camera_vector(self.target_rot)
currpos = self.real_pos + currv
targpos = self.target_pos + targv
currv.normalize()
targv.normalize()
rotdiff = currv.dot(targv)
if rotdiff != 0.0:
rotspeed = (math.sqrt(1.0 + rotdiff) - 1.0) / 10.0
maxrot = 25.0
if rotdiff > maxrot:
rotspeed += (rotdiff - maxrot)
amt = abs(rotspeed / rotdiff)
if amt >= 1.0:
self.real_rot = self.target_rot.copy()
elif amt < 1e-7:
self.real_rot = self.rot.copy()
else:
self.real_rot = self.rot.slerp(self.target_rot, amt)
d = currpos.dist(targpos)
if d != 0.0:
maxdist = 3.0
followspeed = (math.sqrt(1.0 + d) - 1.0)
#followspeed = 0.000001
if d > maxdist:
followspeed += d - maxdist
amt = abs(followspeed / d)
#print "%s, %s, %s" % (d, amt, followspeed)
if amt > 1.0 or amt < 1e-7:
self.real_pos = self.target_pos.copy()
else:
self.real_pos = self.real_pos.slerp(self.target_pos, amt)
#self.real_rot = self.real_rot * get_angle(90.0, vect(0.0, 0.0, 1.0))
def get_forward_vector(self):
return (self.rot * vect(1.0, 0.0, 0.0)).normalize()
def done(self):
glPopMatrix()