You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(33) |
Aug
(9) |
Sep
(2) |
Oct
(4) |
Nov
(13) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
(2) |
Jun
(7) |
Jul
(2) |
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
(3) |
2006 |
Jan
(2) |
Feb
|
Mar
|
Apr
(3) |
May
(2) |
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
(8) |
Dec
|
2007 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(13) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
2009 |
Jan
|
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Matthias B. <mb...@us...> - 2004-07-29 09:48:10
|
Update of /cvsroot/pyode/pyode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3756 Modified Files: INSTALL Log Message: Installation instructions for the new Pyrex version Index: INSTALL =================================================================== RCS file: /cvsroot/pyode/pyode/INSTALL,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** INSTALL 11 Feb 2003 14:55:32 -0000 1.1.1.1 --- INSTALL 29 Jul 2004 09:48:01 -0000 1.2 *************** *** 1,228 **** ! Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software ! Foundation, Inc. ! ! This file is free documentation; the Free Software Foundation gives ! unlimited permission to copy, distribute and modify it. ! ! Basic Installation ! ================== ! ! These are generic installation instructions. ! ! The `configure' shell script attempts to guess correct values for ! various system-dependent variables used during compilation. It uses ! those values to create a `Makefile' in each directory of the package. ! It may also create one or more `.h' files containing system-dependent ! definitions. Finally, it creates a shell script `config.status' that ! you can run in the future to recreate the current configuration, and a ! file `config.log' containing compiler output (useful mainly for ! debugging `configure'). ! ! It can also use an optional file (typically called `config.cache' ! and enabled with `--cache-file=config.cache' or simply `-C') that saves ! the results of its tests to speed up reconfiguring. (Caching is ! disabled by default to prevent problems with accidental use of stale ! cache files.) ! ! If you need to do unusual things to compile the package, please try ! to figure out how `configure' could check whether to do them, and mail ! diffs or instructions to the address given in the `README' so they can ! be considered for the next release. If you are using the cache, and at ! some point `config.cache' contains results you don't want to keep, you ! may remove or edit it. ! ! The file `configure.ac' (or `configure.in') is used to create ! `configure' by a program called `autoconf'. You only need ! `configure.ac' if you want to change it or regenerate `configure' using ! a newer version of `autoconf'. ! ! The simplest way to compile this package is: ! ! 1. `cd' to the directory containing the package's source code and type ! `./configure' to configure the package for your system. If you're ! using `csh' on an old version of System V, you might need to type ! `sh ./configure' instead to prevent `csh' from trying to execute ! `configure' itself. ! ! Running `configure' takes awhile. While running, it prints some ! messages telling which features it is checking for. ! ! 2. Type `make' to compile the package. ! ! 3. Optionally, type `make check' to run any self-tests that come with ! the package. ! ! 4. Type `make install' to install the programs and any data files and ! documentation. ! ! 5. You can remove the program binaries and object files from the ! source code directory by typing `make clean'. To also remove the ! files that `configure' created (so you can compile the package for ! a different kind of computer), type `make distclean'. There is ! also a `make maintainer-clean' target, but that is intended mainly ! for the package's developers. If you use it, you may have to get ! all sorts of other programs in order to regenerate files that came ! with the distribution. ! ! Compilers and Options ! ===================== ! ! Some systems require unusual options for compilation or linking that ! the `configure' script does not know about. Run `./configure --help' ! for details on some of the pertinent environment variables. ! ! You can give `configure' initial values for variables by setting ! them in the environment. You can do that on the command line like this: ! ! ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix ! ! *Note Defining Variables::, for more details. ! ! Compiling For Multiple Architectures ! ==================================== ! ! You can compile the package for more than one kind of computer at the ! same time, by placing the object files for each architecture in their ! own directory. To do this, you must use a version of `make' that ! supports the `VPATH' variable, such as GNU `make'. `cd' to the ! directory where you want the object files and executables to go and run ! the `configure' script. `configure' automatically checks for the ! source code in the directory that `configure' is in and in `..'. ! ! If you have to use a `make' that does not support the `VPATH' ! variable, you have to compile the package for one architecture at a ! time in the source code directory. After you have installed the ! package for one architecture, use `make distclean' before reconfiguring ! for another architecture. ! ! Installation Names ! ================== ! ! By default, `make install' will install the package's files in ! `/usr/local/bin', `/usr/local/man', etc. You can specify an ! installation prefix other than `/usr/local' by giving `configure' the ! option `--prefix=PATH'. ! ! You can specify separate installation prefixes for ! architecture-specific files and architecture-independent files. If you ! give `configure' the option `--exec-prefix=PATH', the package will use ! PATH as the prefix for installing programs and libraries. ! Documentation and other data files will still use the regular prefix. ! ! In addition, if you use an unusual directory layout you can give ! options like `--bindir=PATH' to specify different values for particular ! kinds of files. Run `configure --help' for a list of the directories ! you can set and what kinds of files go in them. ! ! If the package supports it, you can cause programs to be installed ! with an extra prefix or suffix on their names by giving `configure' the ! option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. ! ! Optional Features ! ================= ! ! Some packages pay attention to `--enable-FEATURE' options to ! `configure', where FEATURE indicates an optional part of the package. ! They may also pay attention to `--with-PACKAGE' options, where PACKAGE ! is something like `gnu-as' or `x' (for the X Window System). The ! `README' should mention any `--enable-' and `--with-' options that the ! package recognizes. ! ! For packages that use the X Window System, `configure' can usually ! find the X include and library files automatically, but if it doesn't, ! you can use the `configure' options `--x-includes=DIR' and ! `--x-libraries=DIR' to specify their locations. ! ! Specifying the System Type ! ========================== ! ! There may be some features `configure' cannot figure out ! automatically, but needs to determine by the type of machine the package ! will run on. Usually, assuming the package is built to be run on the ! _same_ architectures, `configure' can figure that out, but if it prints ! a message saying it cannot guess the machine type, give it the ! `--build=TYPE' option. TYPE can either be a short name for the system ! type, such as `sun4', or a canonical name which has the form: ! ! CPU-COMPANY-SYSTEM ! ! where SYSTEM can have one of these forms: ! ! OS KERNEL-OS ! ! See the file `config.sub' for the possible values of each field. If ! `config.sub' isn't included in this package, then this package doesn't ! need to know the machine type. ! ! If you are _building_ compiler tools for cross-compiling, you should ! use the `--target=TYPE' option to select the type of system they will ! produce code for. ! ! If you want to _use_ a cross compiler, that generates code for a ! platform different from the build platform, you should specify the ! "host" platform (i.e., that on which the generated programs will ! eventually be run) with `--host=TYPE'. ! ! Sharing Defaults ! ================ ! ! If you want to set default values for `configure' scripts to share, ! you can create a site shell script called `config.site' that gives ! default values for variables like `CC', `cache_file', and `prefix'. ! `configure' looks for `PREFIX/share/config.site' if it exists, then ! `PREFIX/etc/config.site' if it exists. Or, you can set the ! `CONFIG_SITE' environment variable to the location of the site script. ! A warning: not all `configure' scripts look for a site script. ! Defining Variables ! ================== ! Variables not defined in a site shell script can be set in the ! environment passed to `configure'. However, some packages may run ! configure again during the build, and the customized values of these ! variables may be lost. In order to avoid this problem, you should set ! them in the `configure' command line, using `VAR=value'. For example: ! ./configure CC=/usr/local2/bin/gcc ! will cause the specified gcc to be used as the C compiler (unless it is ! overridden in the site shell script). - `configure' Invocation - ====================== ! `configure' recognizes the following options to control how it ! operates. ! `--help' ! `-h' ! Print a summary of the options to `configure', and exit. ! `--version' ! `-V' ! Print the version of Autoconf used to generate the `configure' ! script, and exit. ! `--cache-file=FILE' ! Enable the cache: use and save the results of the tests in FILE, ! traditionally `config.cache'. FILE defaults to `/dev/null' to ! disable caching. ! `--config-cache' ! `-C' ! Alias for `--cache-file=config.cache'. ! `--quiet' ! `--silent' ! `-q' ! Do not print messages saying which checks are being made. To ! suppress all normal output, redirect it to `/dev/null' (any error ! messages will still be shown). - `--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. ! `configure' also accepts some other, not widely useful, options. Run ! `configure --help' for more details. --- 1,39 ---- ! Installation instructions for all systems ! ========================================= ! Requirements: ! ------------- ! - Python v2.2 (or higher) ! http://www.python.org/ ! - Pyrex 0.9.3 (or higher) ! http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/ ! - ODE 0.5 ! http://ode.org/ ! Installation: ! ------------- ! The package uses the Python distutils, so you can build it by calling ! python setup.py build ! and install it by calling ! python setup.py install ! which installs the package on your system. ! See the "Installing Python Modules" manual inside your Python documentation ! or at http://docs.python.org/inst/inst.html if you want to customize the ! build process or the target location. ! Note: It is assumed that the ODE library is already compiled and installed ! somewhere on your system. In the setup script there's a variable ODE_BASE ! that points to the base ODE directory. It might be possible that you have ! to modify this variable so that it points to the actual location on your ! system. |
From: Timothy S. <pe...@us...> - 2004-07-28 18:38:19
|
Update of /cvsroot/pyode/pyode/xode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1457/xode Modified Files: geom.py Log Message: Fixed bug where Geoms were already inserted into a space before encapsulating in a GeomTransform. Index: geom.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/geom.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** geom.py 16 Jul 2004 11:45:17 -0000 1.1 --- geom.py 28 Jul 2004 18:38:10 -0000 1.2 *************** *** 81,115 **** if (obj is None): raise errors.InvalidError('No geom type element found.') ! if (not obj.placeable()): ! # Non-placeable geoms cannot be attached to bodies or be ! # transformed ! self._parser.pop() ! return ! if (self._body is None): ! # The Geom is independant so it can have its own transform ! ! t = self.getTransform() ! obj.setPosition(t.getPosition()) ! obj.setRotation(t.getRotation()) ! elif (self._transformed): ! # The Geom is attached to a body so to transform it, it must ! # by placed in a GeomTransform and its transform is relative ! # to the body. ! t = self.getTransform(self._body) ! obj.setPosition(t.getPosition()) ! obj.setRotation(t.getRotation()) ! ! trans = ode.GeomTransform(self._space) ! trans.setGeom(obj) ! trans.setBody(self._body.getODEObject()) ! ! self.setODEObject(trans) ! else: ! obj.setBody(self._body.getODEObject()) ! self._parser.pop() def _parseGeomBox(self, attrs): --- 81,124 ---- if (obj is None): raise errors.InvalidError('No geom type element found.') + + self._parser.pop() ! def _setObject(self, kclass, *args): ! """ ! Create the Geom object and apply transforms. Only call for placeable ! Geoms. ! """ ! ! if (self._body is None): ! # The Geom is independant so it can have its own transform ! obj = kclass(*((self._space,) + args)) ! t = self.getTransform() ! obj.setPosition(t.getPosition()) ! obj.setRotation(t.getRotation()) ! self.setODEObject(obj) ! ! elif (self._transformed): ! # The Geom is attached to a body so to transform it, it must ! # by placed in a GeomTransform and its transform is relative ! # to the body. ! ! obj = kclass(*((None,) + args)) ! ! t = self.getTransform(self._body) ! obj.setPosition(t.getPosition()) ! obj.setRotation(t.getRotation()) ! ! trans = ode.GeomTransform(self._space) ! trans.setGeom(obj) ! trans.setBody(self._body.getODEObject()) ! ! self.setODEObject(trans) ! else: ! obj = kclass(*((self._space,) + args)) ! obj.setBody(self._body.getODEObject()) ! self.setODEObject(obj) def _parseGeomBox(self, attrs): *************** *** 128,132 **** lz = float(attrs['sizez']) ! self.setODEObject(ode.GeomBox(self._space, (lx, ly, lz))) self._parser.push(startElement=start, endElement=end) --- 137,141 ---- lz = float(attrs['sizez']) ! self._setObject(ode.GeomBox, (lx, ly, lz)) self._parser.push(startElement=start, endElement=end) *************** *** 145,149 **** length = float(attrs['length']) ! self.setODEObject(ode.GeomCCylinder(self._space, radius, length)) self._parser.push(startElement=start, endElement=end) --- 154,158 ---- length = float(attrs['length']) ! self._setObject(ode.GeomCCylinder, radius, length) self._parser.push(startElement=start, endElement=end) *************** *** 161,165 **** radius = float(attrs['radius']) ! self.setODEObject(ode.GeomSphere(self._space, radius)) self._parser.push(startElement=start, endElement=end) --- 170,174 ---- radius = float(attrs['radius']) ! self._setObject(ode.GeomSphere, radius) self._parser.push(startElement=start, endElement=end) |
From: Matthias B. <mb...@us...> - 2004-07-28 16:03:18
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4462 Modified Files: geoms.pyx Log Message: Doc string updates Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** geoms.pyx 28 Jul 2004 07:27:09 -0000 1.6 --- geoms.pyx 28 Jul 2004 16:03:09 -0000 1.7 *************** *** 185,190 **** def getSpace(self): ! """Return the space that contains the geom. ! Return the space that the given geometry is contained in, or return None if it is not contained in any space.""" --- 185,190 ---- def getSpace(self): ! """getSpace() -> Space ! Return the space that the given geometry is contained in, or return None if it is not contained in any space.""" *************** *** 248,252 **** # GeomSphere cdef class GeomSphere(GeomObject): ! """Sphere object. """ --- 248,258 ---- # GeomSphere cdef class GeomSphere(GeomObject): ! """Sphere geometry. ! ! This class represents a sphere centered at the origin. ! ! Constructor:: ! ! GeomSphere(space=None, radius=1.0) """ *************** *** 311,315 **** # GeomBox cdef class GeomBox(GeomObject): ! """Box object. """ --- 317,327 ---- # GeomBox cdef class GeomBox(GeomObject): ! """Box geometry. ! ! This class represents a box centered at the origin. ! ! Constructor:: ! ! GeomBox(space=None, lengths=(1.0, 1.0, 1.0)) """ *************** *** 364,371 **** # GeomPlane cdef class GeomPlane(GeomObject): ! """Plane object. This object can't be attached to a body. If you call getBody() on this object it always returns ode.environment. """ --- 376,391 ---- # GeomPlane cdef class GeomPlane(GeomObject): ! """Plane geometry. ! ! This class represents an infinite plane. The plane equation is: ! n.x*x + n.y*y + n.z*z = dist This object can't be attached to a body. If you call getBody() on this object it always returns ode.environment. + + Constructor:: + + GeomPlane(space=None, normal=(0,0,1), dist=0) + """ *************** *** 418,422 **** # GeomCCylinder cdef class GeomCCylinder(GeomObject): ! """Capped cylinder object. """ --- 438,451 ---- # GeomCCylinder cdef class GeomCCylinder(GeomObject): ! """Capped cylinder geometry. ! ! This class represents a capped cylinder aligned along the local Z axis ! and centered at the origin. ! ! Constructor:: ! ! GeomCCylinder(space=None, radius=0.5, length=1.0) ! ! The length parameter does not include the caps. """ *************** *** 472,475 **** --- 501,514 ---- cdef class GeomRay(GeomObject): """Ray object. + + A ray is different from all the other geom classes in that it does + not represent a solid object. It is an infinitely thin line that + starts from the geom's position and extends in the direction of + the geom's local Z-axis. + + Constructor:: + + GeomRay(space=None, rlen=1.0) + """ *************** *** 521,524 **** --- 560,567 ---- "E", allowing E to be positioned and rotated arbitrarily with respect to its point of reference. + + Constructor:: + + GeomTransform(space=None) """ *************** *** 631,634 **** --- 674,681 ---- stores the actual mesh. This object has to be passed as first argument to the constructor. + + Constructor:: + + GeomTriMesh(data, space=None) """ |
From: Matthias B. <mb...@us...> - 2004-07-28 07:27:19
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23647/src Modified Files: geoms.pyx Log Message: Check the geom argument to setGeom() Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** geoms.pyx 27 Jul 2004 15:19:03 -0000 1.5 --- geoms.pyx 28 Jul 2004 07:27:09 -0000 1.6 *************** *** 557,568 **** return id ! def setGeom(self, geom): """setGeom(geom) ! Set the geom that the geometry transform encapsulates. The geom must ! not be inserted into any space, and must not be associated with any ! body. """ cdef long id id = geom._id() --- 557,579 ---- return id ! def setGeom(self, GeomObject geom not None): """setGeom(geom) ! Set the geom that the geometry transform encapsulates. ! A ValueError exception is thrown if a) the geom is not placeable, ! b) the geom was already inserted into a space or c) the geom is ! already associated with a body. ! ! @param geom: Geom object to encapsulate ! @type geom: GeomObject """ cdef long id + + if not geom.placeable(): + raise ValueError, "Only placeable geoms can be encapsulated by a GeomTransform" + if dGeomGetSpace(geom.gid)!=<dSpaceID>0: + raise ValueError, "The encapsulated geom was already inserted into a space." + if dGeomGetBody(geom.gid)!=<dBodyID>0: + raise ValueError, "The encapsulated geom is already associated with a body." id = geom._id() *************** *** 592,595 **** --- 603,608 ---- @type mode: int """ + if mode<0 or mode>1: + raise ValueError, "Invalid information mode (%d). Must be either 0 or 1."%mode dGeomTransformSetInfo(self.gid, mode) |
From: Matthias B. <mb...@us...> - 2004-07-27 15:19:14
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14817 Modified Files: declarations.pyx geoms.pyx Log Message: Added setInfo()/getInfo() and a few doc strings to the GeomTransform class Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** geoms.pyx 19 Jul 2004 15:02:05 -0000 1.4 --- geoms.pyx 27 Jul 2004 15:19:03 -0000 1.5 *************** *** 517,520 **** --- 517,524 ---- cdef class GeomTransform(GeomObject): """GeomTransform. + + A geometry transform "T" is a geom that encapsulates another geom + "E", allowing E to be positioned and rotated arbitrarily with + respect to its point of reference. """ *************** *** 530,533 **** --- 534,540 ---- sid = sp.sid self.gid = dCreateGeomTransform(sid) + # Set cleanup mode to 0 as a contained geom will be deleted + # by its Python wrapper class + dGeomTransformSetCleanup(self.gid, 0) # if space!=None: # space._addgeom(self) *************** *** 551,554 **** --- 558,567 ---- def setGeom(self, geom): + """setGeom(geom) + + Set the geom that the geometry transform encapsulates. The geom must + not be inserted into any space, and must not be associated with any + body. + """ cdef long id *************** *** 558,563 **** --- 571,611 ---- def getGeom(self): + """getGeom() -> GeomObject + + Get the geom that the geometry transform encapsulates. + """ return self.geom + def setInfo(self, int mode): + """setInfo(mode) + + Set the "information" mode of the geometry transform. + + With mode 0, when a transform object is collided with another + object, the geom field of the ContactGeom structure is set to the + geom that is encapsulated by the transform object. + + With mode 1, the geom field of the ContactGeom structure is set + to the transform object itself. + + @param mode: Information mode (0 or 1) + @type mode: int + """ + dGeomTransformSetInfo(self.gid, mode) + + def getInfo(self): + """getInfo() -> int + + Get the "information" mode of the geometry transform (0 or 1). + + With mode 0, when a transform object is collided with another + object, the geom field of the ContactGeom structure is set to the + geom that is encapsulated by the transform object. + + With mode 1, the geom field of the ContactGeom structure is set + to the transform object itself. + """ + return dGeomTransformGetInfo(self.gid) + include "trimeshdata.pyx" Index: declarations.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/declarations.pyx,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** declarations.pyx 24 Jul 2004 11:53:38 -0000 1.5 --- declarations.pyx 27 Jul 2004 15:19:03 -0000 1.6 *************** *** 347,350 **** --- 347,352 ---- void dGeomTransformSetCleanup (dGeomID g, int mode) int dGeomTransformGetCleanup (dGeomID g) + void dGeomTransformSetInfo (dGeomID g, int mode) + int dGeomTransformGetInfo (dGeomID g) int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip) |
From: Timothy S. <pe...@us...> - 2004-07-24 11:53:47
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15552/src Modified Files: declarations.pyx trimeshdata.pyx Log Message: Changed dGeomTriMeshDataBuildSingle to dGeomTriMeshDataBuildSingle1. Index: trimeshdata.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/trimeshdata.pyx,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** trimeshdata.pyx 19 Jul 2004 15:02:05 -0000 1.1 --- trimeshdata.pyx 24 Jul 2004 11:53:38 -0000 1.2 *************** *** 66,68 **** # Pass the data to ODE # dGeomTriMeshDataBuildSimple(self.tmdid, self.vertex_buffer, numverts, self.face_buffer, numfaces) ! dGeomTriMeshDataBuildSingle(self.tmdid, self.vertex_buffer, 3*sizeof(dReal), numverts, self.face_buffer, numfaces, 3*sizeof(int), NULL) --- 66,68 ---- # Pass the data to ODE # dGeomTriMeshDataBuildSimple(self.tmdid, self.vertex_buffer, numverts, self.face_buffer, numfaces) ! dGeomTriMeshDataBuildSingle1(self.tmdid, self.vertex_buffer, 3*sizeof(dReal), numverts, self.face_buffer, numfaces, 3*sizeof(int), NULL) Index: declarations.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/declarations.pyx,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** declarations.pyx 19 Jul 2004 14:57:40 -0000 1.4 --- declarations.pyx 24 Jul 2004 11:53:38 -0000 1.5 *************** *** 353,357 **** dTriMeshDataID dGeomTriMeshDataCreate() void dGeomTriMeshDataDestroy(dTriMeshDataID g) ! void dGeomTriMeshDataBuildSingle (dTriMeshDataID g, void* Vertices, int VertexStride, int VertexCount, void* Indices, int IndexCount, --- 353,357 ---- dTriMeshDataID dGeomTriMeshDataCreate() void dGeomTriMeshDataDestroy(dTriMeshDataID g) ! void dGeomTriMeshDataBuildSingle1 (dTriMeshDataID g, void* Vertices, int VertexStride, int VertexCount, void* Indices, int IndexCount, |
From: Matthias B. <mb...@us...> - 2004-07-19 15:02:15
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13551 Modified Files: geoms.pyx Added Files: trimeshdata.pyx Log Message: Initial trimesh support --- NEW FILE: trimeshdata.pyx --- # TriMeshData cdef class TriMeshData: """This class stores the mesh data. """ cdef dTriMeshDataID tmdid cdef dReal* vertex_buffer cdef int* face_buffer def __new__(self): self.tmdid = dGeomTriMeshDataCreate() self.vertex_buffer = NULL self.face_buffer = NULL def __dealloc__(self): if self.tmdid!=NULL: dGeomTriMeshDataDestroy(self.tmdid) if self.vertex_buffer!=NULL: free(self.vertex_buffer) if self.face_buffer!=NULL: free(self.face_buffer) def build(self, verts, faces): """build(verts, faces) @param verts: Vertices @type verts: Sequence of 3-sequences of floats @param faces: Face definitions (three indices per face) @type faces: Sequence of 3-sequences of ints """ cdef int numverts cdef int numfaces cdef dReal* vp cdef int* fp cdef int a,b,c numverts = len(verts) numfaces = len(faces) # Allocate the vertex and face buffer self.vertex_buffer = <dReal*>malloc(numverts*3*sizeof(dReal)) self.face_buffer = <int*>malloc(numfaces*3*sizeof(int)) # Fill the vertex buffer vp = self.vertex_buffer for v in verts: vp[0] = v[0] vp[1] = v[1] vp[2] = v[2] # vp[3] = 0 vp = vp+3 # Fill the face buffer fp = self.face_buffer for f in faces: a = f[0] b = f[1] c = f[2] if a<0 or b<0 or c<0 or a>=numverts or b>=numverts or c>=numverts: raise ValueError, "Vertex index out of range" fp[0] = a fp[1] = b fp[2] = c fp = fp+3 # Pass the data to ODE # dGeomTriMeshDataBuildSimple(self.tmdid, self.vertex_buffer, numverts, self.face_buffer, numfaces) dGeomTriMeshDataBuildSingle(self.tmdid, self.vertex_buffer, 3*sizeof(dReal), numverts, self.face_buffer, numfaces, 3*sizeof(int), NULL) Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** geoms.pyx 13 Jul 2004 16:44:18 -0000 1.3 --- geoms.pyx 19 Jul 2004 15:02:05 -0000 1.4 *************** *** 296,300 **** def pointDepth(self, p): ! """pointDepth() -> float Return the depth of the point p in the sphere. Points inside --- 296,300 ---- def pointDepth(self, p): ! """pointDepth(p) -> float Return the depth of the point p in the sphere. Points inside *************** *** 349,353 **** def pointDepth(self, p): ! """pointDepth() -> float Return the depth of the point p in the box. Points inside the --- 349,353 ---- def pointDepth(self, p): ! """pointDepth(p) -> float Return the depth of the point p in the box. Points inside the *************** *** 403,407 **** def pointDepth(self, p): ! """pointDepth() -> float Return the depth of the point p in the plane. Points inside the --- 403,407 ---- def pointDepth(self, p): ! """pointDepth(p) -> float Return the depth of the point p in the plane. Points inside the *************** *** 456,460 **** def pointDepth(self, p): ! """pointDepth() -> float Return the depth of the point p in the cylinder. Points inside the --- 456,460 ---- def pointDepth(self, p): ! """pointDepth(p) -> float Return the depth of the point p in the cylinder. Points inside the *************** *** 561,562 **** --- 561,630 ---- + include "trimeshdata.pyx" + + # GeomTriMesh + cdef class GeomTriMesh(GeomObject): + """TriMesh object. + + To construct the trimesh geom you need a TriMeshData object that + stores the actual mesh. This object has to be passed as first + argument to the constructor. + """ + + # Keep a reference to the data + cdef TriMeshData data + + def __new__(self, TriMeshData data not None, space=None): + cdef Space sp + cdef dSpaceID sid + + self.data = data + + sid=NULL + if space!=None: + sp = space + sid = sp.sid + self.gid = dCreateTriMesh(sid, data.tmdid, NULL, NULL, NULL) + + _geom_c2py_lut[<long>self.gid] = self + + + def __init__(self, TriMeshData data not None, space=None): + self.space = space + self.body = None + + def placeable(self): + return True + + def _id(self): + cdef long id + id = <long>self.gid + return id + + def clearTCCache(self): + """clearTCCache() + + Clears the internal temporal coherence caches. + """ + dGeomTriMeshClearTCCache(self.gid) + + def getTriangle(self, int idx): + """getTriangle(idx) -> (v0, v1, v2) + + @param idx: Triangle index + @type idx: int + """ + + cdef dVector3 v0, v1, v2 + cdef dVector3* vp0 + cdef dVector3* vp1 + cdef dVector3* vp2 + + vp0 = <dVector3*>v0 + vp1 = <dVector3*>v1 + vp2 = <dVector3*>v2 + + dGeomTriMeshGetTriangle(self.gid, idx, vp0, vp1, vp2) + return ((v0[0],v0[1],v0[2]), (v1[0],v1[1],v1[2]), (v2[0],v2[1],v2[2])) + + |
From: Matthias B. <mb...@us...> - 2004-07-19 14:57:50
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12807 Modified Files: declarations.pyx Log Message: Add most trimesh declarations Index: declarations.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/declarations.pyx,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** declarations.pyx 12 Jul 2004 17:30:08 -0000 1.3 --- declarations.pyx 19 Jul 2004 14:57:40 -0000 1.4 *************** *** 39,42 **** --- 39,44 ---- cdef struct dxJointGroup: int _dummy + cdef struct dxTriMeshData: + int _dummy # Types *************** *** 47,50 **** --- 49,53 ---- ctypedef dxJoint* dJointID ctypedef dxJointGroup* dJointGroupID + ctypedef dxTriMeshData* dTriMeshDataID ctypedef dReal dVector3[4] ctypedef dReal dVector4[4] *************** *** 347,348 **** --- 350,380 ---- int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip) + # Trimesh + dTriMeshDataID dGeomTriMeshDataCreate() + void dGeomTriMeshDataDestroy(dTriMeshDataID g) + void dGeomTriMeshDataBuildSingle (dTriMeshDataID g, void* Vertices, + int VertexStride, int VertexCount, + void* Indices, int IndexCount, + int TriStride, void* Normals) + + void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, + dReal* Vertices, int VertexCount, + int* Indices, int IndexCount) + + dGeomID dCreateTriMesh (dSpaceID space, dTriMeshDataID Data, + void* Callback, + void* ArrayCallback, + void* RayCallback) + + void dGeomTriMeshSetData (dGeomID g, dTriMeshDataID Data) + + void dGeomTriMeshClearTCCache (dGeomID g) + + void dGeomTriMeshGetTriangle (dGeomID g, int Index, dVector3 *v0, + dVector3 *v1, dVector3 *v2) + + void dGeomTriMeshGetPoint (dGeomID g, int Index, dReal u, dReal v, + dVector3 Out) + + void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) + int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) |
From: Matthias B. <mb...@us...> - 2004-07-19 14:56:51
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12697 Modified Files: ode.pyx Log Message: Increased maximum number of contact points Index: ode.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/ode.pyx,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ode.pyx 12 Jul 2004 17:30:08 -0000 1.4 --- ode.pyx 19 Jul 2004 14:56:42 -0000 1.5 *************** *** 165,169 **** """ ! cdef dContactGeom c[10] cdef long id1 cdef long id2 --- 165,169 ---- """ ! cdef dContactGeom c[150] cdef long id1 cdef long id2 *************** *** 174,178 **** id2 = geom2._id() ! n = dCollide(<dGeomID>id1, <dGeomID>id2, 10, c, sizeof(dContactGeom)) res = [] i=0 --- 174,178 ---- id2 = geom2._id() ! n = dCollide(<dGeomID>id1, <dGeomID>id2, 150, c, sizeof(dContactGeom)) res = [] i=0 |
From: Timothy S. <pe...@us...> - 2004-07-16 11:45:28
|
Update of /cvsroot/pyode/pyode/xode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24225/xode Modified Files: body.py joint.py node.py parser.py transform.py Added Files: errors.py geom.py Removed Files: xode.py Log Message: xode/ * Added Geom parser. * Fixed some mistakes in transform.py. * Moved exception classes from parser.py to errors.py. examples/ * Added the xml encoding attribute to the XODE document in tutorial2.py * Added an example to demonstrate XODE's transform features. tests/ * Added Geom tests to test_xode.py. --- NEW FILE: geom.py --- # XODE Importer for PyODE # Copyright (C) 2004 Timothy Stranex """ XODE Geom Parser @author: U{Timothy Stranex<mailto:ti...@st...>} """ import ode import errors, node, joint, body, transform class Geom(node.TreeNode): """ Represents an C{ode.Geom} object and corresponds to the <geom> tag. """ def __init__(self, name, parent): node.TreeNode.__init__(self, name, parent) self._space = self.getFirstAncestor(ode.Space).getODEObject() self._transformed = False try: self._body = self.getFirstAncestor(ode.Body) except node.AncestorNotFoundError: self._body = None def takeParser(self, parser): """ Handle further parsing. It should be called immediately after the <geom> tag has been encountered. """ self._parser = parser self._parser.push(startElement=self._startElement, endElement=self._endElement) def _startElement(self, name, attrs): nodeName = attrs.get('name', None) if (name == 'transform'): t = transform.Transform() t.takeParser(self._parser, self, attrs) self._transformed = True elif (name == 'box'): self._parseGeomBox(attrs) elif (name == 'cappedCylinder'): self._parseGeomCCylinder(attrs) elif (name == 'cone'): raise NotImplementedError() elif (name == 'cylinder'): raise NotImplementedError() elif (name == 'plane'): self._parseGeomPlane(attrs) elif (name == 'ray'): self._parseGeomRay(attrs) elif (name == 'sphere'): self._parseGeomSphere(attrs) elif (name == 'trimesh'): raise NotImplementedError() elif (name == 'geom'): g = Geom(nodeName, self) g.takeParser(self._parser) elif (name == 'body'): b = body.Body(nodeName, self, attrs) b.takeParser(self._parser) elif (name == 'joint'): j = joint.Joint(nodename, self) j.takeParser(self._parser) elif (name == 'jointgroup'): pass elif (name == 'ext'): pass else: raise errors.ChildError('geom', name) def _endElement(self, name): if (name == 'geom'): obj = self.getODEObject() if (obj is None): raise errors.InvalidError('No geom type element found.') if (not obj.placeable()): # Non-placeable geoms cannot be attached to bodies or be # transformed self._parser.pop() return if (self._body is None): # The Geom is independant so it can have its own transform t = self.getTransform() obj.setPosition(t.getPosition()) obj.setRotation(t.getRotation()) elif (self._transformed): # The Geom is attached to a body so to transform it, it must # by placed in a GeomTransform and its transform is relative # to the body. t = self.getTransform(self._body) obj.setPosition(t.getPosition()) obj.setRotation(t.getRotation()) trans = ode.GeomTransform(self._space) trans.setGeom(obj) trans.setBody(self._body.getODEObject()) self.setODEObject(trans) else: obj.setBody(self._body.getODEObject()) self._parser.pop() def _parseGeomBox(self, attrs): def start(name, attrs): if (name == 'ext'): pass else: raise errors.ChildError('box', name) def end(name): if (name == 'box'): self._parser.pop() lx = float(attrs['sizex']) ly = float(attrs['sizey']) lz = float(attrs['sizez']) self.setODEObject(ode.GeomBox(self._space, (lx, ly, lz))) self._parser.push(startElement=start, endElement=end) def _parseGeomCCylinder(self, attrs): def start(name, attrs): if (name == 'ext'): pass else: raise errors.ChildError('cappedCylinder', name) def end(name): if (name == 'cappedCylinder'): self._parser.pop() radius = float(attrs['radius']) length = float(attrs['length']) self.setODEObject(ode.GeomCCylinder(self._space, radius, length)) self._parser.push(startElement=start, endElement=end) def _parseGeomSphere(self, attrs): def start(name, attrs): if (name == 'ext'): pass else: raise errors.ChildError('sphere', name) def end(name): if (name == 'sphere'): self._parser.pop() radius = float(attrs['radius']) self.setODEObject(ode.GeomSphere(self._space, radius)) self._parser.push(startElement=start, endElement=end) def _parseGeomPlane(self, attrs): def start(name, attrs): if (name == 'ext'): pass else: raise errors.ChildError('plane', name) def end(name): if (name == 'plane'): self._parser.pop() a = float(attrs['a']) b = float(attrs['b']) c = float(attrs['c']) d = float(attrs['d']) self.setODEObject(ode.GeomPlane(self._space, (a, b, c), d)) self._parser.push(startElement=start, endElement=end) def _parseGeomRay(self, attrs): def start(name, attrs): if (name == 'ext'): pass else: raise errors.ChildError('ray', name) def end(name): if (name == 'ray'): self._parser.pop() length = float(attrs['length']) self.setODEObject(ode.GeomRay(self._space, length)) self._parser.push(startElement=start, endElement=end) Index: parser.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/parser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** parser.py 7 Jul 2004 11:46:32 -0000 1.1 --- parser.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 53,62 **** import ode import xml.parsers.expat ! import transform, node, body, joint ! ! class InvalidError(Exception): ! """ ! Raised when an XODE document is invalid. ! """ class Parser: --- 53,57 ---- import ode import xml.parsers.expat ! import errors, transform, node, body, joint, geom class Parser: *************** *** 100,104 **** self._root.takeParser(self) else: ! raise InvalidError('Root element must be <xode>.') def parseVector(self, attrs): --- 95,99 ---- self._root.takeParser(self) else: ! raise errors.InvalidError('Root element must be <xode>.') def parseVector(self, attrs): *************** *** 109,114 **** @rtype: tuple ! @raise InvalidError: If the attributes don't correspond to a valid ! vector. """ --- 104,109 ---- @rtype: tuple ! @raise errors.InvalidError: If the attributes don't correspond to a ! valid vector. """ *************** *** 116,122 **** vec = float(attrs['x']), float(attrs['y']), float(attrs['z']) except ValueError: ! raise InvalidError('Vector attributes must be numbers.') except KeyError: ! raise InvalidError('Vector must have x, y and z attributes.') else: return vec --- 111,117 ---- vec = float(attrs['x']), float(attrs['y']), float(attrs['z']) except ValueError: ! raise errors.InvalidError('Vector attributes must be numbers.') except KeyError: ! raise errors.InvalidError('Vector must have x, y and z attributes.') else: return vec *************** *** 132,136 **** @rtype: instance of L{node.TreeNode} ! @raise InvalidException: If document is invalid. """ --- 127,131 ---- @rtype: instance of L{node.TreeNode} ! @raise errors.InvalidError: If document is invalid. """ *************** *** 148,152 **** @rtype: instance of L{node.TreeNode} ! @raise InvalidException: If document is invalid. """ --- 143,147 ---- @rtype: instance of L{node.TreeNode} ! @raise errors.InvalidError: If document is invalid. """ *************** *** 181,186 **** pass else: ! raise InvalidError('%s is not a valid child of <xode>.' % ! repr(name)) def _endElement(self, name): --- 176,180 ---- pass else: ! raise errors.ChildError('xode', name) def _endElement(self, name): *************** *** 222,227 **** pass else: ! raise InvalidError('%s is not a valid child of <world>' % ! repr(name)) def _endElement(self, name): --- 216,220 ---- pass else: ! raise errors.ChildError('world', name) def _endElement(self, name): *************** *** 258,263 **** t.takeParser(self._parser, self, attrs) elif (name == 'geom'): ! # parse geom ! pass elif (name == 'group'): # parse group --- 251,256 ---- t.takeParser(self._parser, self, attrs) elif (name == 'geom'): ! g = geom.Geom(nodeName, self) ! g.takeParser(self._parser) elif (name == 'group'): # parse group *************** *** 276,281 **** pass else: ! raise InvalidError('%s is not a valid child of <space>.' % ! repr(name)) def _endElement(self, name): --- 269,273 ---- pass else: ! raise errors.ChildError('space', name) def _endElement(self, name): --- xode.py DELETED --- Index: joint.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/joint.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** joint.py 7 Jul 2004 11:46:32 -0000 1.1 --- joint.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 8,12 **** import ode ! import node, parser class Joint(node.TreeNode): --- 8,12 ---- import ode ! import node, errors class Joint(node.TreeNode): *************** *** 41,49 **** link = root.namedChild(name).getODEObject() except KeyError: ! raise parser.InvalidError('Joint link must reference an already '\ ! 'parsed body.') if (not isinstance(link, ode.Body)): ! raise parser.InvalidError('Joint link must reference a body.') return link --- 41,49 ---- link = root.namedChild(name).getODEObject() except KeyError: ! raise errors.InvalidError('Joint link must reference an already '\ ! 'parsed body.') if (not isinstance(link, ode.Body)): ! raise errors.InvalidError('Joint link must reference a body.') return link *************** *** 64,68 **** if (link1 is link2): ! raise parser.InvalidError('Joint requires two objects.') return link1, link2 --- 64,68 ---- if (link1 is link2): ! raise errors.InvalidError('Joint requires two objects.') return link1, link2 *************** *** 101,111 **** pass else: ! raise parser.InvalidError('%s is not a valid child of <joint>.' % ! repr(name)) def _endElement(self, name): if (name == 'joint'): if (self.getODEObject() is None): ! raise parser.InvalidError('No joint type element found.') self._parser.pop() --- 101,110 ---- pass else: ! raise errors.ChildError('joint', name) def _endElement(self, name): if (name == 'joint'): if (self.getODEObject() is None): ! raise errors.InvalidError('No joint type element found.') self._parser.pop() *************** *** 117,122 **** anchor[0] = self._parser.parseVector(attrs) else: ! raise parser.InvalidError('%s is not a valid child of <ball>.' % ! repr(name)) def end(name): --- 116,120 ---- anchor[0] = self._parser.parseVector(attrs) else: ! raise errors.ChildError('ball', name) def end(name): Index: transform.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/transform.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** transform.py 7 Jul 2004 11:46:32 -0000 1.1 --- transform.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 24,27 **** --- 24,28 ---- [0, 0, 0, 0]] self.setIdentity() + self._absolute = False def takeParser(self, parser, node, attrs): *************** *** 41,44 **** --- 42,50 ---- self._scale = float(attrs.get('scale', 1.0)) + self._absolute = (attrs.get('absolute', 'false') == 'true') + + self._position = None + self._euler = None + self._node = node self._parser = parser *************** *** 48,59 **** def _startElement(self, name, attrs): if (name == 'matrix4f'): - self.setIdentity() for r in range(4): for c in range(4): self.m[r][c] = float(attrs['m%i%i' % (r, c)]) elif (name == 'position'): ! self.translate(float(attrs['x']), ! float(attrs['y']), ! float(attrs['z'])) elif (name == 'euler'): coeff = 1 --- 54,64 ---- def _startElement(self, name, attrs): if (name == 'matrix4f'): for r in range(4): for c in range(4): self.m[r][c] = float(attrs['m%i%i' % (r, c)]) elif (name == 'position'): ! self._position = (float(attrs['x']), ! float(attrs['y']), ! float(attrs['z'])) elif (name == 'euler'): coeff = 1 *************** *** 64,76 **** y = coeff * float(attrs['y']) z = coeff * float(attrs['z']) ! ! self.rotate(x, y, z) def _endElement(self, name): if (name == 'transform'): self.scale(self._scale, self._scale, self._scale) self._node.setNodeTransform(self) self._parser.pop() def setIdentity(self): """ --- 69,104 ---- y = coeff * float(attrs['y']) z = coeff * float(attrs['z']) ! ! self._euler = (x, y, z) ! elif (name == 'rotation'): ! pass ! else: ! import parser ! raise parser.InvalidError("%s is not a valid child of <transform>."% ! repr(name)) def _endElement(self, name): if (name == 'transform'): + if (self._euler): + x, y, z = self._euler + self.rotate(x, y, z) + if (self._position): + x, y, z = self._position + self.translate(x, y, z) + self.scale(self._scale, self._scale, self._scale) + self._node.setNodeTransform(self) self._parser.pop() + def isAbsolute(self): + """ + @return: True if this transform is to be absolute rather than + relative to another. + @rtype: bool + """ + + return self._absolute + def setIdentity(self): """ *************** *** 142,146 **** @type z: float """ ! rx = Transform() rx.m[1][1] = math.cos(x) --- 170,174 ---- @type z: float """ ! rx = Transform() rx.m[1][1] = math.cos(x) *************** *** 150,157 **** ry = Transform() ! ry.m[0][0] = math.cos(x) ! ry.m[0][2] = -math.sin(x) ! ry.m[2][0] = math.sin(x) ! ry.m[2][2] = math.cos(x) rz = Transform() --- 178,185 ---- ry = Transform() ! ry.m[0][0] = math.cos(y) ! ry.m[0][2] = -math.sin(y) ! ry.m[2][0] = math.sin(y) ! ry.m[2][2] = math.cos(y) rz = Transform() *************** *** 161,165 **** rz.m[1][1] = math.cos(z) ! r = self * rz * ry * rz self.m = r.m --- 189,193 ---- rz.m[1][1] = math.cos(z) ! r = self * rx * ry * rz self.m = r.m --- NEW FILE: errors.py --- # XODE Importer for PyODE # Copyright (C) 2004 Timothy Stranex """ XODE Exceptions @author: U{Timothy Stranex<mailto:ti...@st...>} """ class InvalidError(Exception): """ Raised when an XODE document is invalid. """ class ChildError(InvalidError): """ Raised when an invalid child element is found. @ivar parent: The parent element. @type parent: str @ivar child: The invalid child element. @type child: str """ def __init__(self, parent, child): self.parent = parent self.child = child def __str__(self): return '<%s> is not a valid child of <%s>.' % (self.child, self.parent) class MissingElementError(InvalidError): """ Raised when a child element is missing. @ivar parent: The parent element. @type parent: str @ivar child: The missing child element. @type child: str """ def __init__(self, parent, child): self.parent = parent self.child = child def __str__(self): return 'Missing child <%s> of <%s>.' % (self.child, self.parent) Index: body.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/body.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** body.py 7 Jul 2004 11:46:32 -0000 1.1 --- body.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 8,12 **** import ode ! import parser, node, joint, transform class Body(node.TreeNode): --- 8,12 ---- import ode ! import errors, node, joint, transform, geom class Body(node.TreeNode): *************** *** 22,27 **** enabled = attrs.get('enabled', 'true') if (enabled not in ['true', 'false']): ! raise parser.InvalidError("Enabled attribute must be either 'true' or " \ ! "'false'.") else: if (enabled == 'false'): --- 22,27 ---- enabled = attrs.get('enabled', 'true') if (enabled not in ['true', 'false']): ! raise errors.InvalidError("Enabled attribute must be either 'true'"\ ! " or 'false'.") else: if (enabled == 'false'): *************** *** 77,85 **** float(attrs['zaxis'])) except KeyError: ! raise parser.InvalidError('finiteRotation element must have' \ ' xaxis, yaxis and zaxis attributes') if (mode not in [0, 1]): ! raise parser.InvalidError('finiteRotation mode attribute must' \ ' be either 0 or 1.') --- 77,85 ---- float(attrs['zaxis'])) except KeyError: ! raise errors.InvalidError('finiteRotation element must have' \ ' xaxis, yaxis and zaxis attributes') if (mode not in [0, 1]): ! raise errors.InvalidError('finiteRotation mode attribute must' \ ' be either 0 or 1.') *************** *** 96,99 **** --- 96,109 ---- j = joint.Joint(nodeName, self) j.takeParser(self._parser) + elif (name == 'body'): + b = Body(nodeName, self, attrs) + b.takeParser(self._parser) + elif (name == 'geom'): + g = geom.Geom(nodeName, self) + g.takeParser(self._parser) + elif (name == 'transform'): # so it doesn't raise ChildError + pass + else: + raise errors.ChildError('body', name) def _endElement(self, name): *************** *** 146,151 **** mass.takeParser(self._parser) else: ! raise parser.InvalidError('%s is not a valid child of <mass>' % ! repr(name)) def _endElement(self, name): --- 156,160 ---- mass.takeParser(self._parser) else: ! raise errors.ChildError('mass', name) def _endElement(self, name): Index: node.py =================================================================== RCS file: /cvsroot/pyode/pyode/xode/node.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** node.py 7 Jul 2004 11:46:32 -0000 1.1 --- node.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 97,102 **** return self._transform ! def getTransform(self): """ @return: The absolute transform at this node. @rtype: instance of L{transform.Transform} --- 97,111 ---- return self._transform ! def getTransform(self, untilAncestor=None): """ + Calculates the absolute transform at this node. It calculates the + transforms recursively from the root node. If C{untilAncestor} is + passed, the transform is calculated relative to it. If C{untilAncestor} + is passed but is not an ancestor of this node, the transform is + calculated from the root node as if C{None} was passed. + + @param untilAncestor: The ancestor to calculate the transform from. + @type untilAncestor: instance of L{TreeNode} + @return: The absolute transform at this node. @rtype: instance of L{transform.Transform} *************** *** 106,113 **** t = self.getNodeTransform() ! if (p is not None): ! return p.getTransform() * t ! else: return t def getName(self): --- 115,122 ---- t = self.getNodeTransform() ! if ((p is None) or (t.isAbsolute()) or (p is untilAncestor)): return t + else: + return p.getTransform(untilAncestor) * t def getName(self): |
From: Timothy S. <pe...@us...> - 2004-07-16 11:45:27
|
Update of /cvsroot/pyode/pyode/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24225/tests Modified Files: test_xode.py Log Message: xode/ * Added Geom parser. * Fixed some mistakes in transform.py. * Moved exception classes from parser.py to errors.py. examples/ * Added the xml encoding attribute to the XODE document in tutorial2.py * Added an example to demonstrate XODE's transform features. tests/ * Added Geom tests to test_xode.py. Index: test_xode.py =================================================================== RCS file: /cvsroot/pyode/pyode/tests/test_xode.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_xode.py 7 Jul 2004 11:46:32 -0000 1.1 --- test_xode.py 16 Jul 2004 11:45:17 -0000 1.2 *************** *** 3,7 **** import unittest import ode ! from xode import node, transform, parser test_doc = '''<?xml version="1.0"?> --- 3,8 ---- import unittest import ode ! import math ! from xode import node, transform, parser, errors test_doc = '''<?xml version="1.0"?> *************** *** 50,53 **** --- 51,58 ---- </ball> </joint> + + <geom name="geom1"> + <box sizex="10" sizey="20" sizez="30"/> + </geom> </body> *************** *** 72,85 **** <body name="body3"> <transform> ! <matrix4f m00="0.0" m01="0.0" m02="1.0" m03="0.0" m10="0.0" m11="1.0" m12="0.0" m13="0.0" ! m20="1.0" m21="0.0" m22="0.0" m23="0.0" m30="10.0" m31="20.0" m32="30.0" m33="0.0"/> </transform> </body> </space> </world> </xode>''' class Class1: pass --- 77,167 ---- <body name="body3"> <transform> ! <matrix4f m00="1.0" m01="0.0" m02="0.0" m03="0.0" m10="0.0" m11="1.0" m12="0.0" m13="0.0" ! m20="0.0" m21="0.0" m22="1.0" m23="0.0" m30="10.0" m31="20.0" m32="30.0" m33="0.0"/> </transform> </body> + + <body name="body4"> + <transform> + <position x="1" y="1" z="1"/> + </transform> + <body name="body5"> + <transform> + <position x="2" y="2" z="2"/> + </transform> + </body> + </body> + + <body name="body6"> + <transform> + <rotation> + <euler x="0" y="0" z="0.78" aformat="radians"/> + </rotation> + </transform> + + <body name="body7"> + <transform absolute="true"> + <matrix4f m00="1.0" m01="2.0" m02="3.0" m03="4.0" + m10="1.2" m11="2.2" m12="3.2" m13="4.2" + m20="1.4" m21="2.4" m22="3.4" m23="4.4" + m30="1.8" m31="2.8" m32="3.8" m33="4.8"/> + </transform> + + <geom name="geom6"> + <transform> + <position x="1.0" y="2.0" z="3.0"/> + <rotation> + <euler x="0.78" y="0" z="0" aformat="radians"/> + </rotation> + </transform> + <sphere radius="1.0"/> + </geom> + + </body> + </body> + + <geom name="geom2"> + <cappedCylinder radius="15.0" length="3.0"/> + </geom> + + <geom name="geom3"> + <ray length="11.0"/> + + <geom name="geom4"> + <plane a="0.0" b="1.0" c="0.0" d="17.0"/> + </geom> + + <geom name="geom5"> + <transform> + <position x="1.0" y="2.0" z="3.0"/> + <rotation> + <euler x="0.0" y="0.0" z="0.78" aformat="radians"/> + </rotation> + </transform> + + <sphere radius="23.0"/> + </geom> + + </geom> + </space> </world> + </xode>''' + def feq(n1, n2, error=0.1): + """ + Compare two floating point numbers. If the differ by less than C{error}, + return True; otherwise, return False. + """ + + n = math.fabs(n1 - n2) + if (n <= error): + return True + else: + return False + class Class1: pass *************** *** 94,97 **** --- 176,180 ---- self.node2 = node.TreeNode('node2', self.node1) self.node3 = node.TreeNode('node3', self.node2) + self.node4 = node.TreeNode('node4', self.node3) self.t2 = transform.Transform() *************** *** 103,106 **** --- 186,193 ---- self.node3.setNodeTransform(self.t3) + self.t4 = transform.Transform() + self.t4.translate(2.0, 3.0, 1.0) + self.node4.setNodeTransform(self.t4) + self.node1.setODEObject(Class2()) self.node2.setODEObject(Class2()) *************** *** 116,120 **** self.assertEqual(self.node1.getChildren(), [self.node2]) self.assertEqual(self.node2.getChildren(), [self.node3]) ! self.assertEqual(self.node3.getChildren(), []) def testNamedChildLocal(self): --- 203,208 ---- self.assertEqual(self.node1.getChildren(), [self.node2]) self.assertEqual(self.node2.getChildren(), [self.node3]) ! self.assertEqual(self.node3.getChildren(), [self.node4]) ! self.assertEqual(self.node4.getChildren(), []) def testNamedChildLocal(self): *************** *** 143,146 **** --- 231,238 ---- self.assertEqual(self.node3.getTransform().m, ref.m) + def testGetTransformUntil(self): + ref = self.t3 * self.t4 + self.assertEqual(self.node4.getTransform(self.node2).m, ref.m) + class TestParser(unittest.TestCase): def setUp(self): *************** *** 163,166 **** --- 255,259 ---- self.body1 = self.root.namedChild('body1').getODEObject() self.body3 = self.root.namedChild('body3').getODEObject() + self.body6 = self.root.namedChild('body6').getODEObject() def testInstance(self): *************** *** 168,176 **** def testRotation(self): ! # FIXME? ! #self.assertEqual(self.body3.getRotation(), [0.0, 0.0, 1.0, ! # 0.0, 1.0, 0.0, ! # 1.0, 0.0, 0.0]) ! pass def testPosition(self): --- 261,270 ---- def testRotation(self): ! ref = transform.Transform() ! ref.rotate(0.0, 0.0, 0.78) ! ! rot = self.body6.getRotation() ! for n1, n2 in zip(ref.getRotation(), rot): ! self.assert_(feq(n1, n2)) def testPosition(self): *************** *** 254,260 **** def testBallAnchor(self): ! # FIXME? ! #self.assertEqual(self.joint1.getAnchor(), (1.0, 2.0, 3.0)) ! pass class TestTransformParser(TestParser): --- 348,431 ---- def testBallAnchor(self): ! for n1, n2 in zip(self.joint1.getAnchor(), (1.0, 2.0, 3.0)): ! self.assert_(feq(n1, n2)) ! ! class TestGeomParser(TestParser): ! def setUp(self): ! TestParser.setUp(self) ! ! self.geom1 = self.root.namedChild('geom1').getODEObject() ! self.geom2 = self.root.namedChild('geom2').getODEObject() ! self.geom3 = self.root.namedChild('geom3').getODEObject() ! self.geom4 = self.root.namedChild('geom4').getODEObject() ! self.geom5 = self.root.namedChild('geom5').getODEObject() ! self.geom6 = self.root.namedChild('geom6').getODEObject() ! ! self.body1 = self.root.namedChild('body1').getODEObject() ! self.space1 = self.root.namedChild('space1').getODEObject() ! ! def testSpaceAncestor(self): ! self.assertEqual(self.geom1.getSpace(), self.space1) ! ! def testBodyAttach(self): ! self.assertEqual(self.geom1.getBody(), self.body1) ! ! def testBoxInstance(self): ! self.assert_(isinstance(self.geom1, ode.GeomBox)) ! ! def testBoxSize(self): ! self.assertEqual(self.geom1.getLengths(), (10.0, 20.0, 30.0)) ! ! def testCCylinderInstance(self): ! self.assert_(isinstance(self.geom2, ode.GeomCCylinder)) ! ! def testCCylinderParams(self): ! self.assertEqual(self.geom2.getParams(), (15.0, 3.0)) ! ! def testSphereInstance(self): ! self.assert_(isinstance(self.geom5, ode.GeomSphere)) ! ! def testSphereRadius(self): ! self.assertEqual(self.geom5.getRadius(), 23.0) ! ! def testPlaneInstance(self): ! self.assert_(isinstance(self.geom4, ode.GeomPlane)) ! ! def testPlaneParams(self): ! self.assertEqual(self.geom4.getParams(), ((0.0, 1.0, 0.0), 17.0)) ! ! def testRayInstance(self): ! self.assert_(isinstance(self.geom3, ode.GeomRay)) ! ! def testRayLength(self): ! self.assertEqual(self.geom3.getLength(), 11.0) ! ! def testIndependantRotation(self): ! ref = transform.Transform() ! ref.rotate(0.0, 0.0, 0.78) ! ! for n1, n2 in zip(self.geom5.getRotation(), ref.getRotation()): ! self.assert_(feq(n1, n2)) ! ! def testIndependantPosition(self): ! self.assertEqual(self.geom5.getPosition(), (1.0, 2.0, 3.0)) ! ! def testTransformInstance(self): ! self.assert_(isinstance(self.geom6, ode.GeomTransform)) ! ! def testTransformGeomInstance(self): ! self.assert_(isinstance(self.geom6.getGeom(), ode.GeomSphere)) ! ! def testTransformPosition(self): ! pos = self.geom6.getGeom().getPosition() ! self.assertEqual(pos, (1.0, 2.0, 3.0)) ! ! def testTransformRotation(self): ! ref = transform.Transform() ! ref.rotate(0.78, 0.0, 0.0) ! rot = self.geom6.getGeom().getRotation() ! ! for n1, n2 in zip(rot, ref.getRotation()): ! self.assert_(feq(n1, n2)) class TestTransformParser(TestParser): *************** *** 263,266 **** --- 434,439 ---- self.world1 = self.root.namedChild('world1') self.body1 = self.root.namedChild('body1') + self.body5 = self.root.namedChild('body5') + self.body7 = self.root.namedChild('body7') def testMatrixStyle(self): *************** *** 273,280 **** def testVector(self): ref = transform.Transform() - ref.translate(10.0, 11.0, 12.0) ref.rotate(45.0, 45.0, 45.0) ref.scale(2.0, 2.0, 2.0) self.assertEqual(self.body1.getNodeTransform().m, ref.m) def testMultiply(self): --- 446,470 ---- def testVector(self): ref = transform.Transform() ref.rotate(45.0, 45.0, 45.0) + ref.translate(10.0, 11.0, 12.0) ref.scale(2.0, 2.0, 2.0) self.assertEqual(self.body1.getNodeTransform().m, ref.m) + + def testAbsolute(self): + t = self.body7.getTransform() + self.assertEqual(t.m, [[1.0, 2.0, 3.0, 4.0], + [1.2, 2.2, 3.2, 4.2], + [1.4, 2.4, 3.4, 4.4], + [1.8, 2.8, 3.8, 4.8]]) + + def testRelative(self): + t1 = transform.Transform() + t1.translate(1.0, 1.0, 1.0) + t2 = transform.Transform() + t2.translate(2.0, 2.0, 2.0) + + t3 = t1 * t2 + + self.assertEqual(self.body5.getTransform().m, t3.m) def testMultiply(self): *************** *** 306,314 **** class TestInvalidTags(TestInvalid): def testRoot(self): ! self.assertRaises(parser.InvalidError, self.p.parseString, '<?xml version="1.0"?>\n<test></test>') def testRootChild(self): ! self.assertRaises(parser.InvalidError, self.p.parseString, '<?xml version="1.0"?>\n<xode><test/></xode>') --- 496,504 ---- class TestInvalidTags(TestInvalid): def testRoot(self): ! self.assertRaises(errors.InvalidError, self.p.parseString, '<?xml version="1.0"?>\n<test></test>') def testRootChild(self): ! self.assertRaises(errors.ChildError, self.p.parseString, '<?xml version="1.0"?>\n<xode><test/></xode>') *************** *** 319,323 **** </world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testSpaceChild(self): --- 509,513 ---- </world></xode>''' ! self.assertRaises(errors.ChildError, self.p.parseString, doc) def testSpaceChild(self): *************** *** 327,331 **** </space></world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testMassChild(self): --- 517,521 ---- </space></world></xode>''' ! self.assertRaises(errors.ChildError, self.p.parseString, doc) def testMassChild(self): *************** *** 339,348 **** </space></world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testJointChild(self): doc = '''<?xml version="1.0"?> <xode><world><space><joint><test/></joint></space></world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) class TestInvalidBody(TestInvalid): --- 529,543 ---- </space></world></xode>''' ! self.assertRaises(errors.ChildError, self.p.parseString, doc) def testJointChild(self): doc = '''<?xml version="1.0"?> <xode><world><space><joint><test/></joint></space></world></xode>''' ! self.assertRaises(errors.ChildError, self.p.parseString, doc) ! ! def testGeomChild(self): ! doc = '''<?xml version="1.0"?> ! <xode><world><space><geom><test/></geom></space></world></xode>''' ! self.assertRaises(errors.ChildError, self.p.parseString, doc) class TestInvalidBody(TestInvalid): *************** *** 355,359 **** </world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testBodyEnable(self): --- 550,554 ---- </world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testBodyEnable(self): *************** *** 364,368 **** </world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testFiniteRotationMode(self): --- 559,563 ---- </world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testFiniteRotationMode(self): *************** *** 374,378 **** </world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testFiniteRotationAxes(self): --- 569,573 ---- </world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testFiniteRotationAxes(self): *************** *** 384,388 **** </world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) class TestInvalidJoint(TestInvalid): --- 579,583 ---- </world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) class TestInvalidJoint(TestInvalid): *************** *** 396,400 **** # both links are ode.environment ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testNoType(self): --- 591,595 ---- # both links are ode.environment ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testNoType(self): *************** *** 404,408 **** </space></world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testWrongType(self): --- 599,603 ---- </space></world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testWrongType(self): *************** *** 417,421 **** </space></world></xode>''' ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testMisplacedReference(self): --- 612,616 ---- </space></world></xode>''' ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) def testMisplacedReference(self): *************** *** 432,436 **** # bodies must be defined before the joint ! self.assertRaises(parser.InvalidError, self.p.parseString, doc) if (__name__ == '__main__'): --- 627,640 ---- # bodies must be defined before the joint ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) ! ! class TestInvalidGeom(TestInvalid): ! def testNoType(self): ! doc = '''<?xml version="1.0"?> ! <xode><world><space> ! <geom/> ! </space></world></xode>''' ! ! self.assertRaises(errors.InvalidError, self.p.parseString, doc) if (__name__ == '__main__'): |
From: Timothy S. <pe...@us...> - 2004-07-16 11:45:26
|
Update of /cvsroot/pyode/pyode/examples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24225/examples Modified Files: tutorial2.py Added Files: transforms.py Log Message: xode/ * Added Geom parser. * Fixed some mistakes in transform.py. * Moved exception classes from parser.py to errors.py. examples/ * Added the xml encoding attribute to the XODE document in tutorial2.py * Added an example to demonstrate XODE's transform features. tests/ * Added Geom tests to test_xode.py. Index: tutorial2.py =================================================================== RCS file: /cvsroot/pyode/pyode/examples/tutorial2.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tutorial2.py 7 Jul 2004 11:46:32 -0000 1.2 --- tutorial2.py 16 Jul 2004 11:45:17 -0000 1.3 *************** *** 7,11 **** import xode.parser ! doc = '''<?xml version="1.0"?> <xode> <world name="world"> --- 7,11 ---- import xode.parser ! doc = '''<?xml version="1.0" encoding="iso-8859-1"?> <xode> <world name="world"> --- NEW FILE: transforms.py --- # PyODE Example: Transforms # This example demonstrates the way object transforms are calculated relative # to the parent element's transform in XODE. from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * from cgtypes import * import pygame import math import ode import xode.parser doc = '''<?xml version="1.0" encoding="iso-8859-1"?> <xode> <world name="world1"> <space name="space1"> <body> <transform> <position x="0" y="0" z="0"/> <rotation> <euler x="0" y="0" z="0" aformat="degrees"/> </rotation> </transform> <!-- Y-axis Rotations --> <body> <transform scale="1.25"> <position x="0" y="1" z="0"/> <rotation> <euler x="0" y="30" z="0" aformat="degrees"/> </rotation> </transform> <body> <transform scale="1.25"> <position x="0" y="1" z="0"/> <rotation> <euler x="0" y="30" z="0" aformat="degrees"/> </rotation> </transform> </body> </body> <!-- X-axis Rotations --> <body> <transform scale="1.25"> <position x="1" y="0" z="0"/> <rotation> <euler x="30" y="0" z="0" aformat="degrees"/> </rotation> </transform> <body> <transform scale="1.25"> <position x="1" y="0" z="0"/> <rotation> <euler x="30" y="0" z="0" aformat="degrees"/> </rotation> </transform> </body> </body> <!-- Z-axis Rotations --> <body> <transform scale="1.25"> <position x="0" y="0" z="-1"/> <rotation> <euler x="0" y="0" z="30" aformat="degrees"/> </rotation> </transform> <body> <transform scale="1.25"> <position x="0" y="0" z="-1"/> <rotation> <euler x="0" y="0" z="30" aformat="degrees"/> </rotation> </transform> </body> </body> </body> </space> </world> </xode> ''' def prepare_GL(c): """Prepare drawing. """ # Viewport glViewport(0, 0, 640, 480) # Initialize glClearColor(0.8, 0.8, 0.9, 0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glEnable(GL_LIGHTING) glEnable(GL_NORMALIZE) glShadeModel(GL_FLAT) # Projection glMatrixMode(GL_PROJECTION) glLoadIdentity() P = mat4(1).perspective(45,1.3333,0.2,20) glMultMatrixd(P.toList()) # Initialize ModelView matrix glMatrixMode(GL_MODELVIEW) glLoadIdentity() # Light source glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0]) glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1]) glEnable(GL_LIGHT0) # View transformation V = mat4(1).lookAt(1.2*vec3(0.5*c,0.7*c,c),(1.0,1.0,0), up=(0,1,0)) V.rotate(math.pi,vec3(0,1,0)) V = V.inverse() glMultMatrixd(V.toList()) def draw_body(body): """Draw an ODE body. """ x,y,z = body.getPosition() R = body.getRotation() T = mat4() T[0,0] = R[0] T[0,1] = R[1] T[0,2] = R[2] T[1,0] = R[3] T[1,1] = R[4] T[1,2] = R[5] T[2,0] = R[6] T[2,1] = R[7] T[2,2] = R[8] T[3] = (x,y,z,1.0) glPushMatrix() glMultMatrixd(T.toList()) if body.shape=="box": sx,sy,sz = body.boxsize glScale(sx, sy, sz) glutSolidCube(1) glPopMatrix() ###################################################################### # Initialize pygame passed, failed = pygame.init() # Open a window srf = pygame.display.set_mode((640,480), pygame.OPENGL | pygame.DOUBLEBUF) root = xode.parser.Parser().parseString(doc) world = root.namedChild('world1').getODEObject() world.setGravity( (0, 0, 0) ) # Add all ODE bodies from the XODE document into bodies. def transverse(node): obj = node.getODEObject() if (isinstance(obj, ode.Body)): # Set attributes for draw_body() obj.shape = 'box' obj.boxsize = (0.4, 0.4, 0.4) bodies.append(obj) for node in node.getChildren(): transverse(node) bodies = [] transverse(root) # Some variables used inside the simulation loop fps = 50 dt = 1.0/fps counter = 0.0 running = True clk = pygame.time.Clock() while running: events = pygame.event.get() for e in events: if e.type==pygame.QUIT: running=False if (counter < 5): counter = counter + 0.1 # Draw the scene prepare_GL(counter) for b in bodies: draw_body(b) pygame.display.flip() # Simulate n = 2 for i in range(n): world.step(dt/n) clk.tick(fps) |
From: Matthias B. <mb...@us...> - 2004-07-13 16:44:26
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15555 Modified Files: geoms.pyx Log Message: Doc strings updates. New method getAABB() to return the bounding box. New method placeable() that returns whether a geom is placeable or not. This is used for improved error checks (e.g. calling setPosition() on non-placeable geoms resulted in a crash). Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** geoms.pyx 12 Jul 2004 17:30:08 -0000 1.2 --- geoms.pyx 13 Jul 2004 16:44:18 -0000 1.3 *************** *** 54,65 **** self.attribs[name]=val def setBody(self, Body body): """setBody(body) ! Associate the geom to a body or remove an association. @param body: The Body object or None. @type body: Body """ if body==None: --- 54,87 ---- self.attribs[name]=val + def _id(self): + """_id() -> int + + Return the internal id of the geom (dGeomID) as returned by + the dCreateXyz() functions. + + This method has to be overwritten in derived methods. + """ + raise NotImplementedError, "Bug: The _id() method is not implemented." + + def placeable(self): + """placeable() -> bool + + Returns True if the geom object is a placeable geom. + + This method has to be overwritten in derived methods. + """ + return False + def setBody(self, Body body): """setBody(body) ! Set the body associated with a placeable geom. @param body: The Body object or None. @type body: Body """ + + if not self.placeable(): + raise ValueError, "Non-placeable geoms cannot have a body associated to them." if body==None: *************** *** 70,79 **** --- 92,126 ---- def getBody(self): + """getBody() -> Body + + Get the body associated with this geom. + """ + if not self.placeable(): + return environment + return self.body def setPosition(self, pos): + """setPosition(pos) + + Set the position of the geom. If the geom is attached to a body, + the body's position will also be changed. + + @param pos: Position + @type pos: 3-sequence of floats + """ + if not self.placeable(): + raise ValueError, "Cannot set a position on non-placeable geoms." dGeomSetPosition(self.gid, pos[0], pos[1], pos[2]) def getPosition(self): + """getPosition() -> 3-tuple + + Get the current position of the geom. If the geom is attached to + a body the returned value is the body's position. + """ + if not self.placeable(): + raise ValueError, "Non-placeable geoms do not have a position." + cdef dReal* p p = <dReal*>dGeomGetPosition(self.gid) *************** *** 81,84 **** --- 128,142 ---- def setRotation(self, R): + """setRotation(R) + + Set the orientation of the geom. If the geom is attached to a body, + the body's orientation will also be changed. + + @param R: Rotation matrix + @type R: 9-sequence of floats + """ + if not self.placeable(): + raise ValueError, "Cannot set a rotation on non-placeable geoms." + cdef dMatrix3 m m[0] = R[0] *************** *** 97,106 **** def getRotation(self): cdef dReal* m m = <dReal*>dGeomGetRotation(self.gid) return [m[0],m[1],m[2],m[4],m[5],m[6],m[8],m[9],m[10]] def isSpace(self): ! """Return 1 if the given geom is a space, or 0 if not.""" return dGeomIsSpace(self.gid) --- 155,185 ---- def getRotation(self): + """getRotation() -> 9-tuple + + Get the current orientation of the geom. If the geom is attached to + a body the returned value is the body's orientation. + """ + if not self.placeable(): + raise ValueError, "Non-placeable geoms do not have a rotation." + cdef dReal* m m = <dReal*>dGeomGetRotation(self.gid) return [m[0],m[1],m[2],m[4],m[5],m[6],m[8],m[9],m[10]] + def getAABB(self): + """getAABB() -> 6-tuple + + Return an axis aligned bounding box that surrounds the geom. + The return value is a 6-tuple (minx, maxx, miny, maxy, minz, maxz). + """ + cdef dReal aabb[6] + + dGeomGetAABB(self.gid, aabb) + return (aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5]) + def isSpace(self): ! """isSpace() -> bool ! ! Return 1 if the given geom is a space, or 0 if not.""" return dGeomIsSpace(self.gid) *************** *** 113,137 **** def setCollideBits(self, bits): dGeomSetCollideBits(self.gid, bits) def setCategoryBits(self, bits): dGeomSetCategoryBits(self.gid, bits) def getCollideBits(self): return dGeomGetCollideBits(self.gid) def getCategoryBits(self): return dGeomGetCategoryBits(self.gid) def enable(self): ! """Enable the geom.""" dGeomEnable(self.gid) def disable(self): ! """Disable the geom.""" dGeomDisable(self.gid) def isEnabled(self): ! """Return True if the geom is enabled.""" return dGeomIsEnabled(self.gid) --- 192,244 ---- def setCollideBits(self, bits): + """setCollideBits(bits) + + Set the "collide" bitfields for this geom. + + @param bits: Collide bit field + @type bits: int + """ dGeomSetCollideBits(self.gid, bits) def setCategoryBits(self, bits): + """setCategoryBits(bits) + + Set the "category" bitfields for this geom. + + @param bits: Category bit field + @type bits: int + """ dGeomSetCategoryBits(self.gid, bits) def getCollideBits(self): + """getCollideBits() -> int + + Return the "collide" bitfields for this geom. + """ return dGeomGetCollideBits(self.gid) def getCategoryBits(self): + """getCategoryBits() -> int + + Return the "category" bitfields for this geom. + """ return dGeomGetCategoryBits(self.gid) def enable(self): ! """enable() ! ! Enable the geom.""" dGeomEnable(self.gid) def disable(self): ! """disable() ! ! Disable the geom.""" dGeomDisable(self.gid) def isEnabled(self): ! """isEnabled() -> bool ! ! Return True if the geom is enabled.""" return dGeomIsEnabled(self.gid) *************** *** 163,166 **** --- 270,276 ---- self.body = None + def placeable(self): + return True + def _id(self): cdef long id *************** *** 169,178 **** --- 279,309 ---- def setRadius(self, radius): + """setRadius(radius) + + Set the radius of the sphere. + + @param radius: New radius + @type radius: float + """ dGeomSphereSetRadius(self.gid, radius) def getRadius(self): + """getRadius() -> float + + Return the radius of the sphere. + """ return dGeomSphereGetRadius(self.gid) def pointDepth(self, p): + """pointDepth() -> float + + Return the depth of the point p in the sphere. Points inside + the geom will have positive depth, points outside it will have + negative depth, and points on the surface will have zero + depth. + + @param p: Point + @type p: 3-sequence of floats + """ return dGeomSpherePointDepth(self.gid, p[0], p[1], p[2]) *************** *** 201,204 **** --- 332,338 ---- self.body = None + def placeable(self): + return True + def _id(self): cdef long id *************** *** 215,218 **** --- 349,362 ---- def pointDepth(self, p): + """pointDepth() -> float + + Return the depth of the point p in the box. Points inside the + geom will have positive depth, points outside it will have + negative depth, and points on the surface will have zero + depth. + + @param p: Point + @type p: 3-sequence of floats + """ return dGeomBoxPointDepth(self.gid, p[0], p[1], p[2]) *************** *** 259,270 **** def pointDepth(self, p): ! return dGeomPlanePointDepth(self.gid, p[0], p[1], p[2]) ! def getBody(self): ! return environment ! def setBody(self, Body body): ! if body!=None: ! raise ValueError, "A GeomPlane cannot be associated to a body." --- 403,417 ---- def pointDepth(self, p): ! """pointDepth() -> float ! Return the depth of the point p in the plane. Points inside the ! geom will have positive depth, points outside it will have ! negative depth, and points on the surface will have zero ! depth. ! @param p: Point ! @type p: 3-sequence of floats ! """ ! return dGeomPlanePointDepth(self.gid, p[0], p[1], p[2]) *************** *** 292,295 **** --- 439,444 ---- self.body = None + def placeable(self): + return True def _id(self): *************** *** 307,310 **** --- 456,469 ---- def pointDepth(self, p): + """pointDepth() -> float + + Return the depth of the point p in the cylinder. Points inside the + geom will have positive depth, points outside it will have + negative depth, and points on the surface will have zero + depth. + + @param p: Point + @type p: 3-sequence of floats + """ return dGeomCCylinderPointDepth(self.gid, p[0], p[1], p[2]) *************** *** 376,380 **** _geom_c2py_lut[<long>self.gid]=self - def __init__(self, space=None): self.space = space --- 535,538 ---- *************** *** 384,387 **** --- 542,548 ---- self.attribs={} + def placeable(self): + return True + def _id(self): cdef long id *************** *** 399,400 **** --- 560,562 ---- return self.geom + |
From: Matthias B. <mb...@us...> - 2004-07-12 17:30:19
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2558/src Modified Files: body.pyx contact.pyx declarations.pyx geoms.pyx mass.pyx ode.pyx space.pyx Log Message: Doc string updates. There are no warnings from epydoc anymore. Cleared the cleanup flag in the Space object. Index: body.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/body.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** body.pyx 12 Jul 2004 12:35:26 -0000 1.2 --- body.pyx 12 Jul 2004 17:30:08 -0000 1.3 *************** *** 147,151 **** # setLinearVel def setLinearVel(self, vel): ! """setLinearVel(pos) Set the linear velocity of the body. --- 147,151 ---- # setLinearVel def setLinearVel(self, vel): ! """setLinearVel(vel) Set the linear velocity of the body. *************** *** 169,173 **** # setAngularVel def setAngularVel(self, vel): ! """setAngularVel(pos) Set the angular velocity of the body. --- 169,173 ---- # setAngularVel def setAngularVel(self, vel): ! """setAngularVel(vel) Set the angular velocity of the body. Index: space.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/space.pyx,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** space.pyx 27 Jun 2004 20:46:17 -0000 1.1 --- space.pyx 12 Jul 2004 17:30:08 -0000 1.2 *************** *** 12,17 **** (see ODE documentation). ! space = Space(type=0) # Create a SimpleSpace ! space = Space(type=1) # Create a HashSpace """ --- 12,17 ---- (see ODE documentation). ! >>> space = Space(type=0) # Create a SimpleSpace ! >>> space = Space(type=1) # Create a HashSpace """ *************** *** 27,30 **** --- 27,31 ---- self.sid = dHashSpaceCreate(0) + dSpaceSetCleanup(self.sid, 0) _geom_c2py_lut[<long>self.sid]=self *************** *** 61,64 **** --- 62,72 ---- return id + def getNumGeoms(self): + """getNumGeoms() -> int + + Return the number of geoms contained within the space. + """ + return dSpaceGetNumGeoms(self.sid) + def collide(self, arg, callback): """Do collision detection. Index: geoms.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/geoms.pyx,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** geoms.pyx 27 Jun 2004 20:46:17 -0000 1.1 --- geoms.pyx 12 Jul 2004 17:30:08 -0000 1.2 *************** *** 55,61 **** def setBody(self, Body body): ! """Associate the geom to a body or remove an association. @param body: The Body object or None. """ --- 55,64 ---- def setBody(self, Body body): ! """setBody(body) ! ! Associate the geom to a body or remove an association. @param body: The Body object or None. + @type body: Body """ Index: mass.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/mass.pyx,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mass.pyx 5 Jul 2004 20:01:37 -0000 1.4 --- mass.pyx 12 Jul 2004 17:30:08 -0000 1.5 *************** *** 155,159 **** relative to the body frame. ! @param t Translation vector (x, y, z) @type t: 3-tuple of floats """ --- 155,159 ---- relative to the body frame. ! @param t: Translation vector (x, y, z) @type t: 3-tuple of floats """ Index: declarations.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/declarations.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** declarations.pyx 3 Jul 2004 16:57:41 -0000 1.2 --- declarations.pyx 12 Jul 2004 17:30:08 -0000 1.3 *************** *** 17,20 **** --- 17,23 ---- void free(void*) + cdef extern from "stdio.h": + int printf(char*) + # Include the basic floating point type -> dReal (either float or double) include "_precision.pyx" *************** *** 273,276 **** --- 276,284 ---- void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel) + void dSpaceSetCleanup (dSpaceID space, int mode) + int dSpaceGetCleanup (dSpaceID space) + + int dSpaceGetNumGeoms (dSpaceID) + # Geom dGeomID dCreateSphere (dSpaceID space, dReal radius) Index: ode.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/ode.pyx,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ode.pyx 12 Jul 2004 12:36:14 -0000 1.3 --- ode.pyx 12 Jul 2004 17:30:08 -0000 1.4 *************** *** 27,61 **** There are the following classes and functions: ! - World ! - Body ! - JointGroup ! - Contact ! - Space ! - Mass Joint classes: ! - BallJoint ! - HingeJoint ! - Hinge2Joint ! - SliderJoint ! - UniversalJoint ! - FixedJoint ! - ContactJoint ! - AMotor Geom classes: ! - GeomSphere ! - GeomBox ! - GeomPlane ! - GeomCCylinder ! - GeomRay ! - GeomTransform Functions: ! - CloseODE() ! - collide() """ --- 27,61 ---- There are the following classes and functions: ! - World ! - Body ! - JointGroup ! - Contact ! - Space ! - Mass Joint classes: ! - BallJoint ! - HingeJoint ! - Hinge2Joint ! - SliderJoint ! - UniversalJoint ! - FixedJoint ! - ContactJoint ! - AMotor Geom classes: ! - GeomSphere ! - GeomBox ! - GeomPlane ! - GeomCCylinder ! - GeomRay ! - GeomTransform Functions: ! - CloseODE() ! - collide() """ Index: contact.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/contact.pyx,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** contact.pyx 27 Jun 2004 20:46:17 -0000 1.1 --- contact.pyx 12 Jul 2004 17:30:08 -0000 1.2 *************** *** 5,15 **** A Contact object stores all the input parameters for a ContactJoint. ! This class wraps the ODE dContact structure which has 3 components: ! struct dContact { ! dSurfaceParameters surface; ! dContactGeom geom; ! dVector3 fdir1; ! }; This wrapper class provides methods to get and set the items of those --- 5,15 ---- A Contact object stores all the input parameters for a ContactJoint. ! This class wraps the ODE dContact structure which has 3 components:: ! struct dContact { ! dSurfaceParameters surface; ! dContactGeom geom; ! dVector3 fdir1; ! }; This wrapper class provides methods to get and set the items of those |
From: Matthias B. <mb...@us...> - 2004-07-12 12:37:33
|
Update of /cvsroot/pyode/pyode/xode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7343/xode Added Files: .cvsignore Log Message: Ignore *.pyc files --- NEW FILE: .cvsignore --- *.pyc |
From: Matthias B. <mb...@us...> - 2004-07-12 12:36:22
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7191 Modified Files: ode.pyx Log Message: Updated/created doc strings Index: ode.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/ode.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ode.pyx 3 Jul 2004 16:57:41 -0000 1.2 --- ode.pyx 12 Jul 2004 12:36:14 -0000 1.3 *************** *** 17,21 **** # be deleted. ! """Python Open Dynamics Engine (ODE) wrapper. This module contains classes and functions that wrap the functionality --- 17,23 ---- # be deleted. ! # Excplicitly assign the module doc string to __doc__ ! # (otherwise it won't show up which is probably a "bug" in Pyrex (v0.9.2.1)) ! __doc__ = """Python Open Dynamics Engine (ODE) wrapper. This module contains classes and functions that wrap the functionality *************** *** 41,44 **** --- 43,47 ---- - FixedJoint - ContactJoint + - AMotor Geom classes: *************** *** 183,186 **** --- 186,194 ---- def CloseODE(): + """CloseODE() + + Deallocate some extra memory used by ODE that can not be deallocated + using the normal destroy functions. + """ dCloseODE() |
From: Matthias B. <mb...@us...> - 2004-07-12 12:35:37
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7080 Modified Files: body.pyx Log Message: Updated/created doc strings Index: body.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/body.pyx,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** body.pyx 27 Jun 2004 20:46:17 -0000 1.1 --- body.pyx 12 Jul 2004 12:35:26 -0000 1.2 *************** *** 2,6 **** # Body cdef class Body: ! """Rigid body. """ --- 2,16 ---- # Body cdef class Body: ! """The rigid body class encapsulating the ODE body. ! ! This class represents a rigid body that has a location and orientation ! in space and that stores the mass properties of an object. ! ! When creating a Body object you have to pass the world it belongs to ! as argument to the constructor:: ! ! >>> import ode ! >>> w = ode.World() ! >>> b = ode.Body(w) """ *************** *** 15,26 **** def __new__(self, World world): - cdef World w - self.bid = NULL if world!=None: ! w = world ! self.bid = dBodyCreate(w.wid) ! def __init__(self, world): self.world = world self.userattribs = {} --- 25,38 ---- def __new__(self, World world): self.bid = NULL if world!=None: ! self.bid = dBodyCreate(world.wid) ! def __init__(self, World world): ! """Constructor. ! ! @param world: The world in which the body should be created. ! @type world: World ! """ self.world = world self.userattribs = {} *************** *** 47,54 **** --- 59,77 ---- # setPosition def setPosition(self, pos): + """setPosition(pos) + + Set the position of the body. + + @param pos: The new position + @type pos: 3-sequence of floats + """ dBodySetPosition(self.bid, pos[0], pos[1], pos[2]) # getPosition def getPosition(self): + """getPosition() -> 3-tuple + + Return the current position of the body. + """ cdef dReal* p # The "const" in the original return value is cast away *************** *** 58,61 **** --- 81,93 ---- # setRotation def setRotation(self, R): + """setRotation(R) + + Set the orientation of the body. The rotation matrix must be + given as a sequence of 9 floats which are the elements of the + matrix in row-major order. + + @param R: Rotation matrix + @type R: 9-sequence of floats + """ cdef dMatrix3 m m[0] = R[0] *************** *** 75,94 **** # getRotation def getRotation(self): cdef dReal* m # The "const" in the original return value is cast away m = <dReal*>dBodyGetRotation(self.bid) ! return [m[0],m[1],m[2],m[4],m[5],m[6],m[8],m[9],m[10]] def getQuaternion(self): cdef dReal* q q = <dReal*>dBodyGetQuaternion(self.bid) ! return [q[0], q[1], q[2], q[3]] # setLinearVel ! def setLinearVel(self, pos): ! dBodySetLinearVel(self.bid, pos[0], pos[1], pos[2]) # getLinearVel def getLinearVel(self): cdef dReal* p # The "const" in the original return value is cast away --- 107,165 ---- # getRotation def getRotation(self): + """getRotation() -> 9-tuple + + Return the current rotation matrix as a tuple of 9 floats (row-major + order). + """ cdef dReal* m # The "const" in the original return value is cast away m = <dReal*>dBodyGetRotation(self.bid) ! return (m[0],m[1],m[2],m[4],m[5],m[6],m[8],m[9],m[10]) + # getQuaternion def getQuaternion(self): + """getQuaternion() -> 4-tuple + + Return the current rotation as a quaternion. The return value + is a list of 4 floats. + """ cdef dReal* q q = <dReal*>dBodyGetQuaternion(self.bid) ! return (q[0], q[1], q[2], q[3]) ! ! # setQuaternion ! def setQuaternion(self, q): ! """setQuaternion(q) ! ! Set the orientation of the body. The quaternion must be given as a ! sequence of 4 floats. ! ! @param q: Quaternion ! @type q: 4-sequence of floats ! """ ! cdef dQuaternion w ! w[0] = q[0] ! w[1] = q[1] ! w[2] = q[2] ! w[3] = q[3] ! dBodySetQuaternion(self.bid, w) # setLinearVel ! def setLinearVel(self, vel): ! """setLinearVel(pos) ! ! Set the linear velocity of the body. ! ! @param vel: New velocity ! @type vel: 3-sequence of floats ! """ ! dBodySetLinearVel(self.bid, vel[0], vel[1], vel[2]) # getLinearVel def getLinearVel(self): + """getLinearVel() -> 3-tuple + + Get the current linear velocity of the body. + """ cdef dReal* p # The "const" in the original return value is cast away *************** *** 97,105 **** # setAngularVel ! def setAngularVel(self, pos): ! dBodySetAngularVel(self.bid, pos[0], pos[1], pos[2]) # getAngularVel def getAngularVel(self): cdef dReal* p # The "const" in the original return value is cast away --- 168,187 ---- # setAngularVel ! def setAngularVel(self, vel): ! """setAngularVel(pos) ! ! Set the angular velocity of the body. ! ! @param vel: New angular velocity ! @type vel: 3-sequence of floats ! """ ! dBodySetAngularVel(self.bid, vel[0], vel[1], vel[2]) # getAngularVel def getAngularVel(self): + """getAngularVel() -> 3-tuple + + Get the current angular velocity of the body. + """ cdef dReal* p # The "const" in the original return value is cast away *************** *** 109,116 **** --- 191,210 ---- # setMass def setMass(self, Mass mass): + """setMass(mass) + + Set the mass properties of the body. The argument mass must be + an instance of a Mass object. + + @param mass: Mass properties + @type mass: Mass + """ dBodySetMass(self.bid, &mass._mass) # getMass def getMass(self): + """getMass() -> mass + + Return the mass properties as a Mass object. + """ cdef Mass m m=Mass() *************** *** 120,155 **** # addForce def addForce(self, f): dBodyAddForce(self.bid, f[0], f[1], f[2]) # addTorque ! def addTorque(self, f): ! dBodyAddTorque(self.bid, f[0], f[1], f[2]) # addRelForce def addRelForce(self, f): dBodyAddRelForce(self.bid, f[0], f[1], f[2]) # addRelTorque ! def addRelTorque(self, f): ! dBodyAddRelTorque(self.bid, f[0], f[1], f[2]) # addForceAtPos def addForceAtPos(self, f, p): dBodyAddForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addForceAtRelPos def addForceAtRelPos(self, f, p): dBodyAddForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addRelForceAtPos def addRelForceAtPos(self, f, p): dBodyAddRelForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addRelForceAtRelPos def addRelForceAtRelPos(self, f, p): dBodyAddRelForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # getForce def getForce(self): cdef dReal* f # The "const" in the original return value is cast away --- 214,325 ---- # addForce def addForce(self, f): + """addForce(f) + + Add an external force f given in absolute coordinates. The force + is applied at the center of mass. + + @param f: Force + @type f: 3-sequence of floats + """ dBodyAddForce(self.bid, f[0], f[1], f[2]) # addTorque ! def addTorque(self, t): ! """addTorque(t) ! ! Add an external torque t given in absolute coordinates. ! ! @param t: Torque ! @type t: 3-sequence of floats ! """ ! dBodyAddTorque(self.bid, t[0], t[1], t[2]) # addRelForce def addRelForce(self, f): + """addRelForce(f) + + Add an external force f given in relative coordinates + (relative to the body's own frame of reference). The force + is applied at the center of mass. + + @param f: Force + @type f: 3-sequence of floats + """ dBodyAddRelForce(self.bid, f[0], f[1], f[2]) # addRelTorque ! def addRelTorque(self, t): ! """addRelTorque(t) ! ! Add an external torque t given in relative coordinates ! (relative to the body's own frame of reference). ! ! @param t: Torque ! @type t: 3-sequence of floats ! """ ! dBodyAddRelTorque(self.bid, t[0], t[1], t[2]) # addForceAtPos def addForceAtPos(self, f, p): + """addForceAtPos(f, p) + + Add an external force f at position p. Both arguments must be + given in absolute coordinates. + + @param f: Force + @param p: Position + @type f: 3-sequence of floats + @type p: 3-sequence of floats + """ dBodyAddForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addForceAtRelPos def addForceAtRelPos(self, f, p): + """addForceAtRelPos(f, p) + + Add an external force f at position p. f is given in absolute + coordinates and p in absolute coordinates. + + @param f: Force + @param p: Position + @type f: 3-sequence of floats + @type p: 3-sequence of floats + """ dBodyAddForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addRelForceAtPos def addRelForceAtPos(self, f, p): + """addRelForceAtPos(f, p) + + Add an external force f at position p. f is given in relative + coordinates and p in relative coordinates. + + @param f: Force + @param p: Position + @type f: 3-sequence of floats + @type p: 3-sequence of floats + """ dBodyAddRelForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # addRelForceAtRelPos def addRelForceAtRelPos(self, f, p): + """addRelForceAtRelPos(f, p) + + Add an external force f at position p. Both arguments must be + given in relative coordinates. + + @param f: Force + @param p: Position + @type f: 3-sequence of floats + @type p: 3-sequence of floats + """ dBodyAddRelForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2]) # getForce def getForce(self): + """getForce() -> 3-tuple + + Return the current accumulated force. + """ cdef dReal* f # The "const" in the original return value is cast away *************** *** 159,162 **** --- 329,336 ---- # getTorque def getTorque(self): + """getTorque() -> 3-tuple + + Return the current accumulated torque. + """ cdef dReal* f # The "const" in the original return value is cast away *************** *** 166,201 **** # setForce def setForce(self, f): dBodySetForce(self.bid, f[0], f[1], f[2]) # setTorque ! def setTorque(self, f): ! dBodySetTorque(self.bid, f[0], f[1], f[2]) # Enable def enable(self): dBodyEnable(self.bid) # Disable def disable(self): dBodyDisable(self.bid) # isEnabled def isEnabled(self): return dBodyIsEnabled(self.bid) # setFiniteRotationMode def setFiniteRotationMode(self, mode): dBodySetFiniteRotationMode(self.bid, mode) # getFiniteRotationMode def getFiniteRotationMode(self): return dBodyGetFiniteRotationMode(self.bid) # setFiniteRotationAxis def setFiniteRotationAxis(self, a): dBodySetFiniteRotationAxis(self.bid, a[0], a[1], a[2]) # getFiniteRotationAxis def getFiniteRotationAxis(self): cdef dVector3 p # The "const" in the original return value is cast away --- 340,441 ---- # setForce def setForce(self, f): + """setForce(f) + + Set the body force accumulation vector. + + @param f: Force + @type f: 3-tuple of floats + """ dBodySetForce(self.bid, f[0], f[1], f[2]) # setTorque ! def setTorque(self, t): ! """setTorque(t) ! ! Set the body torque accumulation vector. ! ! @param t: Torque ! @type t: 3-tuple of floats ! """ ! dBodySetTorque(self.bid, t[0], t[1], t[2]) # Enable def enable(self): + """enable() + + Manually enable a body. + """ dBodyEnable(self.bid) # Disable def disable(self): + """disable() + + Manually disable a body. Note that a disabled body that is connected + through a joint to an enabled body will be automatically re-enabled + at the next simulation step. + """ dBodyDisable(self.bid) # isEnabled def isEnabled(self): + """isEnabled() -> bool + + Check if a body is currently enabled. + """ return dBodyIsEnabled(self.bid) # setFiniteRotationMode def setFiniteRotationMode(self, mode): + """setFiniteRotationMode(mode) + + This function controls the way a body's orientation is updated at + each time step. The mode argument can be: + + - 0: An "infinitesimal" orientation update is used. This is + fast to compute, but it can occasionally cause inaccuracies + for bodies that are rotating at high speed, especially when + those bodies are joined to other bodies. This is the default + for every new body that is created. + + - 1: A "finite" orientation update is used. This is more + costly to compute, but will be more accurate for high speed + rotations. Note however that high speed rotations can result + in many types of error in a simulation, and this mode will + only fix one of those sources of error. + + @param mode: Rotation mode (0/1) + @type mode: int + """ dBodySetFiniteRotationMode(self.bid, mode) # getFiniteRotationMode def getFiniteRotationMode(self): + """getFiniteRotationMode() -> mode (0/1) + + Return the current finite rotation mode of a body (0 or 1). + See setFiniteRotationMode(). + """ return dBodyGetFiniteRotationMode(self.bid) # setFiniteRotationAxis def setFiniteRotationAxis(self, a): + """setFiniteRotationAxis(a) + + Set the finite rotation axis of the body. This axis only has a + meaning when the finite rotation mode is set + (see setFiniteRotationMode()). + + @param a: Axis + @type a: 3-sequence of floats + """ dBodySetFiniteRotationAxis(self.bid, a[0], a[1], a[2]) # getFiniteRotationAxis def getFiniteRotationAxis(self): + """getFiniteRotationAxis() -> 3-tuple + + Return the current finite rotation axis of the body. + """ cdef dVector3 p # The "const" in the original return value is cast away *************** *** 205,215 **** --- 445,472 ---- # getNumJoints def getNumJoints(self): + """getNumJoints() -> int + + Return the number of joints that are attached to this body. + """ return dBodyGetNumJoints(self.bid) # setGravityMode def setGravityMode(self, mode): + """setGravityMode(mode) + + Set whether the body is influenced by the world's gravity + or not. If mode is True it is, otherwise it isn't. + Newly created bodies are always influenced by the world's gravity. + + @param mode: Gravity mode + @type mode: bool + """ dBodySetGravityMode(self.bid, mode) # getGravityMode def getGravityMode(self): + """getGravityMode() -> bool + + Return True if the body is influenced by the world's gravity. + """ return dBodyGetGravityMode(self.bid) |
From: Timothy S. <pe...@us...> - 2004-07-07 11:46:42
|
Update of /cvsroot/pyode/pyode/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12588/tests Added Files: test_xode.py Log Message: - Added XODE importer package and unit tests. - Modified examples/tutorial2.py to use XODE. The original code is still there and can be used by changing the second to last line. - Added a getBody() method to the Joint class. --- NEW FILE: test_xode.py --- #!/usr/bin/env python import unittest import ode from xode import node, transform, parser test_doc = '''<?xml version="1.0"?> <xode> <world name="world1"> <transform> <matrix4f m00="1.0" m01="2.0" m02="3.0" m03="4.0" m10="1.2" m11="2.2" m12="3.2" m13="4.2" m20="1.4" m21="2.4" m22="3.4" m23="4.4" m30="1.8" m31="2.8" m32="3.8" m33="4.8"/> </transform> <space name="space1"> <body name="body1" enabled="false" gravitymode="0"> <transform scale="2.0"> <position x="10.0" y="11.0" z="12.0"/> <rotation> <euler x="45.0" y="45.0" z="45.0" aformat="radians"/> </rotation> </transform> <torque x="1.0" y="2.0" z="3.0"/> <force x="2.0" y="3.0" z="4.0"/> <finiteRotation mode="1" xaxis="1.0" yaxis="1.0" zaxis="1.0"/> <linearVel x="1.0" y="2.0" z="3.0"/> <angularVel x="3.0" y="2.0" z="1.0"/> <mass name="mass1"> <mass_shape density="1.0"> <sphere radius="1.0"/> </mass_shape> <mass name="mass2"> <mass_shape density="2.0"> <sphere radius="10.0"/> </mass_shape> <adjust total="4.0"/> </mass> </mass> <joint name="joint1"> <ball> <anchor x="1.0" y="2.0" z="3.0"/> </ball> </joint> </body> <body name="body2"> <joint name="joint2"> <link1 body="body1"/> <ball/> </joint> </body> <joint name="joint3"> <link1 body="body1"/> <link2 body="body2"/> <ball/> </joint> </space> </world> <world name="world2"> <space> <body name="body3"> <transform> <matrix4f m00="0.0" m01="0.0" m02="1.0" m03="0.0" m10="0.0" m11="1.0" m12="0.0" m13="0.0" m20="1.0" m21="0.0" m22="0.0" m23="0.0" m30="10.0" m31="20.0" m32="30.0" m33="0.0"/> </transform> </body> </space> </world> </xode>''' class Class1: pass class Class2: pass class TestTreeNode(unittest.TestCase): def setUp(self): self.node1 = node.TreeNode('node1', None) self.node2 = node.TreeNode('node2', self.node1) self.node3 = node.TreeNode('node3', self.node2) self.t2 = transform.Transform() self.t2.scale(2.0, 3.0, 4.0) self.node2.setNodeTransform(self.t2) self.t3 = transform.Transform() self.t3.rotate(1.0, 2.0, 3.0) self.node3.setNodeTransform(self.t3) self.node1.setODEObject(Class2()) self.node2.setODEObject(Class2()) self.node3.setODEObject(Class1()) def testGetName(self): self.assertEqual(self.node1.getName(), 'node1') def testGetParent(self): self.assertEqual(self.node2.getParent(), self.node1) def testGetChildren(self): self.assertEqual(self.node1.getChildren(), [self.node2]) self.assertEqual(self.node2.getChildren(), [self.node3]) self.assertEqual(self.node3.getChildren(), []) def testNamedChildLocal(self): self.assertEqual(self.node1.namedChild('node2'), self.node2) def testNamedChildRemote(self): self.assertEqual(self.node1.namedChild('node3'), self.node3) def testNamedChildNotFound(self): self.assertRaises(KeyError, self.node1.namedChild, 'undefined') def testGetFirstAncestor(self): self.assertEqual(self.node3.getFirstAncestor(Class2), self.node2) def testGetFirstAncestorNotFound(self): self.assertRaises(node.AncestorNotFoundError, self.node3.getFirstAncestor, Class1) def testInitialTransform(self): t = transform.Transform() t.setIdentity() self.assertEqual(self.node1.getNodeTransform().m, t.m) def testGetTransform(self): ref = self.node1.getNodeTransform() * self.t2 * self.t3 self.assertEqual(self.node3.getTransform().m, ref.m) class TestParser(unittest.TestCase): def setUp(self): self.p = parser.Parser() self.root = self.p.parseString(test_doc) class TestWorldParser(TestParser): def testInstance(self): world = self.root.namedChild('world1').getODEObject() self.assert_(isinstance(world, ode.World)) class TestSpaceParser(TestParser): def testInstance(self): space = self.root.namedChild('space1').getODEObject() self.assert_(isinstance(space, ode.Space)) class TestBodyParser(TestParser): def setUp(self): TestParser.setUp(self) self.body1 = self.root.namedChild('body1').getODEObject() self.body3 = self.root.namedChild('body3').getODEObject() def testInstance(self): self.assert_(isinstance(self.body1, ode.Body)) def testRotation(self): # FIXME? #self.assertEqual(self.body3.getRotation(), [0.0, 0.0, 1.0, # 0.0, 1.0, 0.0, # 1.0, 0.0, 0.0]) pass def testPosition(self): self.assertEqual(self.body3.getPosition(), (10.0, 20.0, 30.0)) def testEnable(self): self.assertEqual(self.body1.isEnabled(), 0) def testGravityMode(self): self.assertEqual(self.body1.getGravityMode(), 0) def testTorque(self): self.assertEqual(self.body1.getTorque(), (1.0, 2.0, 3.0)) def testForce(self): self.assertEqual(self.body1.getForce(), (2.0, 3.0, 4.0)) def testFiniteRotation(self): self.assertEqual(self.body1.getFiniteRotationMode(), 1) x, y, z = self.body1.getFiniteRotationAxis() self.assertEqual(x, y, z) def testLinearVel(self): self.assertEqual(self.body1.getLinearVel(), (1.0, 2.0, 3.0)) def testAngularVel(self): self.assertEqual(self.body1.getAngularVel(), (3.0, 2.0, 1.0)) class TestMassParser(TestParser): def setUp(self): TestParser.setUp(self) self.mass1 = self.root.namedChild('mass1').getODEObject() self.mass2 = self.root.namedChild('mass2').getODEObject() self.ref2 = ode.Mass() self.ref2.setSphere(2.0, 10.0) self.ref2.adjust(4.0) def testInstance(self): self.assert_(isinstance(self.mass1, ode.Mass)) def testTotal(self): self.assertEqual(self.mass2.mass, 4.0) def testSphere(self): self.assertEqual(self.ref2.c, self.mass2.c) self.assertEqual(self.ref2.I, self.mass2.I) def testAdd(self): ref = ode.Mass() ref.setSphere(1.0, 1.0) ref.add(self.ref2) self.assertEqual(ref.c, self.mass1.c) self.assertEqual(ref.I, self.mass1.I) class TestJointParser(TestParser): def setUp(self): TestParser.setUp(self) self.body1 = self.root.namedChild('body1').getODEObject() self.body2 = self.root.namedChild('body2').getODEObject() self.joint1 = self.root.namedChild('joint1').getODEObject() self.joint2 = self.root.namedChild('joint2').getODEObject() self.joint3 = self.root.namedChild('joint3').getODEObject() def testInstance(self): self.assert_(isinstance(self.joint1, ode.BallJoint)) def testBodyAncestor(self): self.assertEqual(self.joint1.getBody(0), self.body1) def testEnvironment(self): self.assertEqual(self.joint1.getBody(1), ode.environment) def testBodyReference(self): self.assertEqual(self.joint2.getBody(0), self.body1) def testSpaceParent(self): self.assertEqual(self.joint3.getBody(0), self.body1) self.assertEqual(self.joint3.getBody(1), self.body2) def testBallAnchor(self): # FIXME? #self.assertEqual(self.joint1.getAnchor(), (1.0, 2.0, 3.0)) pass class TestTransformParser(TestParser): def setUp(self): TestParser.setUp(self) self.world1 = self.root.namedChild('world1') self.body1 = self.root.namedChild('body1') def testMatrixStyle(self): t = self.world1.getNodeTransform() self.assertEqual(t.m, [[1.0, 2.0, 3.0, 4.0], [1.2, 2.2, 3.2, 4.2], [1.4, 2.4, 3.4, 4.4], [1.8, 2.8, 3.8, 4.8]]) def testVector(self): ref = transform.Transform() ref.translate(10.0, 11.0, 12.0) ref.rotate(45.0, 45.0, 45.0) ref.scale(2.0, 2.0, 2.0) self.assertEqual(self.body1.getNodeTransform().m, ref.m) def testMultiply(self): t1 = transform.Transform() t2 = transform.Transform() for r in range(4): for c in range(4): t1.m[r][c] = 1 t2.m[r][c] = 2 result = t1 * t2 for r in range(4): for c in range(4): self.assertEqual(result.m[r][c], 8) def testInitialIdentity(self): t = transform.Transform() for r in range(4): for c in range(4): if (r == c): self.assertEqual(t.m[r][c], 1) else: self.assertEqual(t.m[r][c], 0) class TestInvalid(unittest.TestCase): def setUp(self): self.p = parser.Parser() class TestInvalidTags(TestInvalid): def testRoot(self): self.assertRaises(parser.InvalidError, self.p.parseString, '<?xml version="1.0"?>\n<test></test>') def testRootChild(self): self.assertRaises(parser.InvalidError, self.p.parseString, '<?xml version="1.0"?>\n<xode><test/></xode>') def testWorldChild(self): doc = '''<?xml version="1.0"?> <xode><world> <test/> </world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testSpaceChild(self): doc = '''<?xml version="1.0"?> <xode><world><space> <test/> </space></world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testMassChild(self): doc = '''<?xml version="1.0"?> <xode><world><space> <body> <mass> <test/> </mass> </body> </space></world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testJointChild(self): doc = '''<?xml version="1.0"?> <xode><world><space><joint><test/></joint></space></world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) class TestInvalidBody(TestInvalid): def testBadVector(self): doc = '''<?xml version="1.0"?> <xode><world> <body> <torque x="1"/> </body> </world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testBodyEnable(self): doc = '''<?xml version="1.0"?> <xode><world> <body enabled="unsure"> </body> </world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testFiniteRotationMode(self): doc = '''<?xml version="1.0"?> <xode><world> <body> <finiteRotation mode="99" xaxis="0" yaxis="0" zaxis="0"/> </body> </world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testFiniteRotationAxes(self): doc = '''<?xml version="1.0"?> <xode><world> <body> <finiteRotation mode="0" xaxis="0" yaxis="0"/> </body> </world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) class TestInvalidJoint(TestInvalid): def testEqualLinks(self): doc = '''<?xml version="1.0"?> <xode><world><space> <joint> <ball/> </joint> </space></world></xode>''' # both links are ode.environment self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testNoType(self): doc = '''<?xml version="1.0"?> <xode><world><space> <joint/> </space></world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testWrongType(self): doc = '''<?xml version="1.0"?> <xode><world><space name="space1"> <body name="body1"/> <joint> <link1 body="body1"/> <link2 body="space1"/> <ball/> </joint> </space></world></xode>''' self.assertRaises(parser.InvalidError, self.p.parseString, doc) def testMisplacedReference(self): doc = '''<?xml version="1.0"?> <xode><world><space name="space1"> <body name="body1"/> <joint> <link1 body="body1"/> <link2 body="body2"/> <ball/> </joint> <body name="body2"/> </space></world></xode>''' # bodies must be defined before the joint self.assertRaises(parser.InvalidError, self.p.parseString, doc) if (__name__ == '__main__'): unittest.main() |
From: Timothy S. <pe...@us...> - 2004-07-07 11:46:42
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12588/src Modified Files: joints.pyx Log Message: - Added XODE importer package and unit tests. - Modified examples/tutorial2.py to use XODE. The original code is still there and can be used by changing the second to last line. - Added a getBody() method to the Joint class. Index: joints.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/joints.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** joints.pyx 3 Jul 2004 16:57:41 -0000 1.2 --- joints.pyx 7 Jul 2004 11:46:32 -0000 1.3 *************** *** 68,75 **** --- 68,80 ---- cdef dJointFeedback* feedback + cdef object body1 + cdef object body2 + def __new__(self, *a, **kw): self.jid = NULL self.world = None self.feedback = NULL + self.body1 = None + self.body2 = None def __init__(self, *a, **kw): *************** *** 94,99 **** --- 99,116 ---- def attach(self, Body Body1, Body Body2): """TODO: What if there's only one body.""" + + self.body1 = Body1 + self.body2 = Body2 dJointAttach(self.jid, Body1.bid, Body2.bid) + # getBody + def getBody(self, index): + if (index == 0): + return self.body1 + elif (index == 1): + return self.body2 + else: + raise IndexError() + # setFeedback def setFeedback(self, flag=1): *************** *** 143,148 **** ###################################################################### ! ! # BallJoint cdef class BallJoint(Joint): --- 160,165 ---- ###################################################################### ! ! # BallJoint cdef class BallJoint(Joint): |
From: Timothy S. <pe...@us...> - 2004-07-07 11:46:42
|
Update of /cvsroot/pyode/pyode/examples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12588/examples Modified Files: tutorial2.py Log Message: - Added XODE importer package and unit tests. - Modified examples/tutorial2.py to use XODE. The original code is still there and can be used by changing the second to last line. - Added a getBody() method to the Joint class. Index: tutorial2.py =================================================================== RCS file: /cvsroot/pyode/pyode/examples/tutorial2.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tutorial2.py 27 Jun 2004 20:46:16 -0000 1.1 --- tutorial2.py 7 Jul 2004 11:46:32 -0000 1.2 *************** *** 5,8 **** --- 5,57 ---- from pygame.locals import * import ode + import xode.parser + + doc = '''<?xml version="1.0"?> + <xode> + <world name="world"> + <space> + + <body name="body1"> + <transform> + <position x="1" y="2" z="0"/> + </transform> + + <mass> + <mass_shape density="2500"> + <sphere radius="0.05"/> + </mass_shape> + + </mass> + </body> + + <body name="body2"> + <transform> + <position x="2" y="2" z="0"/> + </transform> + + <mass> + <mass_shape density="2500"> + <sphere radius="0.05"/> + </mass_shape> + </mass> + + <joint name="joint2"> + <link1 body="body1"/> + <ball> + <anchor x="1" y="2" z="0"/> + </ball> + </joint> + </body> + + <joint name="joint1"> + <link1 body="body1"/> + <ball> + <anchor x="0" y="2" z="0"/> + </ball> + </joint> + + </space> + </world> + </xode>''' def coord(x,y): *************** *** 10,79 **** return 320+170*x, 400-170*y ! # Initialize pygame ! pygame.init() ! # Open a display ! srf = pygame.display.set_mode((640,480)) ! world = ode.World() ! world.setGravity((0,-9.81,0)) ! body1 = ode.Body(world) ! M = ode.Mass() ! M.setSphere(2500, 0.05) ! body1.setMass(M) ! body1.setPosition((1,2,0)) ! body2 = ode.Body(world) ! M = ode.Mass() ! M.setSphere(2500, 0.05) ! body2.setMass(M) ! body2.setPosition((2,2,0)) ! j1 = ode.BallJoint(world) ! j1.attach(body1, ode.environment) ! j1.setAnchor( (0,2,0) ) ! #j1 = ode.HingeJoint(world) ! #j1.attach(body1, ode.environment) ! #j1.setAnchor( (0,2,0) ) ! #j1.setAxis( (0,0,1) ) ! #j1.setParam(ode.ParamVel, 3) ! #j1.setParam(ode.ParamFMax, 22) ! j2 = ode.BallJoint(world) ! j2.attach(body1, body2) ! j2.setAnchor( (1,2,0) ) ! clk = pygame.time.Clock() ! # Keep the window open and wait for a key ! fps = 50 ! dt = 1.0/fps ! loopFlag = True ! while loopFlag: ! events = pygame.event.get() ! for e in events: ! if e.type==QUIT: ! loopFlag=False ! # if e.type==KEYDOWN: ! # loopFlag=False ! # Clear the screen ! srf.fill((255,255,255)) ! x1,y1,z1 = body1.getPosition() ! x2,y2,z2 = body2.getPosition() ! pygame.draw.circle(srf, (55,0,200), coord(x1,y1), 20, 0) ! pygame.draw.line(srf, (55,0,200), coord(0,2), coord(x1,y1), 2) ! pygame.draw.circle(srf, (55,0,200), coord(x2,y2), 20, 0) ! pygame.draw.line(srf, (55,0,200), coord(x1,y1), coord(x2,y2), 2) ! pygame.display.flip() ! world.step(dt) ! ! clk.tick(fps) ! # print "fps: %2.1f dt:%d rawdt:%d"%(clk.get_fps(), clk.get_time(), clk.get_rawtime()) ! --- 59,155 ---- return 320+170*x, 400-170*y + def buildObjects(): + world = ode.World() + world.setGravity((0,-9.81,0)) ! body1 = ode.Body(world) ! M = ode.Mass() ! M.setSphere(2500, 0.05) ! body1.setMass(M) ! body1.setPosition((1,2,0)) ! ! body2 = ode.Body(world) ! M = ode.Mass() ! M.setSphere(2500, 0.05) ! body2.setMass(M) ! body2.setPosition((2,2,0)) ! ! j1 = ode.BallJoint(world) ! j1.attach(body1, ode.environment) ! j1.setAnchor( (0,2,0) ) ! #j1 = ode.HingeJoint(world) ! #j1.attach(body1, ode.environment) ! #j1.setAnchor( (0,2,0) ) ! #j1.setAxis( (0,0,1) ) ! #j1.setParam(ode.ParamVel, 3) ! #j1.setParam(ode.ParamFMax, 22) ! j2 = ode.BallJoint(world) ! j2.attach(body1, body2) ! j2.setAnchor( (1,2,0) ) ! return world, body1, body2, j1, j2 ! def buildObjectsXODE(): ! p = xode.parser.Parser() ! root = p.parseString(doc) ! world = root.namedChild('world').getODEObject() ! body1 = root.namedChild('body1').getODEObject() ! body2 = root.namedChild('body2').getODEObject() ! j1 = root.namedChild('joint1').getODEObject() ! j2 = root.namedChild('joint2').getODEObject() ! world.setGravity((0,-9.81,0)) ! #body1.setPosition((1,2,0)) ! #body2.setPosition((2,2,0)) ! #j1 = ode.BallJoint(world) ! #j1.attach(body1, ode.environment) ! #j1.setAnchor( (0,2,0) ) ! #j2 = ode.BallJoint(world) ! #j2.attach(body1, body2) ! #j2.setAnchor( (1,2,0) ) ! return world, body1, body2, j1, j2 ! def simulate(world, body1, body2): ! # Initialize pygame ! pygame.init() ! ! # Open a display ! srf = pygame.display.set_mode((640,480)) ! clk = pygame.time.Clock() ! # Keep the window open and wait for a key ! fps = 50 ! dt = 1.0/fps ! loopFlag = True ! while loopFlag: ! events = pygame.event.get() ! for e in events: ! if e.type==QUIT: ! loopFlag=False ! ! # Clear the screen ! srf.fill((255,255,255)) ! x1,y1,z1 = body1.getPosition() ! x2,y2,z2 = body2.getPosition() ! pygame.draw.circle(srf, (55,0,200), coord(x1,y1), 20, 0) ! pygame.draw.line(srf, (55,0,200), coord(0,2), coord(x1,y1), 2) ! pygame.draw.circle(srf, (55,0,200), coord(x2,y2), 20, 0) ! pygame.draw.line(srf, (55,0,200), coord(x1,y1), coord(x2,y2), 2) ! ! pygame.display.flip() + world.step(dt) + + clk.tick(fps) + #print "fps: %2.1f dt:%d rawdt:%d"%(clk.get_fps(), clk.get_time(), clk.get_rawtime()) + + + world, body1, body2, j1, j2 = buildObjectsXODE() + simulate(world, body1, body2) |
From: Timothy S. <pe...@us...> - 2004-07-07 11:46:41
|
Update of /cvsroot/pyode/pyode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12588 Modified Files: setup.py Log Message: - Added XODE importer package and unit tests. - Modified examples/tutorial2.py to use XODE. The original code is still there and can be used by changing the second to last line. - Added a getBody() method to the Joint class. Index: setup.py =================================================================== RCS file: /cvsroot/pyode/pyode/setup.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup.py 27 Jun 2004 20:46:16 -0000 1.1 --- setup.py 7 Jul 2004 11:46:32 -0000 1.2 *************** *** 88,91 **** --- 88,92 ---- # author_email="ba...@ir...", # license="BSD license, see license*.txt", + packages=["xode"], ext_modules=[Extension("ode", ["ode.c"] ,libraries=LIBS |
From: Timothy S. <pe...@us...> - 2004-07-07 11:41:53
|
Update of /cvsroot/pyode/pyode/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12348/tests Log Message: Directory /cvsroot/pyode/pyode/tests added to the repository |
From: Timothy S. <pe...@us...> - 2004-07-07 11:37:20
|
Update of /cvsroot/pyode/pyode/xode In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11553/xode Log Message: Directory /cvsroot/pyode/pyode/xode added to the repository |
From: Matthias B. <mb...@us...> - 2004-07-05 20:01:45
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25284/src Modified Files: mass.pyx Log Message: Overlooked another parameter renaming Index: mass.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/mass.pyx,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** mass.pyx 5 Jul 2004 19:57:20 -0000 1.3 --- mass.pyx 5 Jul 2004 20:01:37 -0000 1.4 *************** *** 57,61 **** @type I23: float """ ! dMassSetParameters(&self._mass, themass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23) def setSphere(self, density, radius): --- 57,61 ---- @type I23: float """ ! dMassSetParameters(&self._mass, mass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23) def setSphere(self, density, radius): |
From: Matthias B. <mb...@us...> - 2004-07-05 19:57:28
|
Update of /cvsroot/pyode/pyode/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24422/src Modified Files: mass.pyx Log Message: Forgot the rename two arguments in a doc string Index: mass.pyx =================================================================== RCS file: /cvsroot/pyode/pyode/src/mass.pyx,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** mass.pyx 5 Jul 2004 15:37:12 -0000 1.2 --- mass.pyx 5 Jul 2004 19:57:20 -0000 1.3 *************** *** 73,77 **** def setCappedCylinder(self, density, direction, r, h): ! """setCappedCylinder(density, direction, a, b) Set the mass parameters to represent a capped cylinder of the --- 73,77 ---- def setCappedCylinder(self, density, direction, r, h): ! """setCappedCylinder(density, direction, r, h) Set the mass parameters to represent a capped cylinder of the |