# PySoy's bodies.Camera class # # Copyright (C) 2006,2007,2008 PySoy Group # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program; if not, see http://www.gnu.org/licenses # # $Id$ cdef class Camera(Body) : '''soy.bodies.Camera A camera is an invisible object in 3d space through which the scene can be rendered through. It must be attached to a soy.widgets.Projector or other rendering class to be activated. ''' ########################################################################## # # Python Functions # def __cinit__(self, scene=None, position=None, rotation=None, velocity=None, model=None, shape=None, wireframe=0, *args, **keywords) : cdef int _i self._fovy = 45.0 self._znear = 1.0 self._zfar = 100.0 self.mass = 0 self._wire = wireframe self._rpt = 0 for _i from 0 <= _i < 16 : self._rtimes[_i] = 0.0 ############################################################################ # # Properties # property fps : def __get__(self) : cdef double f1, f2 f2 = self._rtimes[self._rpt] f1 = self._rtimes[(self._rpt + 1) % 16] if f1 == 0.0 or f2 == 0.0 or f1 == f2 : return 0.0 else : return 1 / (f2 - f1) * 15 property wireframe : def __get__(self) : return self._wire def __set__(self,value) : self._wire = value property lens : '''Camera Lens This is the (vertical) angle which the lens can view. Defaults to 45.0 ''' def __get__(self) : return self._fovy def __set__(self, value) : self._fovy = value property direction : '''Camera Direction Direction in which camera is looking ''' def __get__(self) : return ( self._rotation[2], self._rotation[6], self._rotation[10] ) property right : '''Camera Right Direction of the 'right' side of the camera ''' def __get__(self): return ( self._rotation[0], self._rotation[4], self._rotation[8] ) property up : '''Camera Up Direction of the up vector of the camera ''' def __get__(self): return ( self._rotation[1], self._rotation[5], self._rotation[9] ) ############################################################################ # # WindowLoop Functions # cdef void _project(self, gl.GLdouble _aspect) : cdef gl.GLfloat _mtx[16] # # Bail now if in the abyss if self._scene is None : return # # Check if wireframe mode is turned on if self._wire == 1 : #gl.glEnable (gl.GL_LINE_SMOOTH) #gl.glEnable (gl.GL_BLEND) #gl.glBlendFunc (gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) ## Anti-Aliasing maybe? #gl.glHint (gl.GL_LINE_SMOOTH_HINT, gl.GL_DONT_CARE) #gl.glLineWidth (3) gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) else : gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) #gl.glDisable (gl.GL_LINE_SMOOTH) #gl.glDisable (gl.GL_BLEND) #gl.glBlendFunc (gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) #gl.glHint (gl.GL_LINE_SMOOTH_HINT, gl.GL_DONT_CARE) #gl.glLineWidth (1) # # Now we apply an inverse matrix to translate to the Scene's origin gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() _mtx[0] = self._rotation[0] _mtx[1] = self._rotation[1] _mtx[2] = self._rotation[2] _mtx[3] = 0.0 _mtx[4] = self._rotation[4] _mtx[5] = self._rotation[5] _mtx[6] = self._rotation[6] _mtx[7] = 0.0 _mtx[8] = self._rotation[8] _mtx[9] = self._rotation[9] _mtx[10] = self._rotation[10] _mtx[11] = 0.0 _mtx[12] = 0.0 _mtx[13] = 0.0 _mtx[14] = 0.0 _mtx[15] = 1.0 gl.glLoadMatrixf(_mtx) gl.glTranslatef(-self._position[0], -self._position[1], -self._position[2]) self._scene._render(self._fovy, _aspect, self._znear, self._zfar) # # Framerate calc self._rpt = (self._rpt + 1) % 16 self._rtimes[self._rpt] = soy._internals._time()