Class ODE::Geometry
In: ext/body.c  (CVS)
Parent: Object

Methods

Classes and Modules

Class ODE::Geometry::Box
Class ODE::Geometry::CappedCylinder
Class ODE::Geometry::Cylinder
Class ODE::Geometry::Placeable
Class ODE::Geometry::Plane
Class ODE::Geometry::Ray
Class ODE::Geometry::Sphere
Class ODE::Geometry::Transform
Class ODE::Geometry::TransformGroup

Public Class methods

Generalized constructor

[Source]

/*
 * Generalized constructor
 */
static VALUE
ode_geometry_s_alloc( klass )
	 VALUE klass;
{
	debugMsg(( "Wrapping an uninitialized ODE::Geometry pointer." ));
	return Data_Wrap_Struct( klass, ode_geometry_gc_mark, ode_geometry_gc_free, 0 );
}

Base initializer.

[Source]

/* 
 * Base initializer.
 */
static VALUE
ode_geometry_init( argc, argv, self )
	 int	argc;
	 VALUE	*argv, self;
{
	debugMsg(( "ODE::Geometry init." ));
	if ( !check_geom(self) ) {
		ode_GEOMETRY *geom;

		debugMsg(( "Fetching new data object." ));
		DATA_PTR(self) = geom = ode_geometry_alloc();

		geom->object = self;

		debugMsg(( "New ode_GEOMETRY = <%p>", geom ));
	}

	debugMsg(( "Calling super()" ));
	rb_call_super( 0, 0 );
	debugMsg(( "Back from super()" ));

	return self;
}

Public Instance methods

ODE::Geometry#aabb — Return an axis aligned bounding box that surrounds the given geom as a six-element Array. The aabb array has elements [minx, maxx, miny, maxy, minz, maxz]. If the geom is a space, a bounding box that surrounds all contained geoms is returned.

This function may return a pre-computed cached bounding box, if it can determine that the geom has not moved since the last time the bounding box was computed.

[Source]

/*
 * ODE::Geometry#aabb
 * --
 * Return an axis aligned bounding box that surrounds the given geom as a
 * six-element Array. The aabb array has elements [minx, maxx, miny, maxy, minz,
 * maxz]. If the geom is a space, a bounding box that surrounds all contained
 * geoms is returned.
 *
 * This function may return a pre-computed cached bounding box, if it can
 * determine that the geom has not moved since the last time the bounding box
 * was computed.
 */
static VALUE
ode_geometry_aabb( self )
	 VALUE self;
{
	VALUE			aabbArray;
	dReal			aabb[6];
	ode_GEOMETRY	*geometry = get_geom( self );
	int				i;
	
	dGeomGetAABB( geometry->id, aabb );
	
	aabbArray = rb_ary_new2( 6 );
	for ( i = 0; i < 6; i++ )
		rb_ary_store( aabbArray, i, rb_float_new(aabb[i]) );
	
	return aabbArray;
}

ODE::Geometry#body — Returns nil; overridden in ODE::Geometry::Placeable.

[Source]

/*
 * ODE::Geometry#body
 * --
 * Returns <tt>nil</tt>; overridden in ODE::Geometry::Placeable.
 */
static VALUE
ode_geometry_body( self )
	 VALUE self;
{
	return Qnil;
}

ODE::Geometry#body= — Raises an exception; overridden in ODE::Geometry::Placeable.

[Source]

/*
 * ODE::Geometry#body=
 * --
 * Raises an exception; overridden in ODE::Geometry::Placeable.
 */
static VALUE
ode_geometry_body_eq( self )
	 VALUE self;
{
	rb_raise( ode_eOdeGeometryError, "Cannot set a body for a non-placeable geometry." );
}

