ode.h

Path: ext/ode.h  (CVS)
Last Update: Wed Jul 27 22:48:36 EDT 2005

/*

 *              ode.h - ODE Ruby Binding - Header file
 *              $Id: ode.h 96 2005-07-28 02:48:31Z ged $
 *              Time-stamp: <18-Feb-2003 09:56:41 deveiant>
 *
 *              Authors:
 *                * Michael Granger <ged@FaerieMUD.org>
 *
 *              Copyright (c) 2001, 2002, 2003 The FaerieMUD Consortium.
 *
 *              This work is licensed under the Creative Commons Attribution License. To
 *              view a copy of this license, visit
 *              http://creativecommons.org/licenses/by/1.0 or send a letter to Creative
 *              Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
 *
 */

ifndef _R_ODE_H define _R_ODE_H 1

include <stdlib.h> include <stdio.h>

include <ruby.h> include <intern.h> /* For rb_dbl2big() */ include <version.h> /* Check version for alloc framework */

include <ode/ode.h>

/* Debugging functions/macros */ ifdef HAVE_STDARG_PROTOTYPES include <stdarg.h> define va_init_list(a,b) va_start(a,b) extern void ode_debug(const char *fmt, …); else include <varargs.h> define va_init_list(a,b) va_start(a) extern void ode_debug(fmt, va_alist); endif

/* ——————————————————-

 * Globals
 * ------------------------------------------------------- */

/*

 * Hack to make up for various Ruby objects being static for some reason.
 */

extern VALUE ruby_cMethod; extern VALUE ruby_eLocalJumpError;

/*

 * Modules
 */

extern VALUE ode_mOde;

/*

 * Exception classes
 */

extern VALUE ode_eOdeObsoleteJointError; extern VALUE ode_eOdeGeometryError;

/*

 * Utility/data classes
 */

extern VALUE ode_cOdeVector; extern VALUE ode_cOdeQuaternion; extern VALUE ode_cOdePosition; extern VALUE ode_cOdeLinearVelocity; extern VALUE ode_cOdeAngularVelocity; extern VALUE ode_cOdeForce; extern VALUE ode_cOdeTorque;

/*

 * Primary Classes
 */

extern VALUE ode_cOdeWorld; extern VALUE ode_cOdeBody; extern VALUE ode_cOdeJointGroup; extern VALUE ode_cOdeJoint; extern VALUE ode_cOdeBallJoint; extern VALUE ode_cOdeFixedJoint; extern VALUE ode_cOdeUniversalJoint; extern VALUE ode_cOdeContactJoint;

extern VALUE ode_cOdeParamJoint; extern VALUE ode_cOdeHingeJoint; extern VALUE ode_cOdeHinge2Joint; extern VALUE ode_cOdeSliderJoint; extern VALUE ode_cOdeAMotorJoint;

extern VALUE ode_cOdeMass; extern VALUE ode_cOdeMassBox; extern VALUE ode_cOdeMassSphere; extern VALUE ode_cOdeMassCapCyl;

extern VALUE ode_cOdeContact;

extern VALUE ode_cOdeGeometry; extern VALUE ode_cOdePlaceable; extern VALUE ode_cOdeGeometrySphere; extern VALUE ode_cOdeGeometryBox; extern VALUE ode_cOdeGeometryPlane; extern VALUE ode_cOdeGeometryCapCyl; extern VALUE ode_cOdeGeometryCylinder; /* Optional ODE extension */ extern VALUE ode_cOdeGeometryRay; extern VALUE ode_cOdeGeometryTransform; extern VALUE ode_cOdeGeometryTransformGroup; /* Optional ODE extension */ extern VALUE ode_cOdeSpace; extern VALUE ode_cOdeHashSpace;

extern VALUE ode_cOdeSurface; extern VALUE ode_cOdeContact;

/* ——————————————————-

 *      Structures
 * ------------------------------------------------------- */

/* ODE::Body struct */ typedef struct {

        dBodyID                        id;
        VALUE                  object, world, mass;

} ode_BODY;

/* ODE::Mass object */ typedef struct {

        dMass                  *massptr;
        VALUE                  body;

} ode_MASS;

/* ODE::Joint structs */ typedef struct {

        dJointID               id;
        dJointFeedback *feedback;
        VALUE                  object, jointGroup, world, body1, body2, fbhash, contact, obsolete;

} ode_JOINT;

/* JointGroup linked list entry */ typedef struct jointListNode {

        struct jointListNode *next;
        VALUE          joint;

} ode_JOINTLIST;

/* ODE::JointGroup struct */ typedef struct {

        dJointGroupID  id;
        ode_JOINTLIST  *jointList;

} ode_JOINTGROUP;

