Ruby-ODE-SWIG

Copyright © 2008 William de Beaumont <wdebeaum at gmail.com>

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Description

Ruby-ODE-SWIG provides Ruby language bindings for the Open Dynamics Engine (ODE), written using the Simplified Wrapper and Interface Generator (SWIG). I wrote it so I could use it in my game, Modularity (which is still at a very early stage of development).

Requirements

  • Ruby

  • ODE

  • SWIG

To Install

gem install Ruby-ODE-SWIG

To Use

require "ode"
w = ODE::World.new
# etc.

RubyForge Pages

Similar Projects

Ruby-ODE

Author: Michael Granger

URL: www.deveiate.org/projects/Ruby-ODE/

License: Creative Commons Attribution

Description

Written in straight C (no wrapper generator) for use in FaerieMUD.

Why I didn’t use it

  • It appears to be unmaintained since about 2003. The latest version is 0.01.

  • It doesn’t compile on the amd64 architecture due to pointer size issues.

  • It’s not very DRY (which made fixing the above point harder than it should have been).

ruby-ode

Author: Marcel Toele?

URL: rubyforge.org/frs/shownotes.php?release_id=5051

License: GPL

Description

Written using Ruby/DLX (a Ruby library for interfacing with C), as one of the demos thereof.

Why I didn’t use it

  • I had already started Ruby-ODE-SWIG when I discovered it.

  • It also appears unmaintained, since 2006.

  • It’s still not very DRY.

About the Code

I only wrote in C what was necessary, which turned out to be very little. Mostly I just “include”d all the ODE headers in ode.i, and let SWIG figure it out. The SWIG documentation recommends not doing it this way, but it seems to work OK. Just ignore all the warnings you get ;)

The only function I really had to wrap by hand in C was dCollide, which fills a variable-sized array argument. I wrote dCollideRuby to instead return a Ruby array of the desired size. I also wrote a typemap for using Ruby Procs for collision callbacks, and a couple functions necessary for using SWIG pointer objects in hash tables.

Most of the real magic happens in ode.rb, where I was able to use Ruby’s reflection capabilities to more concisely express the relationship between Ruby method calls and C function calls. SWIG puts all its wrapped methods in the Ode module (which I’ve given the alternative name ODE). I’ve made Ruby classes whose instances act as proxies for ODE classes. The generic support for this is in the ODE::ObjectID module, which those classes include.

ObjectID handles creating ODE objects with their Ruby proxies (via initialize), and converting conventional Ruby method calls (e.g. ODE::World#gravity=(v)) to their more C-ish counterparts (e.g. ODE.dWorldSetGravity(id,x,y,z)). In a few cases I manually mapped lower-case versions of method names that would have started with an upper-case letter otherwise (e.g. ODE::World#erp=(v) => ODE.dWorldSetERP(id,v)).

Vectors (and matrices) are automatically converted between ODE dVectorN and Ruby arrays of floats of length N. Unfortunately, in many cases I have to specify N, since that information isn’t actually contained in the C headers in a way that SWIG can use. I also standardize on passing vectors as single arguments, rather than passing them as a separate argument for each coordinate (as happens some of the time in ODE).

Some C structs can be initialized using the from_hash class method, e.g.:

surface_parameters =
  ODE::DSurfaceParameters.from_hash(
    :mode => ODE::DContactBounce,
    :mu => 0,
    :bounce => 0.5,
    :bounce_vel => 0
    )

from_hash creates a new C structure object and calls the Ruby setter methods for each of the hash keys on the corresponding value. Those setters are generated by SWIG.

ODE::Space#collide and ODE::Space#collide2 both may take either a block, or a Proc as the last argument, to be used as a callback. It will be called with the two potentially colliding ODE::Geom objects as arguments. See the ODE documentation for what to do in the callback.