ODE::Geometry#categoryMask — Get the ‘category’ bitfield for the receiving Geometry. This bitfield is used by spaces to govern which geoms will interact with each other; each bit position in the bitfield represents a different category of object. The actual meaning of these categories (if any) is user defined. The category bitfield indicates which categories a geom is a member of. The bit fields are guaranteed to be at least 32 bits wide. The default category mask for newly created geoms has all bits set.

[Source]

/*
 * ODE::Geometry#categoryMask
 * --
 * Get the 'category' bitfield for the receiving Geometry. This bitfield is
 * used by spaces to govern which geoms will interact with each other; each bit
 * position in the bitfield represents a different category of object. The
 * actual meaning of these categories (if any) is user defined. The category
 * bitfield indicates which categories a geom is a member of. The bit fields are
 * guaranteed to be at least 32 bits wide. The default category mask for newly
 * created geoms has all bits set.
 */
static VALUE
ode_geometry_category_mask( self )
	 VALUE self;
{
	ode_GEOMETRY	*geometry = get_geom( self );
	unsigned long	mask;

	mask = dGeomGetCategoryBits( geometry->id );

	return INT2NUM( mask );
}

ODE::Geometry#categoryMask=( mask ) — Set the ‘category’ bitfield for the receiving Geometry. This bitfield is used by spaces to govern which geoms will interact with each other; each bit position in the bitfield represents a different category of object. The actual meaning of these categories (if any) is user defined. The category bitfield indicates which categories a geom is a member of. The bit fields are guaranteed to be at least 32 bits wide. The default category mask for newly created geoms has all bits set.

[Source]

/*
 * ODE::Geometry#categoryMask=( mask )
 * --
 * Set the 'category' bitfield for the receiving Geometry. This bitfield is
 * used by spaces to govern which geoms will interact with each other; each bit
 * position in the bitfield represents a different category of object. The
 * actual meaning of these categories (if any) is user defined. The category
 * bitfield indicates which categories a geom is a member of. The bit fields are
 * guaranteed to be at least 32 bits wide. The default category mask for newly
 * created geoms has all bits set.
 */
static VALUE
ode_geometry_category_mask_eq( self, newMask )
	 VALUE self, newMask;
{
	ode_GEOMETRY	*geometry = get_geom( self );
	unsigned long	mask;

	mask = NUM2ULONG( newMask );
	CheckPositiveNumber( mask, "mask" );

	dGeomSetCategoryBits( geometry->id, mask );

	return INT2NUM( dGeomGetCategoryBits(geometry->id) );
}

ODE::Geometry#collideMask — Get the ‘collide’ bitfield for the receiving Geometry. This bitfield is used by spaces to govern which geoms will interact with each other; each bit position in the bitfield represents a different category of object. A Geometry will only collide with an object which belongs to a category that it has a collide bit set for. The bit fields are guaranteed to be at least 32 bits wide. The default category mask for newly created geoms has all bits set.

[Source]

/*
 * ODE::Geometry#collideMask
 * --
 * Get the 'collide' bitfield for the receiving Geometry. This bitfield is used
 * by spaces to govern which geoms will interact with each other; each bit
 * position in the bitfield represents a different category of object. A
 * Geometry will only collide with an object which belongs to a category that it
 * has a collide bit set for. The bit fields are guaranteed to be at least 32
 * bits wide. The default category mask for newly created geoms has all bits
 * set.
 */
static VALUE
ode_geometry_collide_mask( self )
	 VALUE self;
{
	ode_GEOMETRY	*geometry = get_geom( self );
	unsigned long	mask;

	mask = dGeomGetCollideBits( geometry->id );

	return INT2NUM( mask );
}

ODE::Geometry#collideMask=( mask ) — Set the ‘collide’ bitfield for the receiving Geometry. This bitfield is used by spaces to govern which geoms will interact with each other; each bit position in the bitfield represents a different category of object. A Geometry will only collide with an object which belongs to a category that is has a collide bit set for. The bit fields are guaranteed to be at least 32 bits wide. The default category mask for newly created geoms has all bits set.

[Source]

