# PySoy's scenes.Planar
#
# 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 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see http://www.gnu.org/licenses
#
# $Id: Planar.pxi 972 2008-02-24 03:10:01Z DavidCzech $
DEF GeomScene = 1
DEF GeomBody = 2
DEF GeomField = 4
DEF GeomLight = 8
cdef Vert midpoint(Vert a,Vert b):
X = 0.5*(a.px+b.px)
Y = 0.5*(a.py+b.py)
Z = 0.5*(a.pz+b.pz)
cdef Vert res
res.px=X
res.py=Y
res.pz=Z
return res
cdef class Planar (Scene) :
''' Planar Scene
This is a scene based on a collision plane of infinite size facing up in
the direction of gravity.
'''
# Notes
# http://www.pysoy.org/ticket/928
# axis for gravity
# http://www.ode.org/ode-latest-userguide.html#sec_10_7_3
# plane and heightfield are the only geoms which collide with everything as
# expected EXCEPT themselves and each other
#
# Don't try to get the same effect by setting a very high mass/inertia on
# the ``motionless'' body and then resetting it's position/orientation on
# each time step. This can cause unexpected simulation errors.
def __cinit__(self,offset=0, *args, **kw) :
self._offset = offset
self._planeID = ode.dCreatePlane(self._spaceID, 0.0, 1.0, 0.0, self._offset)
ode.dGeomSetCategoryBits(self._planeID,GeomScene)
ode.dGeomSetData(self._planeID, <void*> self)
cdef Vert _a, _b, _c, _d, _e, _f
SIZE = 40
self._verts[0].px = SIZE
self._verts[0].py = 0.0
self._verts[0].pz = -SIZE
self._verts[1].px = 0.0
self._verts[1].py = 0.0
self._verts[1].pz = SIZE
self._verts[2].px = -SIZE
self._verts[2].py = 0.0
self._verts[2].pz = -SIZE
_a = self._verts[0]
_b = self._verts[1]
_c = self._verts[2]
cdef int _i
for _i from 1 <= _i < 15 :
_d = midpoint(_a,_b)
_e = midpoint(_b,_c)
_f = midpoint(_c,_a)
self._verts[((_i*3)-2)+2] = _d
self._verts[((_i*3)-1)+2] = _e
self._verts[(_i*3)+2] = _f
self._faces[_i].a = ((_i*3)-2)+2
self._faces[_i].b = ((_i*3))+2
self._faces[_i].c = ((_i*3)-1)+2
_a = _d
_b = _e
_c = _f
stdio.printf("test %d",(_i*3)+2)
self._faces[0].a = 0
self._faces[0].b = 2
self._faces[0].c = 1
def __delalloc__(self) :
ode.dGeomDestroy(self._planeID)
cdef void _coreRender(self) :
#gl.glDisable(gl.GL_DEPTH_BUFFER)
gl.glVertexPointer (3, gl.GL_FLOAT, 48, &self._verts[0].px)
gl.glNormalPointer ( gl.GL_FLOAT, 48, &self._verts[0].nx)
gl.glTexCoordPointer(3, gl.GL_FLOAT, 48, &self._verts[0].tx)
#self._coreGetModelview(mtx)
#gl.glPushMatrix()
#gl.glMultMatrixf(mtx)
#(<soy.meshes.Mesh> self._mesh)._coreRender(<void *> self)#Faces go here?
#gl.glPopMatrix()
gl.glDrawElements (gl.GL_TRIANGLES, 60, gl.GL_UNSIGNED_SHORT,
<unsigned short *> self._faces)
#gl.glEnable(gl.GL_DEPTH_BUFFER)
Scene._coreRender(self)
#gl.glEnable(gl.GL_DEPTH_BUFFER)
property gravity :
'''Scene gravity
This is a scene-wide pseudo-force drawing all bodies in a single
direction. This should not be confused with a monopole force or other
forces which are often used for gravity in larger scenes.
Takes a (x,y,z) tuple of numbers, defaults to (0.0, 0.0, 0.0)
'''
def __get__(self) :
cdef ode.dVector3 grav
ode.dWorldGetGravity(self._worldID, grav)
return (grav[0], grav[1], grav[2])
def __set__(self, value) :
cdef ode.dVector3 normal
normal[0] = -(value[0])
normal[1] = -(value[1])
normal[2] = -(value[2])
if len(value) == 4:
stdio.printf("4 Values! using the fourth one as offset")
print value[3]
self._offset = value[3]
ode.dGeomDestroy(self._planeID)
ode.dNormalize3(normal)
self._planeID = ode.dCreatePlane(self._spaceID, normal[0],normal[1],normal[2], self._offset)
ode.dGeomSetCategoryBits(self._planeID,GeomScene)
ode.dGeomSetData(self._planeID, <void*> self)
ode.dWorldSetGravity(self._worldID, value[0], value[1], value[2])