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()