/*
 * ODE::Geometry#collideMask=( mask )
 * --
 * Set the 'collide' bitfield for the receiving Geometry. This bitfield is used
 * by spaces to govern which geoms will interact with each other; each bit
 * position in the bitfield represents a different category of object. A
 * Geometry will only collide with an object which belongs to a category that is
 * has a collide bit set for. The bit fields are guaranteed to be at least 32
 * bits wide. The default category mask for newly created geoms has all bits
 * set.
 */
static VALUE
ode_geometry_collide_mask_eq( self, newMask )
	 VALUE self, newMask;
{
	ode_GEOMETRY	*geometry = get_geom( self );
	unsigned long	mask;

	mask = NUM2ULONG( newMask );
	CheckPositiveNumber( mask, "mask" );

	dGeomSetCollideBits( geometry->id, mask );

	return INT2NUM( dGeomGetCollideBits(geometry->id) );
}

ODE::Geometry#collideWith( otherGeometry, maxContacts=5, &contactHandler ) — Generate contact information for the receiving Geometry and otherGeometry in the form of at most maxContacts ODE::Contact objects, yielding each in turn to the given contactHandler. This corresponds to (and is really just a wrapper around) the dCollide() function in the C API.

[Source]

/*
 * ODE::Geometry#collideWith( otherGeometry, maxContacts=5, &contactHandler )
 * --
 * Generate contact information for the receiving Geometry and
 * <tt>otherGeometry</tt> in the form of at most <tt>maxContacts</tt>
 * ODE::Contact objects, yielding each in turn to the given
 * <tt>contactHandler</tt>. This corresponds to (and is really just a wrapper
 * around) the dCollide() function in the C API.
 */
static VALUE
ode_geometry_collide( argc, argv, self )
	 int	argc;
	 VALUE	*argv, self;
{
	ode_GEOMETRY	*geom1, *geom2;
	VALUE			otherGeom, maxContacts, contact;
	dContactGeom	*cgeoms;
	int				flags, contactCount, i;

	rb_scan_args( argc, argv, "11", &otherGeom, &maxContacts );

	CheckKindOf( otherGeom, ode_cOdeGeometry );
	if ( !rb_block_given_p )
		rb_raise( ruby_eLocalJumpError, "no block given" );
	
	/* Fetch or default the contact count */
	if ( RTEST(maxContacts) ) {
		flags = NUM2INT( maxContacts );
		CheckPositiveNonZeroNumber( flags, "maxContacts" );
	}
	else {
		flags = 5;
	}
	
	/* Unwrap the geometry structs */
	geom1 = get_geom( self );
	geom2 = get_geom( otherGeom );
	
	/* Echo some of ODE's own optimizations here to save pointless memory
	   allocation.
	   :TODO: ODE currently doesn't do much more than this, but if it ever does
	   provide some use for colliding an object with itself, this will have to
	   be removed. */
	if ( geom1 == geom2 ) return INT2FIX( 0 );
	if ( geom1->body == geom2->body && RTEST(geom1->body) )
		return INT2FIX( 0 );
	
	/* Allocate contacts and generate contact information. */
	cgeoms = ALLOCA_N( dContactGeom, (flags & 0xffff) );
	contactCount = dCollide( geom1->id, geom2->id, flags, cgeoms, sizeof(dContactGeom) );

	/* Yield to the block for each contact object */
	for ( i = 0; i < contactCount; i++ ) {
		contact = rb_class_new_instance( 0, 0, ode_cOdeContact );

		/* Set the internal contact geometry of the contact object to this
		   contact geom and call the collision callback. */
		ode_contact_set_cgeom( contact, cgeoms + i );
		rb_yield( contact );
	}

	return INT2FIX( contactCount );
}

ODE::Geometry#container — Return the ODE::Space which contains this object, if it is contained, or nil if not.

[Source]

/*
 * ODE::Geometry#container
 * --
 * Return the ODE::Space which contains this object, if it is contained, or
 * <tt>nil</tt> if not.
 */