/* ODE::Geometry struct (for ODE::Spaces, too) */ typedef struct {

        dGeomID                        id;
        VALUE                  object, body, surface, container;

} ode_GEOMETRY;

/* ODE::Contact struct */ typedef struct {

        dContact               *contact;
        VALUE                  object, surface;

} ode_CONTACT;

/* Callback data for collision system */ typedef struct {

        VALUE                  callback;
        VALUE                  args;

} ode_CALLBACK;

/* ——————————————————-

 *      Macros
 * ------------------------------------------------------- */

/* Convert x,y to index of a 4xn array */ define _index(i,j) ((i)*4+(j))

/* Debugging macro */ if DEBUG # define debugMsg(f) ode_debug f else /* ! DEBUG */ # define debugMsg(f) endif /* DEBUG */

/* Macro for unwrapping World structs */ define GetWorld( r, s ) {\

        (s) = ode_get_world( r ); \

}

/* Macro for unwrapping Body structs */ define GetBody( r, s ) {\

        (s) = ode_get_body( r ); \

}

/* Macro for unwrapping Mass structs */ define GetMass( r, s ) {\

        CheckKindOf( r, ode_cOdeMass );\
        (s) = DATA_PTR(r);\
        if ( (s) == NULL ) rb_fatal( "Null mass pointer." );\

}

/* Macro for unwrapping Joint structs */ define GetJoint( r, s ) {\

        CheckKindOf( r, ode_cOdeJoint );\
    (s) = DATA_PTR(r);\
        if ( (s) == NULL ) rb_fatal( "Null joint pointer." );\

}

/* Macro for unwrapping dJointGroupID structs */ define GetJointGroup( r, s ) {\

        CheckKindOf( r, ode_cOdeJointGroup );\
        (s) = DATA_PTR(r);\
        if ( (s) == NULL ) rb_fatal( "Null jointGroup pointer." );\

}

/* Macro for unwrapping dContact structs */ define GetContact( r, s ) {\

        (r) = ode_get_contact( s ); \

}

/* Macro for unwrapping dSurfaceParameters structs */ define GetSurface( r, s ) {\

        (r) = ode_get_surface( s ); \

}

/* Macro for unwrapping ode_GEOMETRY structs */ define GetGeometry( r, s ) {\

        (r) = ode_get_geom( s ); \

}

define IsSpace( obj ) rb_obj_is_kind_of( (obj), ode_cOdeSpace ) define IsWorld( obj ) rb_obj_is_kind_of( (obj), ode_cOdeWorld ) define IsBody( obj ) rb_obj_is_kind_of( (obj), ode_cOdeBody ) define IsJoint( obj ) rb_obj_is_kind_of( (obj), ode_cOdeJoint ) define IsJointGroup( obj ) rb_obj_is_kind_of( (obj), ode_cOdeJointGroup ) define IsSurface( obj ) rb_obj_is_kind_of( (obj), ode_cOdeSurface ) define IsMass( obj ) rb_obj_is_kind_of( (obj), ode_cOdeMass )

/* Test that obj is .kind_of?( klass ) and raise a TypeError if not. */ define CheckKindOf( obj, klass ) {\

        if ( ! rb_obj_is_kind_of(obj, klass) ) \
                 rb_raise( rb_eTypeError, \
                                   "no implicit conversion to %s from %s", \
                                   rb_class2name(klass), \
                                   rb_class2name(CLASS_OF( obj )) ); \

}

/* Test that the specified var contains a number which is greater than or equal

   to 0. If the test fails, raise a RangeError with a message built from the
   given name. */

define CheckPositiveNumber( var, name ) {\

        if ( (var) < 0 ) \
                rb_raise( rb_eRangeError, \
                                  "Illegal value for parameter '" name \
                                  "' (%0.1f): must be a non-negative number.", \
                                  (var) ); \

}

/* Test that the specified var contains a number which is greater than 0. If the

   test fails, raise a RangeError with a message built from the given name. */

define CheckPositiveNonZeroNumber( var, name ) {\

        if ( (var) <= 0 ) \
                rb_raise( rb_eRangeError, \
                                  "Illegal value for parameter '" name \
                                  "' (%0.1f): must be a positive non-zero number.", \
                                  (var) ); \

}

/* Test that the specified var contains a number which is greater than or equal

   to min, but less than or equal to max, inclusive. If the test fails, raise a
   RangeError with a message built from the given name. */

define CheckNumberBetween( var, name, min, max ) {\

        if ( (var) < (min) || (var) > (max) ) \
                rb_raise( rb_eRangeError, \
                                  "Illegal value for parameter '" name \
                                  "' (%0.1f): must be between %0.5f and %0.5f.", \
                                  (var), (min), (max) ); \

}

