pysoy
changeset 1758:fe48f01093f5
Added fog property from Scene.pym, deleting now obsolete Scene.pym
| author | Arc Riley <arcriley@gmail.com> |
|---|---|
| date | Mon, 12 Dec 2011 02:31:27 -0500 |
| parents | 58021b8791ec |
| children | 542901300d1c |
| files | src/scenes/Scene.c src/scenes/Scene.pym |
| diffstat | 2 files changed, 12 insertions(+), 390 deletions(-) [+] |
line diff
1.1 --- a/src/scenes/Scene.c Sun Dec 11 14:48:50 2011 -0500 1.2 +++ b/src/scenes/Scene.c Mon Dec 12 02:31:27 2011 -0500 1.3 @@ -89,11 +89,23 @@ 1.4 PYSOY_PROP_OBJECT_OWNED(scenes, scene, ambient, atoms_Color); 1.5 1.6 1.7 +static char 1.8 +fog_doc[] = "Scene fog\n" 1.9 +"\n" 1.10 +" This is a scene-wide layer of fog of which the density is set by the\n" 1.11 +" color's alpha channel.\n" 1.12 +"\n" 1.13 +" Defaults to Color('clear')\n" 1.14 +"\n"; 1.15 +PYSOY_PROP_OBJECT_OWNED(scenes, scene, fog, atoms_Color) 1.16 + 1.17 + 1.18 ///////////////////////////////////////////////////////////////////////////// 1.19 // Type structs 1.20 1.21 static PyGetSetDef tp_getset[] = { 1.22 PYSOY_PROPSTRUCT(ambient), 1.23 + PYSOY_PROPSTRUCT(fog), 1.24 {NULL} // sentinel 1.25 }; 1.26
2.1 --- a/src/scenes/Scene.pym Sun Dec 11 14:48:50 2011 -0500 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,390 +0,0 @@ 2.4 -# PySoy's scenes.Scene class 2.5 -# 2.6 -# Copyright (C) 2006,2007,2008,2009 PySoy Group 2.7 -# 2.8 -# This program is free software; you can redistribute it and/or modify 2.9 -# it under the terms of the GNU Affero General Public License as published 2.10 -# by the Free Software Foundation, either version 3 of the License, or 2.11 -# (at your option) any later version. 2.12 -# 2.13 -# This program is distributed in the hope that it will be useful, 2.14 -# but WITHOUT ANY WARRANTY; without even the implied warranty of 2.15 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.16 -# GNU Affero General Public License for more details. 2.17 -# 2.18 -# You should have received a copy of the GNU Affero General Public License 2.19 -# along with this program; if not, see http://www.gnu.org/licenses 2.20 -# 2.21 -# $Id: Scene.pym 1393 2008-12-31 23:51:25Z ArcRiley $ 2.22 -DEF GeomScene = 1 2.23 -DEF GeomBody = 2 2.24 -DEF GeomField = 4 2.25 -DEF GeomLight = 8 2.26 -DEF GeomGhost = 16 2.27 -cdef class Scene (soy._internals.Loopable) : 2.28 - '''PySoy Scene 2.29 - 2.30 - Scenes are containers in physics space for bodies. 2.31 - Objects in different scenes cannot interact, for example, 2.32 - bodies in two different scenes cannot collide. 2.33 - 2.34 - Scenes also apply gravity to bodies. 2.35 - 2.36 - ''' 2.37 - 2.38 - ############################################################################ 2.39 - # 2.40 - # Python functions 2.41 - # 2.42 - 2.43 - def __cinit__(self, *args, **kw) : 2.44 - from soy.colors import gray 2.45 - self._worldID = ode.dWorldCreate() 2.46 - self._spaceID = ode.dSimpleSpaceCreate(NULL) 2.47 - self._contactGroup = ode.dJointGroupCreate(0) 2.48 - self._bodies = soy._internals.Children() 2.49 - self._fields = soy._internals.Children() 2.50 - self._joints = soy._internals.Children() 2.51 - self._lights = soy._internals.Children() 2.52 - self._ambient = gray 2.53 - self._fogDensity = 0.0 2.54 - self._stepSize = 0.01 2.55 - self._friction = 0 2.56 - self._prevTime = _time() 2.57 - self._stepMutex = py.PyThread_allocate_lock() 2.58 - # a list cor keeping track of the fields in the scene. 2.59 - self._giveFields = soy._internals.PointerSet() 2.60 - # 2.61 - self._callFields = soy._internals.PointerSet() 2.62 - _scenes._append(<void*> self) 2.63 - 2.64 - 2.65 - def __dealloc__(self) : 2.66 - _scenes._remove(<void*> self) 2.67 - if self._worldID != NULL : 2.68 - ode.dWorldDestroy(self._worldID) 2.69 - if self._spaceID != NULL : 2.70 - ode.dSpaceDestroy(self._spaceID) 2.71 - 2.72 - 2.73 - def __repr__(self) : 2.74 - report = [] 2.75 - 2.76 - if self._bodies._current == 1 : 2.77 - report.append('1 body') 2.78 - else: 2.79 - report.append('%d bodies' % self._bodies._current) 2.80 - 2.81 - if self._lights._current == 1 : 2.82 - report.append('1 light') 2.83 - else : 2.84 - report.append('%d lights' % self._lights._current) 2.85 - 2.86 - return '<Scene with %s>' % ', '.join(report) 2.87 - 2.88 - ############################################################################ 2.89 - # 2.90 - # Properties 2.91 - # 2.92 - 2.93 - property fog : 2.94 - '''Scene fog 2.95 - 2.96 - This is a scene-wide layer of fog of which the density is set by you 2.97 - 2.98 - Takes a float for fog density from 0-2, fog is disabled when at 0. 2.99 - ''' 2.100 - def __get__(self) : 2.101 - return self._fogDensity 2.102 - 2.103 - def __set__(self, value) : 2.104 - assert type(value) == float and value <= 2 and value >= 0, \ 2.105 - "Fog density must be a float in the range of 0-2." 2.106 - self._fogDensity = value 2.107 - 2.108 - ############################################################################ 2.109 - # 2.110 - # C functions 2.111 - # 2.112 - 2.113 - cdef int _loop(self) nogil : 2.114 - cdef int _i, _steps 2.115 - self._time = _time() 2.116 - self._callFields._empty() 2.117 - self._giveFields._empty() 2.118 - # 2.119 - self._fields._iterStart() 2.120 - for _i from 0 <= _i < self._fields._current : 2.121 - # Make sure every field is in givefields & _give each one 2.122 - if not self._giveFields._has_key(self._fields._list[_i]) : 2.123 - (<soy.fields.Field> self._fields._list[_i])._give(0) 2.124 - self._giveFields._insert(self._fields._list[_i]) 2.125 - # 2.126 - for _i from 0 <= _i < self._fields._current : 2.127 - # Apply fields; add incompletly applied fields to the list 2.128 - if not (<soy.fields.Field> self._fields._list[_i])._apply() : 2.129 - pass 2.130 - #self._callFields._insert(self._fields.list[_i]) 2.131 - # 2.132 - # Apply any outstanding fields 2.133 - self._callFields._foreach(_runField, NULL) 2.134 - self._fields._iterDone() 2.135 - # 2.136 - self._stepLock() 2.137 - _steps = self._steps() 2.138 - for _i from 0 <= _i < _steps : 2.139 - self._time = _time() 2.140 - self._giveFields._foreach(_prerunField, NULL) 2.141 - self._callFields._empty() 2.142 - ode.dSpaceCollide(self._spaceID, <void*> self, 2.143 - <void(*)(void*, ode.dGeomID, ode.dGeomID) nogil> 2.144 - Scene._callback) 2.145 - ode.dWorldQuickStep(self._worldID, self._stepSize) 2.146 - ode.dJointGroupEmpty(self._contactGroup) 2.147 - if _i != 0 : 2.148 - self._callFields._foreach(_runField, NULL) 2.149 - self._stepUnLock() 2.150 - return 1 2.151 - 2.152 - 2.153 - cdef void _render(self, gl.GLdouble _fovy, gl.GLdouble _aspect, 2.154 - gl.GLdouble _znear, gl.GLdouble _zfar) : 2.155 - cdef int _i 2.156 - cdef gl.GLfloat _fogColor[4] 2.157 - _fogColor[0] = .5 2.158 - _fogColor[1] = .5 2.159 - _fogColor[2] = .5 2.160 - _fogColor[3] = 1.0 2.161 - # 2.162 - # Setup projection matrix 2.163 - gl.glMatrixMode(gl.GL_PROJECTION) 2.164 - gl.glLoadIdentity() 2.165 - gl.gluPerspective(_fovy, _aspect, _znear, _zfar) 2.166 - gl.glMatrixMode(gl.GL_MODELVIEW) 2.167 - # 2.168 - # Setup scene-level rendering 2.169 - gl.glClear(gl.GL_DEPTH_BUFFER_BIT) 2.170 - gl.glEnable(gl.GL_DEPTH_TEST) 2.171 - gl.glEnable(gl.GL_LIGHTING) 2.172 - gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, self._ambient._rgba) 2.173 - 2.174 - if self._fogDensity > 0 : 2.175 - # 2.176 - # Turn on some fog! 2.177 - gl.glClearColor(0.5,0.5,0.5,1.0) # We'll Clear To The Color Of The Fog ( Modified ) 2.178 - gl.glEnable(gl.GL_FOG) #Enables GL_FOG 2.179 - gl.glFogi(gl.GL_FOG_MODE, gl.GL_EXP2) #Fog Mode 2.180 - gl.glFogfv(gl.GL_FOG_COLOR, _fogColor) #Set Fog Color 2.181 - gl.glFogf(gl.GL_FOG_DENSITY, self._fogDensity/10) #How Dense Will The Fog Be 2.182 - gl.glHint(gl.GL_FOG_HINT, gl.GL_NICEST) #Fog Hint Value 2.183 - gl.glFogf(gl.GL_FOG_START, 1.0) #Fog Start Depth 2.184 - gl.glFogf(gl.GL_FOG_END, 50.0) #Fog End Depth 2.185 - 2.186 - # 2.187 - # Turn on each light, keep it's iteration locked against mod until done 2.188 - self._lights._iterStart() 2.189 - for _i from 0 <= _i < self._lights._current : 2.190 - # This is a quick hack (gl.GL_LIGHT0 + _i) 2.191 - (<soy.bodies.Light> self._lights._list[_i])._on(gl.GL_LIGHT0 + _i) 2.192 - 2.193 - 2.194 - 2.195 - # 2.196 - # Iterate over bodies 2.197 - self._bodies._iterStart() 2.198 - for _i from 0 <= _i < self._bodies._current : 2.199 - if (<soy.bodies.Body> self._bodies._list[_i])._model is not None : 2.200 - (<soy.models.Model> 2.201 - (<soy.bodies.Body> self._bodies._list[_i])._model)._render( 2.202 - (<soy.bodies.Body> self._bodies._list[_i])) 2.203 - self._bodies._iterDone() 2.204 - 2.205 - # 2.206 - # Turn off all lights and finish iteration loop 2.207 - for _i from 0 <= _i < self._lights._current : 2.208 - # This is a quick hack (gl.GL_LIGHT0 + _i) 2.209 - (<soy.bodies.Light> self._lights._list[_i])._off(gl.GL_LIGHT0 + _i) 2.210 - self._lights._iterDone() 2.211 - 2.212 - if self._fogDensity > 0 : 2.213 - gl.glDisable(gl.GL_FOG) 2.214 - gl.glDisable(gl.GL_LIGHTING) 2.215 - gl.glDisable(gl.GL_DEPTH_TEST) 2.216 - 2.217 - 2.218 - cdef int _steps(self) nogil : 2.219 - cdef int _step 2.220 - cdef double _lapsTime 2.221 - _lapsTime = _time() - self._prevTime 2.222 - if _lapsTime < math.FLT_EPSILON : 2.223 - _lapsTime = math.FLT_EPSILON 2.224 - _step = math.lround(_lapsTime / self._stepSize) 2.225 - if _step > 12 : 2.226 - _step = 12 2.227 - self._prevTime = self._prevTime + (_step * self._stepSize) 2.228 - return _step 2.229 - 2.230 - 2.231 - cdef void _stepLock(self) nogil : 2.232 - py.PyThread_acquire_lock(self._stepMutex,1) 2.233 - 2.234 - 2.235 - cdef int _stepTryLock(self) nogil : 2.236 - return py.PyThread_acquire_lock(self._stepMutex,0) 2.237 - 2.238 - 2.239 - cdef void _stepUnLock(self) nogil : 2.240 - py.PyThread_release_lock(self._stepMutex) 2.241 - 2.242 - 2.243 - cdef void _callback(self, ode.dGeomID _geomA, ode.dGeomID _geomB) nogil : 2.244 - cdef int _contactGeoms, _f, _i 2.245 - cdef ode.dJointID _joint 2.246 - cdef ode.dContact _contact 2.247 - cdef ode.dContactGeom _contactGeom[2] 2.248 - cdef ode.dGeomID _geomIDs[2] 2.249 - cdef ode.dBodyID _bodyIDs[2] 2.250 - 2.251 - # 2.252 - # Start by generating up to four contacts between 2 bodies 2.253 - _contactGeoms = ode.dCollide(_geomA, _geomB, 2, 2.254 - _contactGeom, sizeof(_contactGeom[0])) 2.255 - # 2.256 - # Don't waste time when there's no collision 2.257 - if _contactGeoms == 0 : 2.258 - return 2.259 - # 2.260 - # This makes case-testing much simpler in the code 2.261 - _geomIDs[0] = _geomA 2.262 - _geomIDs[1] = _geomB 2.263 - # 2.264 - # Scene Check 2.265 - for _i from 0 <= _i < 2 : 2.266 - if ode.dGeomGetCategoryBits(_geomIDs[_i]) == GeomScene : 2.267 - _bodyIDs[_i] = NULL 2.268 - #stdio.printf('Scene Collision %d\n', _i) 2.269 - else : 2.270 - _bodyIDs[_i] = ode.dGeomGetBody(_geomIDs[_i]) 2.271 - #stdio.printf('Body Collision %d %d\n', _i, _bodyIDs[_i]) 2.272 - # 2.273 - # Ghost Check 2.274 - for _i from 0 <= _i < 2 : 2.275 - if ode.dGeomGetCategoryBits(_geomIDs[_i]) == GeomGhost : 2.276 - #stdio.printf('Ghost Collision\n') 2.277 - _bodyIDs[(_i + 1) % 2] = NULL 2.278 - # 2.279 - # If we ended up with a null-null collision, just return now 2.280 - if _bodyIDs[0] == NULL and _bodyIDs[1] == NULL : 2.281 - #stdio.printf('Both bodies null, aborting\n') 2.282 - return 2.283 - # 2.284 - # Add each joint to the bodies we just determined 2.285 - for _i from 0 <= _i < _contactGeoms : 2.286 - _contact.geom = _contactGeom[_i] 2.287 - _contact.surface.mode = ode.dContactBounce 2.288 - _contact.surface.mu = self._friction 2.289 - _contact.surface.bounce = 0.8 2.290 - _contact.surface.bounce_vel = 0 2.291 - #stdio.printf('Creating joint\n') 2.292 - _joint = ode.dJointCreateContact(self._worldID, self._contactGroup, 2.293 - &_contact) 2.294 - #stdio.printf('Attaching joint\n') 2.295 - ode.dJointAttach(_joint, _bodyIDs[0], _bodyIDs[1]) 2.296 - #stdio.printf('Processed contact joint %d\n', _i) 2.297 - return 2.298 - 2.299 - ''' 2.300 - # This is the old code, mostly for fields. It needs to be merged into 2.301 - # the above but for now we're just testing Scene and Ghosts 2.302 - if _c > 0 : 2.303 - # Get the Body objects 2.304 - _bo1 = <soy.bodies.Body> ode.dBodyGetData(_b1) 2.305 - _bo2 = <soy.bodies.Body> ode.dBodyGetData(_b2) 2.306 - _f = 0 2.307 - # activate any fields present... 2.308 - if isinstance(_bo1, soy.fields.Field) : 2.309 - _f = 1 2.310 - if not (<soy.fields.Field> _bo1)._exert(_bo2) : 2.311 - self._callFields._insert(<void*> _bo1) 2.312 - if isinstance(_bo2, soy.fields.Field) : 2.313 - _f = 1 2.314 - if not (<soy.fields.Field> _bo2)._exert(_bo1) : 2.315 - self._callFields._insert(<void*> _bo2) 2.316 - # if neither shape is a field 2.317 - if _f == 0 : 2.318 - _ct.geom = _cg 2.319 - # surface parameters should have an exposed interface on soy.shapes.Shape 2.320 - # this code should pull parameters from there. 2.321 - _ct.surface.mode = ode.dContactBounce 2.322 - _ct.surface.bounce = 0.8 2.323 - _ct.surface.bounce_vel = 0 2.324 - _j = ode.dJointCreateContact(self._worldID, self._contactGroup, &_ct) 2.325 - ode.dJointAttach(_j, _b1, _b2) 2.326 - ''' 2.327 - 2.328 - ############################################################################ 2.329 - # 2.330 - # Properties 2.331 - # 2.332 - 2.333 - property gravity : 2.334 - '''Scene gravity 2.335 - 2.336 - This is a scene-wide pseudo-force drawing all bodies in a single 2.337 - direction. This should not be confused with a monopole force or other 2.338 - forces which are often used for gravity in larger scenes. 2.339 - 2.340 - Takes a (x,y,z) tuple of numbers, defaults to (0.0, 0.0, 0.0) 2.341 - ''' 2.342 - def __get__(self) : 2.343 - cdef ode.dVector3 grav 2.344 - ode.dWorldGetGravity(self._worldID, grav) 2.345 - return (grav[0], grav[1], grav[2]) 2.346 - def __set__(self, value) : 2.347 - ode.dWorldSetGravity(self._worldID, value[0], value[1], value[2]) 2.348 - 2.349 - 2.350 - property stepsize : 2.351 - '''Step Size 2.352 - 2.353 - This is the fraction of time each "step" calculates for. Larger steps 2.354 - trade accuracy for speed. 2.355 - 2.356 - Takes a float, defaults to .01 2.357 - ''' 2.358 - def __get__(self) : 2.359 - return self._stepSize 2.360 - def __set__(self, value) : 2.361 - self._stepLock() 2.362 - self._stepSize = value 2.363 - self._stepUnLock() 2.364 - 2.365 - 2.366 - property ambient : 2.367 - '''Scene's ambient light 2.368 - 2.369 - This is the ambient light for the scene. When no light is used this is 2.370 - the only light available in the scene - use it well. 2.371 - 2.372 - Defaults to :const:`soy.colors.gray` 2.373 - ''' 2.374 - def __get__(self) : 2.375 - return self._ambient 2.376 - def __set__(self, soy.colors.Color value) : 2.377 - self._ambient = value 2.378 - 2.379 - 2.380 - property friction : 2.381 - '''Scene's Friction 2.382 - 2.383 - This is the amount of friction given to ode's contact joint. 2.384 - 2.385 - Defaults to 0 ( Really Slippery ) 2.386 - ''' 2.387 - def __get__(self) : 2.388 - return self._friction 2.389 - def __set__(self, value) : 2.390 - if isinstance(value, int): 2.391 - self._friction = value 2.392 - else: 2.393 - raise TypeError("Friction must be an int of some sort")