static VALUE
ode_geometry_container( self )
	 VALUE self;
{
	ode_GEOMETRY *ptr = get_geom( self );
	return ptr->container;
}

ODE::Geometry#disable — Diaable the receiving Geometry; Disabled geoms are completely ignored by their containing space’s collision methods, although they can still be members of a one.

[Source]

/*
 * ODE::Geometry#disable
 * --
 * Diaable the receiving Geometry; Disabled geoms are completely ignored by
 * their containing space's collision methods, although they can still be
 * members of a one.
 */
static VALUE
ode_geometry_disable( self )
	 VALUE self;
{
#ifdef HAVE_DGEOMENABLE
	ode_GEOMETRY	*geometry = get_geom(self);
	dGeomDisable( geometry->id );
	return Qfalse;
#else
	rb_notimplement();
#endif /* HAVE_DGEOMENABLE */
}

ODE::Geometry#enable — Enable the receiving Geometry; Disabled geoms are completely ignored by their containing space’s collision methods, although they can still be members of a one.

[Source]

/*
 * ODE::Geometry#enable
 * --
 * Enable the receiving Geometry; Disabled geoms are completely ignored by their
 * containing space's collision methods, although they can still be members of a
 * one.
 */
static VALUE
ode_geometry_enable( self )
	 VALUE self;
{
#ifdef HAVE_DGEOMENABLE
	ode_GEOMETRY	*geometry = get_geom(self);
	dGeomEnable( geometry->id );
	return Qtrue;
#else
	rb_notimplement();
#endif /* HAVE_DGEOMENABLE */
}

ODE::Geometry#enabled? — Returns true if the receiving Geometry is enabled.

[Source]

/*
 * ODE::Geometry#enabled?
 * --
 * Returns true if the receiving Geometry is enabled.
 */
static VALUE
ode_geometry_enabled_p( self )
	 VALUE self;
{
#ifdef HAVE_DGEOMENABLE
	ode_GEOMETRY	*geometry = get_geom(self);
	if ( dGeomIsEnabled(geometry->id) )
		return Qtrue;
	else
		return Qfalse;
#else
	rb_notimplement();
#endif /* HAVE_DGEOMENABLE */
}

ODE::Geometry#intersectWith( otherGeom, *data, &nearCallback ) — Call the nearCallback for potentially intersecting pairs that contain one geom from the receiving geometry, and one from the otherGeom. Any arguments passed in the data Array will be passed to the callback as arguments after the two potentially-colliding geometry objects.

The exact behavior depends on the types of the receiver and the otherGeom:

  • If one of the geoms is a non-space geom and the other is a space, the callback is called with all potential intersections between the geom and the objects in the space.
  • If both the receiver and otherGeom are spaces, then this calls the callback for all potentially intersecting pairs that contain one geom from the receiver and one geom from otherGeom. The algorithm that is used depends on what kinds of spaces are being collided. If no optimized algorithm can be selected then this function will resort to one of the following two strategies:
    1. All the geoms in the receiver are tested one-by-one against otherGeom.
    2. All the geoms in otherGeom are tested one-by-one against the receiver.

The strategy used may depends on a number of rules, but in general the space with less objects has its geoms examined one-by-one.

  • If both geoms are the same space, this is equivalent to calling eachAdjacentPair() on that space.
  • If both the receiver and otherGeom are non-space geoms, this simply calls the callback once with them.

This method is the equivalent of the dSpaceCollide2() function from the C API.

[Source]

