| Class | ODE::Space |
| In: |
ext/body.c
(CVS)
lib/ode/space.rb (CVS) |
| Parent: | ODE::Geometry |
Instance of this class are collision spaces..
ODE::Space Singleton allocator
/*
* ODE::Space Singleton allocator
*/
static VALUE
ode_space_s_alloc( klass )
VALUE klass;
{
debugMsg(( "Wrapping an uninitialized ODE::Space ptr." ));
return Data_Wrap_Struct( klass, ode_space_gc_mark, ode_space_gc_free, 0 );
}
Base initializer.
/*
* Base initializer.
*/
static VALUE
ode_space_init( argc, argv, self )
int argc;
VALUE *argv, self;
{
debugMsg(( "ODE::Space init." ));
/* Create the underlying dSpaceID object if it hasn't been already */
if ( !check_space(self) ) {
ode_GEOMETRY *ptr;
dSpaceID containerSpace = 0;
VALUE container = Qnil;
debugMsg(( "Space::initialize: Fetching new data object." ));
/* If they gave a container space, fetch it */
if ( rb_scan_args(argc, argv, "01", &container) ) {
ode_GEOMETRY *containerPtr;
containerPtr = get_space( container );
debugMsg(( "Got container space <%p>", containerPtr ));
containerSpace = (dSpaceID)containerPtr->id;
}
/* Allocate the ode_GEOMETRY struct for this space */
DATA_PTR(self) = ptr = ode_space_alloc();
ptr->object = self;
ptr->container = container;
debugMsg(( "New space = <%p>", ptr ));
/* Create the ODE space object according to which class is being initialized */
if ( CLASS_OF(self) == ode_cOdeSpace )
ptr->id = (dGeomID)dSimpleSpaceCreate( containerSpace );
else if ( CLASS_OF(self) == ode_cOdeHashSpace )
ptr->id = (dGeomID)dHashSpaceCreate( containerSpace );
else
rb_raise( rb_eTypeError, "No allocator defined for a %s.",
rb_class2name(CLASS_OF( self )) );
/* Tell ODE not to clean up its spaces itself to prevent running around
pointing to freed memory */
debugMsg(( "Turning off cleanup flag." ));
dSpaceSetCleanup( (dSpaceID)ptr->id, 0 );
/* Set the ode_GEOMETRY struct as the space's data pointer so we can get
the object from the dSpaceID */
dGeomSetData( ptr->id, ptr );
}
/* Call our parent's initializer */
debugMsg(( "Calling super()" ));
rb_call_super( 0, 0 );
debugMsg(( "Back from super()" ));
return self;
}
addGeometries( *geometries ) — Add the specified geometries (ODE::Geometry objects) to the receiving space and return the space itself.
/*
* addGeometries( *geometries )
* --
* Add the specified geometries (ODE::Geometry objects) to the receiving
* space and return the space itself.
*/
static VALUE
ode_space_insert( self, args )
VALUE self, args;
{
ode_GEOMETRY *ptr = get_space( self );
int i = 0;
if ( TYPE(args) != T_ARRAY )
rb_bug( "Expected array, got a %s.", rb_class2name(CLASS_OF(args)) );
for ( i = 0; i < RARRAY(args)->len; i++ ) {
ode_GEOMETRY *cptr = ode_get_geom( *(RARRAY(args)->ptr + i) );
dSpaceAdd( (dSpaceID)ptr->id, (dGeomID)cptr->id );
}
return self;
}
contains?( geom ) — Returns true if the receiving space, or any of the spaces it contains (recursively), contains the specified geom (an ODE::Geometry object).
/*
* contains?( geom )
* --
* Returns true if the receiving space, or any of the spaces it contains
* (recursively), contains the specified <tt>geom</tt> (an ODE::Geometry
* object).
*/
static VALUE
ode_space_contains_p( self, geom )
VALUE self, geom;
{
ode_GEOMETRY *ptr = get_space( self );
ode_GEOMETRY *targetPtr = ode_get_geom( geom );
if ( ode_spaceId_contains((dSpaceID)ptr->id, targetPtr->id) )
return Qtrue;
else
return Qfalse;
}
directlyContains?( geom ) — Returns true if the receiving space contains the geom (an ODE::Geometry object) specified. This, unlike contains?, does not recurse into contained subspaces.
/*
* directlyContains?( geom )
* --
* Returns true if the receiving space contains the geom (an ODE::Geometry
* object) specified. This, unlike contains?, does not recurse into contained
* subspaces.
*/
static VALUE
ode_space_directly_contains_p( self, geom )
VALUE self, geom;
{
ode_GEOMETRY *ptr = get_space( self );
ode_GEOMETRY *otherptr = ode_get_geom( geom );
if ( dSpaceQuery((dSpaceID)ptr->id, otherptr->id) )
return Qtrue;
else
return Qfalse;
}
each( &block ) — Iterate over the geometries in the space, passing each to the given block.
/*
* each( &block )
* --
* Iterate over the geometries in the space, passing each to the given block.
*/
static VALUE
ode_space_each( self )
VALUE self;
{
ode_GEOMETRY *ptr = get_space( self );
VALUE rary = rb_ary_new();
int i, geomCount = dSpaceGetNumGeoms( (dSpaceID)ptr->id );
if ( !rb_block_given_p() )
rb_raise( ruby_eLocalJumpError, "no block given" );
for ( i = 0 ; i < geomCount ; i++ ) {
dGeomID subgeom = dSpaceGetGeom( (dSpaceID)ptr->id, i );
ode_GEOMETRY *subgeomPtr = dGeomGetData(subgeom);
rb_ary_push( rary, rb_yield(subgeomPtr->object) );
}
return rary;
}
eachAdjacentPair( *data ) {|geom1, geom2, *data| block } — Call the specified block once for each adjacent pair of ODE::Geometry objects in the receiving space. The block must accept three arguments: the two geometries and a data Array.
/*
* eachAdjacentPair( *data ) {|geom1, geom2, *data| block }
* --
* Call the specified <tt>block</tt> once for each adjacent pair of
* ODE::Geometry objects in the receiving space. The block must accept three
* arguments: the two geometries and a <tt>data</tt> Array.
*/
static VALUE
ode_space_each_adjacent_pair( argc, argv, self )
int argc;
VALUE *argv, self;
{
ode_GEOMETRY *ptr = get_space( self );
ode_CALLBACK *callback;
VALUE data, block;
rb_scan_args( argc, argv, "0*&", &data, &block );
ode_check_arity( block, 3 );
callback = ALLOCA_N( ode_CALLBACK, 1 );
callback->callback = block;
callback->args = data;
dSpaceCollide( (dSpaceID)ptr->id, callback,
(dNearCallback *)(ode_near_callback) );
return Qtrue;
}
geometries — Returns an Array of all the geometries (ODE::Geometry objects) contained in this space.
/*
* geometries
* --
* Returns an Array of all the geometries (ODE::Geometry objects) contained in
* this space.
*/
static VALUE
ode_space_geometries( self )
VALUE self;
{
ode_GEOMETRY *ptr = get_space( self );
VALUE rary = rb_ary_new();
int i, geomCount = dSpaceGetNumGeoms( (dSpaceID)ptr->id );
for ( i = 0 ; i < geomCount ; i++ ) {
dGeomID geom = dSpaceGetGeom( (dSpaceID)ptr->id, i );
rb_ary_push( rary, ((ode_GEOMETRY *)dGeomGetData(geom))->object );
}
return rary;
}
geometries=( geometryArray ) — Set the geometries in the receiving space to the given Array of geometries (ODE::Geometry objects).
/*
* geometries=( geometryArray )
* --
* Set the geometries in the receiving space to the given Array of geometries
* (ODE::Geometry objects).
*/
static VALUE
ode_space_geometries_eq( self, geometryArray )
VALUE self, geometryArray;
{
ode_GEOMETRY *ptr = get_space( self );
dSpaceID thisSpace = (dSpaceID)( ptr->id );
int i, geomCount = dSpaceGetNumGeoms( (dSpaceID)ptr->id );
VALUE removeGeoms = rb_ary_new(),
addGeoms = rb_ary_new();
Check_Type( geometryArray, T_ARRAY );
/* First remove any geometries that aren't in the new array -- Build an
array of all geometries that are currently in the space but aren't in the
new array. */
for ( i = 0 ; i < geomCount ; i++ ) {
dGeomID geom = dSpaceGetGeom( thisSpace, i );
ode_GEOMETRY *gptr = dGeomGetData( geom );
if ( !RTEST(rb_ary_includes( geometryArray, gptr->object )) )
rb_ary_push( removeGeoms, gptr->object );
}
/* If there are any geometries to remove, remove them via #removeGeometries to give
derivatives a chance to act on the removals. */
if ( RARRAY(removeGeoms)->len )
rb_funcall( self, rb_intern("removeGeometries"), 1, &removeGeoms );
/* Now make an array of geometries which are in the new array, but aren't in
the space currently. */
for ( i = 0 ; i < RARRAY(geometryArray)->len ; i++ ) {
ode_GEOMETRY *geom = ode_get_geom( *(RARRAY(geometryArray)->ptr + i) );
if ( !dSpaceQuery(thisSpace, geom->id) )
rb_ary_push( addGeoms, geom->object );
}
/* If there are any geometries to add, add them via #addGeometries to give
derivatives a chance to act on the additions. */
if ( RARRAY(addGeoms)->len )
rb_funcall( self, rb_intern("addGeometries"), 1, &addGeoms );
/* It doesn't really matter what we return here, as Matz decided assignment
methods always return what was assigned, so... */
return Qnil;
}
Returns a human-readable string containing a representation of the Space suitable for debugging or tracing.
# File lib/ode/space.rb, line 44 def inspect return "<%s 0x%x: geometries=[%s]>" % [ self.class.name, self.respond_to?( :object_id ) ? self.object_id * 2 : self.id * 2, self.geometries.collect {|geom| geom.inspect}.join(", "), ] end
removeGeometries( *geometries ) — Remove the specified geometries (ODE::Geometry objects) from the receiving space if they are there and return the ones that were removed.
/*
* removeGeometries( *geometries )
* --
* Remove the specified <tt>geometries</tt> (ODE::Geometry objects) from the
* receiving space if they are there and return the ones that were removed.
*/
static VALUE
ode_space_remove( self, args )
VALUE self, args;
{
ode_GEOMETRY *ptr = get_space( self );
int i = 0;
VALUE rary = rb_ary_new();
if ( TYPE(args) != T_ARRAY )
rb_bug( "Expected array, got a %s.", rb_class2name(CLASS_OF(args)) );
for ( i = 0; i < RARRAY(args)->len; i++ ) {
ode_GEOMETRY *cptr = ode_get_geom( *(RARRAY(args)->ptr + i) );
if ( dSpaceQuery((dSpaceID)ptr->id, (dGeomID)cptr->id) ) {
rb_ary_push( rary, *(RARRAY(args)->ptr + i) );
dSpaceRemove( (dSpaceID)ptr->id, (dGeomID)cptr->id );
}
}
return rary;
}