@ -1,134 +1,127 @@
# include "physics.h"
# include "../common/log.h"
# include <ode/ode.h>
# include <assert.h>
static struct
{
dWorldID world ;
dSpaceID space ;
dJointGroupID contact_group ;
double step_size ;
}
Physics ;
static void physics_near_callback ( void * data , dGeomID body1 , dGeomID body2 ) ;
void physics_init ( void )
{
if ( dInitODE2 ( 0 ) = = 0 )
{
log_error ( " physics:init " , " Failed to initialize ode " ) ;
return ;
}
dAllocateODEDataForThread ( dAllocateMaskAll ) ;
Physics . world = dWorldCreate ( ) ;
if ( ! Physics . world )
{
log_error ( " physics:init " , " Physics world created! " ) ;
}
else
{
log_message ( " Physics world created " ) ;
Physics . space = dHashSpaceCreate ( 0 ) ;
Physics . contact_group = dJointGroupCreate ( 0 ) ;
Physics . step_size = 0.016 ;
dWorldSetCFM ( Physics . world , 1e-5 ) ;
dWorldSetAutoDisableFlag ( Physics . world , 1 ) ;
dWorldSetLinearDamping ( Physics . world , 0.00001 ) ;
dWorldSetAngularDamping ( Physics . world , 0.005 ) ;
dWorldSetMaxAngularSpeed ( Physics . world , 200 ) ;
dWorldSetContactMaxCorrectingVel ( Physics . world , 0.1 ) ;
dWorldSetContactSurfaceLayer ( Physics . world , 0.001 ) ;
}
}
void physics_cleanup ( void )
{
dJointGroupDestroy ( Physics . contact_group ) ;
dSpaceDestroy ( Physics . space ) ;
if ( Physics . world )
{
dWorldDestroy ( Physics . world ) ;
}
dCleanupODEAllDataForThread ( ) ;
dCloseODE ( ) ;
}
void physics_step ( float delta_time )
{
//if(delta_time <= 0.f) delta_time = Physics.step_size;
//dSpaceCollide(Physics.space, NULL, physics_near_callback);
//dWorldQuickStep(Physics.world, delta_time);
////dWorldStep(Physics.world, Physics.step_size);
//dJointGroupEmpty(Physics.contact_group);
int steps = ( int ) ceilf ( delta_time / Physics . step_size ) ;
//log_message("Num steps : %d", steps);
for ( int i = 0 ; i < steps ; i + + )
{
dSpaceCollide ( Physics . space , NULL , physics_near_callback ) ;
dWorldQuickStep ( Physics . world , Physics . step_size ) ;
//dWorldStep(Physics.world, Physics.step_size);
dJointGroupEmpty ( Physics . contact_group ) ;
}
}
void physics_gravity_set ( float x , float y , float z )
{
dWorldSetGravity ( Physics . world , x , y , z ) ;
}
void physics_gravity_get ( float * x , float * y , float * z )
{
assert ( x & & y & & z ) ;
dVector3 gravity ;
dWorldGetGravity ( Physics . world , gravity ) ;
* x = gravity [ 0 ] ;
* y = gravity [ 1 ] ;
* z = gravity [ 2 ] ;
}
void physics_body_position_get ( Rigidbody body , float * x , float * y , float * z )
{
assert ( x & & y & & z ) ;
const dReal * position = dBodyGetPosition ( body ) ;
* x = position [ 0 ] ;
* y = position [ 1 ] ;
* z = position [ 2 ] ;
}
void physics_body_position_set ( Rigidbody body , float x , float y , float z )
{
dBodySetPosition ( body , x , y , z ) ;
}
void physics_body_rotation_get ( Rigidbody body , float * x , float * y , float * z , float * w )
{
assert ( x & & y & & z & & w ) ;
const dReal * rotation = dBodyGetQuaternion ( body ) ;
* x = rotation [ 1 ] ;
* y = rotation [ 2 ] ;
* z = rotation [ 3 ] ;
* w = rotation [ 0 ] ;
}
void physics_body_rotation_set ( Rigidbody body , float x , float y , float z , float w )
{
dReal rotation [ 4 ] = { 0 } ;
rotation [ 1 ] = x ;
rotation [ 2 ] = y ;
rotation [ 3 ] = z ;
rotation [ 0 ] = w ;
dBodySetQuaternion ( body , & rotation [ 0 ] ) ;
}
void physics_near_callback ( void * data , dGeomID o1 , dGeomID o2 )
{
# include "physics.h"
# include "../common/log.h"
# include <ode/ode.h>
# include <assert.h>
static struct
{
dWorldID world ;
dSpaceID space ;
dJointGroupID contact_group ;
double step_size ;
RigidbodyColCB on_collision ;
RigidbodyMoveCB on_move ;
}
Physics ;
static void physics_near_callback ( void * data , dGeomID body1 , dGeomID body2 ) ;
void physics_init ( void )
{
if ( dInitODE2 ( 0 ) = = 0 )
{
log_error ( " physics:init " , " Failed to initialize ode " ) ;
return ;
}
dAllocateODEDataForThread ( dAllocateMaskAll ) ;
Physics . world = dWorldCreate ( ) ;
if ( ! Physics . world )
{
log_error ( " physics:init " , " Physics world created! " ) ;
}
else
{
log_message ( " Physics world created " ) ;
Physics . space = dHashSpaceCreate ( 0 ) ;
Physics . contact_group = dJointGroupCreate ( 0 ) ;
Physics . step_size = 0.016 ;
dWorldSetCFM ( Physics . world , 1e-5 ) ;
dWorldSetAutoDisableFlag ( Physics . world , 1 ) ;
dWorldSetLinearDamping ( Physics . world , 0.00001 ) ;
dWorldSetAngularDamping ( Physics . world , 0.005 ) ;
dWorldSetMaxAngularSpeed ( Physics . world , 200 ) ;
dWorldSetContactMaxCorrectingVel ( Physics . world , 0.1 ) ;
dWorldSetContactSurfaceLayer ( Physics . world , 0.001 ) ;
}
}
void physics_cleanup ( void )
{
dJointGroupDestroy ( Physics . contact_group ) ;
dSpaceDestroy ( Physics . space ) ;
if ( Physics . world )
{
dWorldDestroy ( Physics . world ) ;
}
dCleanupODEAllDataForThread ( ) ;
dCloseODE ( ) ;
}
void physics_step ( float delta_time )
{
int steps = ( int ) ceilf ( delta_time / Physics . step_size ) ;
for ( int i = 0 ; i < steps ; i + + )
{
dSpaceCollide ( Physics . space , NULL , physics_near_callback ) ;
dWorldQuickStep ( Physics . world , Physics . step_size ) ;
dJointGroupEmpty ( Physics . contact_group ) ;
}
}
void physics_gravity_set ( float x , float y , float z )
{
dWorldSetGravity ( Physics . world , x , y , z ) ;
}
void physics_gravity_get ( float * x , float * y , float * z )
{
assert ( x & & y & & z ) ;
dVector3 gravity ;
dWorldGetGravity ( Physics . world , gravity ) ;
* x = gravity [ 0 ] ;
* y = gravity [ 1 ] ;
* z = gravity [ 2 ] ;
}
void physics_body_position_get ( Rigidbody body , float * x , float * y , float * z )
{
assert ( x & & y & & z ) ;
const dReal * position = dBodyGetPosition ( body ) ;
* x = position [ 0 ] ;
* y = position [ 1 ] ;
* z = position [ 2 ] ;
}
void physics_body_position_set ( Rigidbody body , float x , float y , float z )
{
dBodySetPosition ( body , x , y , z ) ;
}
void physics_body_rotation_get ( Rigidbody body , float * x , float * y , float * z , float * w )
{
assert ( x & & y & & z & & w ) ;
const dReal * rotation = dBodyGetQuaternion ( body ) ;
* x = rotation [ 1 ] ;
* y = rotation [ 2 ] ;
* z = rotation [ 3 ] ;
* w = rotation [ 0 ] ;
}
void physics_body_rotation_set ( Rigidbody body , float x , float y , float z , float w )
{
dReal rotation [ 4 ] = { 0 } ;
rotation [ 1 ] = x ;
rotation [ 2 ] = y ;
rotation [ 3 ] = z ;
rotation [ 0 ] = w ;
dBodySetQuaternion ( body , & rotation [ 0 ] ) ;
}
void physics_near_callback ( void * data , dGeomID o1 , dGeomID o2 )
{
assert ( o1 ) ;
assert ( o2 ) ;
@ -171,7 +164,7 @@ void physics_near_callback(void* data, dGeomID o1, dGeomID o2)
int n = dCollide ( o1 , o2 , MAX_CONTACTS , & ( contact [ 0 ] . geom ) , sizeof ( dContact ) ) ;
if ( n > 0 )
{
log_message ( " Collision! " ) ;
Physics . on_collision ( b1 , b2 ) ;
for ( int i = 0 ; i < n ; i + + )
{
//contact[i].surface.slip1 = 0.7;
@ -186,47 +179,64 @@ void physics_near_callback(void* data, dGeomID o1, dGeomID o2)
/*dGeomGetBody(contact[i].geom.g1),
dGeomGetBody ( contact [ i ] . geom . g2 ) ) ; */
}
}
}
Rigidbody physics_plane_create ( float a , float b , float c , float d )
{
dGeomID plane = dCreatePlane ( Physics . space , a , b , c , d ) ;
/*dBodyID body = dBodyCreate(Physics.world);
dGeomSetBody ( plane , body ) ; */
return plane ;
}
Rigidbody physics_box_create ( float length , float width , float height )
{
dGeomID box = dCreateBox ( Physics . space , length , height , width ) ;
dBodyID body = dBodyCreate ( Physics . world ) ;
dGeomSetBody ( box , body ) ;
dBodySetAngularVel ( body , 0 , 0 , 0 ) ;
dBodySetLinearVel ( body , 0 , 0 , 0 ) ;
dBodySetTorque ( body , 0 , 0 , 0 ) ;
return body ;
}
void physics_body_set_moved_callback ( Rigidbody body , RigidbodyMoveCB callback )
{
dBodySetMovedCallback ( body , callback ) ;
}
}
Rigidbody physics_plane_create ( float a , float b , float c , float d )
{
dGeomID plane = dCreatePlane ( Physics . space , a , b , c , d ) ;
/*dBodyID body = dBodyCreate(Physics.world);
dGeomSetBody ( plane , body ) ; */
return plane ;
}
Rigidbody physics_box_create ( float length , float width , float height )
{
dGeomID box = dCreateBox ( Physics . space , length , height , width ) ;
dBodyID body = dBodyCreate ( Physics . world ) ;
dGeomSetBody ( box , body ) ;
dBodySetAngularVel ( body , 0 , 0 , 0 ) ;
dBodySetLinearVel ( body , 0 , 0 , 0 ) ;
dBodySetTorque ( body , 0 , 0 , 0 ) ;
dBodySetMovedCallback ( body , Physics . on_move ) ;
return body ;
}
void physics_body_set_moved_callback ( RigidbodyMoveCB callback )
{
Physics . on_move = callback ;
}
float physics_body_mass_get ( Rigidbody body )
void physics_body_set_collision_callback ( RigidbodyColCB callback )
{
return 0.0f ;
Physics . on_collision = callback ;
}
float physics_body_mass_get ( Rigidbody body )
{
return 0.0f ;
}
void physics_body_mass_set ( Rigidbody body , float mass )
{
/*dMass dmass;
dMassAdjust ( & dmass , mass ) ;
dBodySetMass ( body , & dmass ) ; */
}
void physics_body_mass_set ( Rigidbody body , float mass )
void physics_body_data _set ( Rigidbody body , void * data )
{
/*dMass dmass;
dMassAdjust ( & dmass , mass ) ;
dBodySetMass ( body , & dmass ) ; */
dBodySetData ( body , data ) ;
}
void physics_body_kinematic_set ( Rigidbody body )
void * physics_body_data_g et( Rigidbody body )
{
dBodySetKinematic ( body ) ;
}
return dBodyGetData ( body ) ;
}
void physics_body_kinematic_set ( Rigidbody body )
{
dBodySetKinematic ( body ) ;
}