/*
 * ODE::Geometry#intersectWith( otherGeom, *data, &nearCallback )
 * --
 * Call the <tt>nearCallback</tt> for potentially intersecting pairs that
 * contain one geom from the receiving geometry, and one from the
 * <tt>otherGeom</tt>. Any arguments passed in the <tt>data</tt> Array will be
 * passed to the callback as arguments after the two potentially-colliding
 * geometry objects.
 *
 * The exact behavior depends on the types of the receiver and the
 * <tt>otherGeom</tt>:
 *
 * * If one of the geoms is a non-space geom and the other is a space, the
 *   callback is called with all potential intersections between the geom and
 *   the objects in the space.
 *
 * * If both the receiver and <tt>otherGeom</tt> are spaces, then this calls the
 *   callback for all potentially intersecting pairs that contain one geom from
 *   the receiver and one geom from <tt>otherGeom</tt>. The algorithm that is
 *   used depends on what kinds of spaces are being collided. If no optimized
 *   algorithm can be selected then this function will resort to one of the
 *   following two strategies:
 *
 *   1. All the geoms in the receiver are tested one-by-one against
 *      <tt>otherGeom</tt>.
 *   2. All the geoms in <tt>otherGeom</tt> are tested one-by-one against the
 *      receiver.
 *
 * The strategy used may depends on a number of rules, but in general the space
 * with less objects has its geoms examined one-by-one.
 *
 * * If both geoms are the same space, this is equivalent to calling
 *   #eachAdjacentPair() on that space.
 *
 * * If both the receiver and <tt>otherGeom</tt> are non-space geoms, this
 *   simply calls the callback once with them.
 *
 * This method is the equivalent of the dSpaceCollide2() function from the C
 * API.
 */
static VALUE
ode_geometry_isect( argc, argv, self )
	 int	argc;
	 VALUE	*argv, self;
{
	ode_GEOMETRY	*geometry, *geometry2;
	ode_CALLBACK	*callback;
	VALUE			otherGeom, data, block;

	rb_scan_args( argc, argv, "1*&", &otherGeom, &data, &block );

	geometry  = get_geom( self );
	geometry2 = get_geom( otherGeom );

	ode_check_arity( block, 3 );

	callback = ALLOCA_N( ode_CALLBACK, 1 );
	callback->callback = block;
	callback->args = data;

	dSpaceCollide2( geometry->id, geometry2->id, callback,
					(dNearCallback *)(ode_near_callback) );

	return Qtrue;
}

ODE::Geometry#isSpace? — Returns true if the receiving Geometry is an ODE::Space or one of its derivatives. This should be functionally (but not implementationally) the same as kind_of?( ODE::Space ), but is provided for completeness. Alias: is_space?.

[Source]

/*
 * ODE::Geometry#isSpace?
 * --
 * Returns <tt>true</tt> if the receiving Geometry is an ODE::Space or one of
 * its derivatives. This should be functionally (but not implementationally) the
 * same as #kind_of?( ODE::Space ), but is provided for completeness. Alias:
 * <tt>is_space?</tt>.
 */
static VALUE
ode_geometry_space_p( self )
	 VALUE self;
{
	ode_GEOMETRY	*geometry = get_geom(self);

	if ( dGeomIsSpace(geometry->id) )
		return Qtrue;
	else
		return Qfalse;
}

ODE::Geometry#surface — Get the geometry’s surface (an ODE::Surface object).

[Source]

/*
 * ODE::Geometry#surface
 * --
 * Get the geometry's surface (an ODE::Surface object).
 */
static VALUE
ode_geometry_surface( self )
	 VALUE self;
{
	ode_GEOMETRY	*ptr = get_geom( self );
	return ptr->surface;
}

ODE::Geometry#surface=( surface ) — Set the geometry’s surface (an ODE::Surface object) to the one specified.

[Source]

/*
 * ODE::Geometry#surface=( surface )
 * --
 * Set the geometry's surface (an ODE::Surface object) to the one specified.
 */
static VALUE
ode_geometry_surface_eq( self, surface )
	 VALUE self, surface;
{
	ode_GEOMETRY	*ptr = get_geom( self );
	
	CheckKindOf( surface, ode_cOdeSurface );
	ptr->surface = surface;

	return surface;
}

[Validate]