import math import time from OpenGL.GL import * from OpenGL.GLU import * from dusk.defs import TILE_WIDTH, TILE_HEIGHT, TILE_DEPTH, RPG_CAMERA_PIXELS_PER_UNIT, RPG_CAMERA_Z_OFFSET, RPG_CAMERA_FOV class Camera: def __init__(self, parent): self.parent = parent self.pixelsPerUnit = RPG_CAMERA_PIXELS_PER_UNIT self.yOffset = RPG_CAMERA_Z_OFFSET self.fov = RPG_CAMERA_FOV self.scale = 8.0 self.lastTime = time.time() self.lookAtTarget = [0.0, 0.0, 0.0] def setup(self, vw, vh, duration=0.1): now = time.time() delta = now - self.lastTime self.lastTime = now # Calculate ease factor for exponential smoothing over 'duration' seconds ease = 1 - math.exp(-delta / duration) z = (vh / 2.0) / ( (self.pixelsPerUnit * self.scale) * math.tan(math.radians(self.fov / 2.0)) ) lookAt = [ self.parent.map.position[0] * TILE_WIDTH, self.parent.map.position[1] * TILE_HEIGHT, self.parent.map.position[2] * TILE_DEPTH, ] aspectRatio = vw / vh # Ease the lookAt target for i in range(3): self.lookAtTarget[i] += (lookAt[i] - self.lookAtTarget[i]) * ease # Camera position is now based on the eased lookAtTarget cameraPosition = ( self.lookAtTarget[0], self.lookAtTarget[1] + self.yOffset, self.lookAtTarget[2] + z ) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(self.fov, aspectRatio, 0.1, 1000.0) glScalef(1.0, -1.0, 1.0) # Flip the projection matrix upside down glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt( cameraPosition[0], cameraPosition[1], cameraPosition[2], self.lookAtTarget[0], self.lookAtTarget[1], self.lookAtTarget[2], 0.0, 1.0, 0.0 )