/* Make a copy of a dReal array */ define CopyDRealArray( original, copy, depth ) {\

        memcpy( (copy), (original), sizeof(dReal)*(depth) );\

}

/* Turn a dVector3 into an ODE::Vector */ define Vec3ToOdeVector( vec, odevec ) {\

  do {\
          VALUE                axes[3];\
          int          i;\
          for ( i = 0; i <= 2; i++ )\
                  axes[i] = rb_float_new( *((vec) + i) );\
          (odevec) = rb_class_new_instance( 3, axes, ode_cOdeVector );\
  } while (0);\

}

/* Update a current ODE::Vector with the values from a dVector3 */ define SetOdeVectorFromVec3( vec, odevec ) {\

  rb_ary_store( (odevec), 0, rb_float_new(*(vec)) );\
  rb_ary_store( (odevec), 1, rb_float_new(*(vec)+1) );\
  rb_ary_store( (odevec), 2, rb_float_new(*(vec)+2) );\

}

define SetVec3FromArray( vec, ary ) {\

        *(vec)   = (dReal)NUM2DBL( *(RARRAY(ary)->ptr  ) ); \
        *(vec+1) = (dReal)NUM2DBL( *(RARRAY(ary)->ptr+1) ); \
        *(vec+2) = (dReal)NUM2DBL( *(RARRAY(ary)->ptr+2) ); \

}

/* Turn a dVector3 into an ODE::Force */ define Vec3ToOdeForce( vec, odeforce ) {\

  do {\
          VALUE                axes[3];\
          int          i;\
          for ( i = 0; i <= 2; i++ )\
                  axes[i] = rb_float_new( *((vec) + i) );\
          (odeforce) = rb_class_new_instance( 3, axes, ode_cOdeForce );\
  } while (0);\

}

/* Turn a dVector3 into an ODE::Torque */ define Vec3ToOdeTorque( vec, odetorque ) {\

  do {\
          VALUE                axes[3];\
          int          i;\
          for ( i = 0; i <= 2; i++ )\
                  axes[i] = rb_float_new( *((vec) + i) );\
          (odetorque) = rb_class_new_instance( 3, axes, ode_cOdeTorque );\
  } while (0);\

}

/* Turn a dVector3 into an ODE::Position */ define Vec3ToOdePosition( vec, oedipus ) {\

  do {\
          VALUE                axes[3];\
          int          i;\
          for ( i = 0; i <= 2; i++ )\
                  axes[i] = rb_float_new( *((vec) + i) );\
          (oedipus) = rb_class_new_instance( 3, axes, ode_cOdePosition );\
  } while (0);\

}

/* ——————————————————-

 * Initializer functions
 * ------------------------------------------------------- */

extern void ode_init_world _(( void )); extern void ode_init_body _(( void )); extern void ode_init_rotation _(( void )); extern void ode_init_mass _(( void )); extern void ode_init_joints _(( void )); extern void ode_init_jointGroup _(( void )); extern void ode_init_space _(( void )); extern void ode_init_contact _(( void )); extern void ode_init_surface _(( void )); extern void ode_init_geometry _(( void ));

/* ——————————————————-

 * Global method function declarations
 * ------------------------------------------------------- */

/* Generic utility functions */ extern VALUE ode_matrix3_to_rArray _(( dMatrix3 )); extern VALUE ode_vector3_to_rArray _(( dVector3 )); extern VALUE ode_obj_to_ary3 _(( VALUE, const char * )); extern VALUE ode_obj_to_ary4 _(( VALUE, const char * )); extern void ode_quaternion_to_dMatrix3 _(( VALUE, dMatrix3 )); extern void ode_near_callback _(( ode_CALLBACK *, dGeomID, dGeomID )); extern void ode_check_arity _(( VALUE, int ));

/* ODE::Mass class */ extern void ode_mass_set_body _(( VALUE, VALUE ));

/* ODE::JointGroup class */ extern void ode_jointGroup_register_joint _(( VALUE, VALUE ));

/* ODE::Contact class */ extern void ode_contact_set_cgeom _(( VALUE, dContactGeom * ));

/* Fetchers */ extern ode_GEOMETRY *ode_get_geom _(( VALUE )); extern ode_GEOMETRY *ode_get_space _(( VALUE )); extern ode_BODY *ode_get_body _(( VALUE )); extern dWorldID ode_get_world _(( VALUE )); extern dSurfaceParameters *ode_get_surface _(( VALUE )); extern ode_CONTACT *ode_get_contact _(( VALUE )); extern ode_JOINT *ode_get_joint _(( VALUE )); extern ode_JOINTGROUP *ode_get_jointGroup _(( VALUE )); extern ode_MASS *ode_get_mass _(( VALUE ));

endif /* _R_ODE_H */

[Validate]