# PySoy's models.Shape class # # Copyright (C) 2006,2007,2008,2009 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: Shape.pym 1393 2008-12-31 23:51:25Z ArcRiley $ cdef class Shape (Model) : '''soy.models.Shape This :class:`~soy.models.Model` renders the shape of the body it belongs to. ''' ############################################################################ # # Python functions # def __cinit__(self, material=None, *args, **keywords) : self.material = material ############################################################################ # # Properties # property material : def __get__(self) : return self._material def __set__(self, value) : if value is None : self._material = soy.materials.StainlessSteel() elif isinstance(value, soy.materials.Material) : self._material = value else : raise TypeError('Must provide an instance of soy.materials.Material') ############################################################################ # # WindowLoop Functions # cdef void _render(self, soy.bodies.Body _body) : cdef int _shapeclass cdef gl.GLfloat _mtx[16] # ###################################### # # Don't attempt to render a non-existant shape # if _body._shape is None : return # ###################################### # # save current matrix # gl.glPushMatrix() # ###################################### # # set model's matrix # _mtx[0] = _body._rotation[0] _mtx[1] = _body._rotation[4] _mtx[2] = _body._rotation[8] _mtx[3] = 0.0 _mtx[4] = _body._rotation[1] _mtx[5] = _body._rotation[5] _mtx[6] = _body._rotation[9] _mtx[7] = 0.0 _mtx[8] = _body._rotation[2] _mtx[9] = _body._rotation[6] _mtx[10] = _body._rotation[10] _mtx[11] = 0.0 _mtx[12] = _body._position[0] _mtx[13] = _body._position[1] _mtx[14] = _body._position[2] _mtx[15] = 1.0 gl.glMultMatrixf(_mtx) # ###################################### # # Grab the shape's class _shapeclass = ode.dGeomGetClass(_body._shape._geomID) # ###################################### # # render the specific shape # if _shapeclass == ode.dSphereClass : self._renderSphere(_body._shape) elif _shapeclass == ode.dCapsuleClass : self._renderCapsule(_body._shape) elif _shapeclass == ode.dBoxClass : self._renderBox(_body._shape) elif _shapeclass == ode.dRayClass : self._renderRay(_body._shape) # ###################################### # # restore previous matrix # gl.glPopMatrix() # ###################################### cdef void _renderSphere(self, soy.shapes.Shape _shape) : cdef int _pass cdef gl.GLUquadricObj* _quadric _pass = 0 while self._material._render(_pass, 24, 24) : _pass += 1 _quadric = gl.gluNewQuadric() gl.gluQuadricNormals(_quadric, gl.GLU_SMOOTH) gl.gluQuadricTexture(_quadric, gl.GL_FALSE) gl.gluSphere(_quadric, _shape._radius(), 32, 32) gl.gluDeleteQuadric(_quadric) cdef void _renderCapsule(self, soy.shapes.Shape _shape) : cdef int _pass cdef ode.dReal r, l cdef gl.GLUquadricObj* _quadric _pass = 0 while self._material._render(_pass, 24, 24) : _pass += 1 ode.dGeomCapsuleGetParams(_shape._geomID, &r, &l) _quadric = gl.gluNewQuadric() gl.gluQuadricNormals(_quadric, gl.GLU_SMOOTH) gl.gluQuadricTexture(_quadric, gl.GL_FALSE) gl.glPushMatrix() gl.glTranslatef(0.0, 0.0, -l * 0.5) gl.gluCylinder(_quadric, r, r, l, 32, 32) gl.gluSphere(_quadric, r, 32, 32) gl.glPushMatrix() gl.glTranslatef(0.0, 0.0, l) gl.gluSphere(_quadric, r, 32, 32) gl.glPopMatrix() gl.glPopMatrix() gl.gluDeleteQuadric(_quadric) cdef void _renderBox(self, soy.shapes.Shape _shape) : cdef int _pass cdef ode.dVector3 _xyz _pass = 0 while self._material._render(_pass, 24, 24) : _pass += 1 ode.dGeomBoxGetLengths(_shape._geomID, _xyz) gl.glPushMatrix() gl.glScalef(_xyz[0], _xyz[1], _xyz[2]) gl.glBegin(gl.GL_QUADS) gl.glNormal3f( 0.0, 0.0, 1.0) gl.glVertex3f(-0.5, -0.5, 0.5) gl.glVertex3f( 0.5, -0.5, 0.5) gl.glVertex3f( 0.5, 0.5, 0.5) gl.glVertex3f(-0.5, 0.5, 0.5) gl.glNormal3f( 0.0, 0.0,-1.0) gl.glVertex3f(-0.5, -0.5, -0.5) gl.glVertex3f(-0.5, 0.5, -0.5) gl.glVertex3f( 0.5, 0.5, -0.5) gl.glVertex3f( 0.5, -0.5, -0.5) gl.glNormal3f( 0.0, 1.0, 0.0) gl.glVertex3f(-0.5, 0.5, -0.5) gl.glVertex3f(-0.5, 0.5, 0.5) gl.glVertex3f( 0.5, 0.5, 0.5) gl.glVertex3f( 0.5, 0.5, -0.5) gl.glNormal3f( 0.0,-1.0, 0.0) gl.glVertex3f(-0.5, -0.5, -0.5) gl.glVertex3f( 0.5, -0.5, -0.5) gl.glVertex3f( 0.5, -0.5, 0.5) gl.glVertex3f(-0.5, -0.5, 0.5) gl.glNormal3f( 1.0, 0.0, 0.0) gl.glVertex3f( 0.5, -0.5, -0.5) gl.glVertex3f( 0.5, 0.5, -0.5) gl.glVertex3f( 0.5, 0.5, 0.5) gl.glVertex3f( 0.5, -0.5, 0.5) gl.glNormal3f(-1.0, 0.0, 0.0) gl.glVertex3f(-0.5, -0.5, -0.5) gl.glVertex3f(-0.5, -0.5, 0.5) gl.glVertex3f(-0.5, 0.5, 0.5) gl.glVertex3f(-0.5, 0.5, -0.5) gl.glEnd() gl.glPopMatrix() cdef void _renderRay(self, soy.shapes.Shape _shape) : cdef int _pass cdef float _l cdef ode.dVector3 _s, _d _pass = 0 while self._material._render(_pass, 24, 24) : _pass += 1 ode.dGeomRayGet(_shape._geomID, _s, _d) _l = ode.dGeomRayGetLength(_shape._geomID) gl.glPushAttrib(gl.GL_LIGHTING_BIT) gl.glDisable(gl.GL_LIGHTING) gl.glBegin(gl.GL_LINES) gl.glVertex3f(_s[0], _s[1], _s[2]) gl.glVertex3f(_s[0] + _d[0] * _l, _s[1] + _d[0] * _l, _s[2] + _d[0] * _l) gl.glEnd() gl.glPopAttrib()