# PySoy's bodies.Light 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 Light (Body) : '''soy.bodies.Light Lights provide illumination in your scene. Needs more work. ''' ############################################################################ # # Python Functions # def __cinit__(self, scene=None, radius=180.0, ambient=None, diffuse=None, specular=None, *args, **keywords) : self.radius = radius self.ambient = ambient self.mass = 0 self.diffuse = diffuse self.specular = specular if self._scene is not None : self._scene._lights._append( self) ############################################################################ # # Properties # property ambient : def __get__(self) : return self._ambient def __set__(self, value) : if value == None : from soy.colors import black self._ambient = black elif isinstance(value, soy.colors.Color) : self._ambient = value else : raise TypeError('color must be an instance of soy.colors.Color') property diffuse : def __get__(self) : return self._diffuse def __set__(self, value) : if value == None : from soy.colors import gray self._diffuse = gray elif isinstance(value, soy.colors.Color) : self._diffuse = value else : raise TypeError('color must be an instance of soy.colors.Color') property radius : def __get__(self) : return self._radius def __set__(self, value) : if type(value) != float and type(value) != int : raise TypeError('Light.radius must be a float or int') if value < 0.0 or value > 180.0 : raise ValueError('Light.radius must be 0.0 - 180.0') self._radius = value property specular : def __get__(self) : return self._specular def __set__(self, value) : if value == None : from soy.colors import white self._specular = white elif isinstance(value, soy.colors.Color) : self._specular = value else : raise TypeError('color must be an instance of soy.colors.Color') ############################################################################ # # General C Functions # cdef void _append(self) : # # this overrides Body._append to also append self to self._scene._lights # self._scene._bodies._append( self) self._scene._lights._append( self) # ###################################### cdef void _remove(self) : # # this overrides Body._remove to also remove self from self._scene._lights # self._scene._bodies._remove( self) self._scene._lights._remove( self) # ###################################### ############################################################################ # # WindowLoop Functions # cdef void _on(self, int _id) nogil : cdef gl.GLfloat _position[4] # # we do this only because glLightfv takes four parameters _position[0] = self._position[0] _position[1] = self._position[1] _position[2] = self._position[2] _position[3] = 1.0 # # enable the light of the given _id gl.glEnable(_id) gl.glLightfv(_id, gl.GL_AMBIENT, ( self._ambient)._rgba) gl.glLightfv(_id, gl.GL_DIFFUSE, ( self._diffuse)._rgba) gl.glLightfv(_id, gl.GL_SPECULAR, ( self._specular)._rgba) gl.glLightfv(_id, gl.GL_POSITION, _position) # # for spotlights gl.glLightf (_id, gl.GL_SPOT_CUTOFF, self._radius) #if self._radius != 180.0 : # TODO, Ticket #947 : # gl.glLightf (_id, gl.GL_SPOT_EXPODENT, [[0-128, default 0]]) # gl.glLightfv(_id, gl.GL_SPOT_DIRECTION, [[direction, as per Body]]) cdef void _off(self, int _id) nogil : gl.glDisable(_id)