190 lines
4.8 KiB
Python
190 lines
4.8 KiB
Python
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()
|
|
|
|
|
|
|
|
|