物体の固定
ここでは物体を固定する方法について説明します。
実は簡単で、固定したいオブジェクトを衝突検出のみさせるようにすればよいだけです。
つまり、dGeomIDは設定する必要はあるがdBodyIDを設定する必要はないということです。
dBodyIDを設定しなければ物体は移動することができず、その場所に固定されます。
実は簡単で、固定したいオブジェクトを衝突検出のみさせるようにすればよいだけです。
つまり、dGeomIDは設定する必要はあるがdBodyIDを設定する必要はないということです。
dBodyIDを設定しなければ物体は移動することができず、その場所に固定されます。
static dGeomID g_fixed; g_fixed = dCreateBox( space, f_box_sizes[0], f_box_sizes[1], f_box_sizes[2] );
このとき、dGeomSetBodyは設定しません。

サンプルコード
ODE付属のサンプルコードでdemo_buggy.cppを参考にしました。
/***********************************************************
* Hajime no Ippo --- file : hjime.cpp
***********************************************************/
#include <ode/ode.h>
#include <drawstuff/drawstuff.h>
#define MAX_CONTACTS 4
static dWorldID world;
static dSpaceID space;
static dJointGroupID contactgroup;
static dBodyID b_sphere;
static dGeomID g_sphere;
static dGeomID g_fixed;
static dReal radius = 0.5;
static dReal f_box_sizes[3] = { 2.0, 2.0, 1.0 };
#ifdef dDOUBLE
#define dsDrawSphere dsDrawSphereD
#define dsDrawBox dsDrawBoxD
#endif
static void nearCallback( void *data, dGeomID o1, dGeomID o2 )
{
dBodyID b1 = dGeomGetBody( o1 );
dBodyID b2 = dGeomGetBody( o2 );
if ( b1 && b2 && dAreConnectedExcluding( b1, b2, dJointTypeContact ) )
return;
dContact contact[MAX_CONTACTS];
for ( int i=0; i<MAX_CONTACTS; i++ )
{
//contact[i].surface.mode = dContactBounce | dContactSoftERP | dContactSoftCFM;
contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = dInfinity;
contact[i].surface.bounce = 1.0;
//contact[i].surface.soft_erp = 0.2;
//contact[i].surface.soft_cfm = 0.00001;
}
int numc = dCollide( o1, o2, MAX_CONTACTS, &contact[0].geom, sizeof( dContact ) );
if ( numc > 0 )
{
for ( int i=0; i<numc; i++ )
{
dJointID c = dJointCreateContact( world, contactgroup, contact+i );
dJointAttach( c, b1, b2 );
}
}
}
// start simulation - set viewpoint
static void start()
{
static float xyz[3] = { 0.0f, 7.0f, 5.0f };
static float hpr[3] = { -90.f, -15.f, 0.f };
dsSetViewpoint( xyz, hpr );
}
// simulation loop
static void simLoop( int pause )
{
dSpaceCollide( space, 0, &nearCallback );
if (!pause)
{
dWorldStep( world, 0.005 );
}
dJointGroupEmpty( contactgroup );
dsSetColor( 1.0, 1.0, 0.0 );
dsDrawSphere( dBodyGetPosition( b_sphere ), dBodyGetRotation( b_sphere ), radius );
dsSetColor( 0.5, 0.5, 0.5 );
dsDrawBox( dGeomGetPosition( g_fixed ), dGeomGetRotation( g_fixed ), f_box_sizes );
}
int main( int argc, char* argv[] )
{
// setup pointers to drawstuff callback functions
dsFunctions fn;
fn.version = DS_VERSION;
fn.start = &start;
fn.step = &simLoop;
fn.command = 0;
fn.stop = 0;
fn.path_to_textures = "../../drawstuff/textures";
dInitODE();
// creating world
world = dWorldCreate();
space = dHashSpaceCreate( 0 );
contactgroup = dJointGroupCreate( 0 );
dCreatePlane( space, 0, 0, 1, 0 );
dWorldSetGravity( world, 0.0, 0.0, -9.8 );
dWorldSetERP( world, 0.8 );
dWorldSetCFM( world, 0.00001 );
// creating Sphere
b_sphere = dBodyCreate( world );
dReal pos[3] = { 0.0, 0.0, 5.0 };
dBodySetPosition( b_sphere, pos[0], pos[1], pos[2] );
dMass sphere_mass;
dMassSetSphere( &sphere_mass, 1.0, radius );
dBodySetMass( b_sphere, &sphere_mass );
g_sphere = dCreateSphere( space, radius );
dGeomSetBody( g_sphere, b_sphere );
// creating Fixed Box
g_fixed = dCreateBox( space, f_box_sizes[0], f_box_sizes[1], f_box_sizes[2] );
dMatrix3 R;
dRFromAxisAndAngle( R, 0, 1, 0, -0.30 );
dGeomSetRotation( g_fixed, R); // 方向指定
dGeomSetPosition( g_fixed, 0.0, 0.0, 0.5 ); // 位置指定
// starting simulation
dsSimulationLoop( argc, argv, 320, 240, &fn );
dJointGroupDestroy( contactgroup );
dSpaceDestroy( space );
dWorldDestroy( world );
return 0;
}
以上