アットウィキロゴ

test

demo_boxstack (ODE 0.11.1)

動画をYouTubeで見る
 
#include#include#include"texturepath.h"#ifdef_MSC_VER#pragmawarning(disable:4244 4305 )// 型変換に伴う精度喪失の警告を抑制する (VC++)#endif#include"icosahedron_geom.h"
// 凸形状オブジェクト// 立方体の面dReal planes[] = {    1.0f,  0.0f,  0.0f, 0.25f,    0.0f,  1.0f,  0.0f, 0.25f,    0.0f,  0.0f,  1.0f, 0.25f,   -1.0f,  0.0f,  0.0f, 0.25f,    0.0f, -1.0f,  0.0f, 0.25f,    0.0f,  0.0f, -1.0f, 0.25f, };constunsignedintplanecount = 6;// 立方体の点dReal points[] = {    0.25f, 0.25f, 0.25f,  // 点0 -0.25f, 0.25f, 0.25f,  // 点1   0.25f, -0.25f, 0.25f, // 点2 -0.25f, -0.25f, 0.25f, // 点3   0.25f, 0.25f, -0.25f, // 点4 -0.25f, 0.25f, -0.25f, // 点5   0.25f, -0.25f, -0.25f,// 点6-0.25f, -0.25f, -0.25f,// 点7};constunsignedintpointcount = 8;// 立方体のポリゴン (6つの四角形)unsignedintpolygons[] = {   4, 0, 2, 6, 4,// +X4, 1, 0, 4, 5,// +Y4, 0, 1, 3, 2,// +Z4, 3, 1, 5, 7,// -X4, 2, 3, 7, 6,// -Y4, 5, 4, 6, 7,// -Z};
// 適切な描画関数を選択する#ifdefdDOUBLE #definedsDrawBox       dsDrawBoxD #definedsDrawSphere    dsDrawSphereD #definedsDrawCylinder  dsDrawCylinderD #definedsDrawCapsule   dsDrawCapsuleD #definedsDrawConvex    dsDrawConvexD#endif
// 定数#defineNUM             100  // オブジェクトの最大数#defineDENSITY         ( 5.0 )// すべてのオブジェクトの密度#defineGPB             3    // 1つのボディの最大のジオメトリ数#defineMAX_CONTACTS    8    // 1つのボディの最大の接点数#defineMAX_FEEDBACKNUM 20   // フィードバックの最大数#defineGRAVITY         REAL( 0.5 )#defineUSE_GEOM_OFFSET 1    // 混成オブジェクトの重心をオフセットさせるか?
// 動力学と衝突検出のオブジェクトstructMyObject {   dBodyID body;         // ボディdGeomID geom[ GPB ];  // ボディのジオメトリ};staticintnum = 0;     // シミュレーション内のオブジェクトの数staticintnextobj = 0; // num == NUMとなったときに再利用される次のオブジェクトstaticdWorldID world;staticdSpaceID space;staticMyObject obj[ NUM ];staticdJointGroupID contactgroup;staticintselected = -1;    // 選択されているオブジェクトstaticintshow_aabb = 0;    // ジオメトリのAABBを表示するか?staticintshow_contacts = 0;// 接触点を表示するか?staticintrandom_pos = 1;   // ランダムな位置からオブジェクトを落下させるか?staticintwrite_world = 0;  // 現在の状態をファイルに書き出すか?staticintshow_body = 0;    // ボディを表示するか?structMyFeedback {   dJointFeedback fb;// ジョイントのフィードバックboolfirst;       // 選択されているオブジェクトか?};staticMyFeedback feedbacks[ MAX_FEEDBACKNUM ];staticintdoFeedback = 0;   // フィードバックを表示するか?staticintfbnum = 0;        // フィードバックの数

nearCallback

// スペースの2つのオブジェクトが衝突する可能性があるときに、// dSpaceCollideによって呼び出されるstaticvoidnearCallback(void*data, dGeomID o1, dGeomID o2 ) {inti;// if( o1->body && o2->body ) return; dBodyID b1 = dGeomGetBody( o1 );   dBodyID b2 = dGeomGetBody( o2 ); // 2つのボディがジョイントによって接続されているならば、何もせずに関数を抜けるif( b1 && b2     && dAreConnectedExcluding( b1, b2, dJointTypeContact ) )   {  return;   }     dContact contact[ MAX_CONTACTS ];// up to MAX_CONTACTS contacts per box-boxfor( i = 0; i < MAX_CONTACTS; i++ )   {     contact[ i ].surface.mode = dContactBounce | dContactSoftCFM;     contact[ i ].surface.mu = dInfinity;     contact[ i ].surface.mu2 = 0;     contact[ i ].surface.bounce = 0.1;     contact[ i ].surface.bounce_vel = 0.1;     contact[ i ].surface.soft_cfm = 0.01;   } // 接触情報を作成するintnumc = dCollide( o1, o2, MAX_CONTACTS, &contact[ 0 ].geom,sizeof( dContact ) );if( numc )   {     dMatrix3 RI;     dRSetIdentity( RI );   constdReal ss[ 3 ] = { 0.02, 0.02, 0.02 };   for( i = 0; i < numc; i++ )     {    // 接触ジョイントを作成する    dJointID c = dJointCreateContact( world, contactgroup, contact + i );        dJointAttach( c, b1, b2 );      if( show_contacts )       {      // 接触した位置に直方体を描画する      dsDrawBox( contact[ i ].geom.pos, RI, ss );       }     if( doFeedback        && ( b1 == obj[ selected ].body          || b2 == obj[ selected ].body ) )       {      if( fbnum < MAX_FEEDBACKNUM )         {           feedbacks[ fbnum ].first = ( b1 == obj[ selected ].body );         // 作成した接触ジョイントにフィードバックを設定する        dJointSetFeedback( c, &feedbacks[ fbnum++ ].fb );         }      else      {           fbnum++;         }       }     }   } }

start

// シミュレーションを開始するstaticvoidstart() {   dAllocateODEDataForThread( dAllocateMaskAll );  // 視点を設定するstaticfloatxyz[ 3 ] = { 2.1640f, -1.3079f, 1.7600f };staticfloathpr[ 3 ] = { 125.5000f, -17.0000f, 0.0000f };   dsSetViewpoint( xyz, hpr );     printf( "To drop another object, press:\n" );   printf( "   b for box.\n" );   printf( "   s for sphere.\n" );   printf( "   c for capsule.\n" );   printf( "   y for cylinder.\n" );   printf( "   v for a convex object.\n" );   printf( "   x for a composite object.\n" );   printf( "To select an object, press space.\n" );   printf( "To disable the selected object, press d.\n" );   printf( "To enable the selected object, press e.\n" );   printf( "To dump transformation data for the selected object, press p.\n" );   printf( "To toggle showing the geom AABBs, press a.\n" );   printf( "To toggle showing the contact points, press t.\n" );   printf( "To toggle dropping from random position/orientation, press r.\n" );   printf( "To save the current state to 'state.dif', press 1.\n" );   printf( "To show joint feedbacks of selected object, press f.\n" ); }

locase

// 小文字に変換するcharlocase(charc ) {if( c >= 'A' && c <= 'Z' )   {  returnc - ( 'a' - 'A' );   }else{  returnc;   } }

command

// キー押下時に呼び出されるstaticvoidcommand(intcmd ) {   size_t i;  // オブジェクトを識別するための番号intj, k;   dReal sides[ 3 ];   dMass m;intsetBody;// ボディとの関連付け (dGeomSetBody) は不要か? cmd =locase( cmd );if( cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y' || cmd == 'v' )   {     setBody = 0;// ボディとの関連付け必要if( num < NUM )     {       i = num;       num++;     }  else  {       i = nextobj;       nextobj++;     if( nextobj >= num )       {         nextobj = 0;       }      // iの位置にあるボディとジオメトリを破棄する    dBodyDestroy( obj[ i ].body );     for( k = 0; k < GPB; k++ )       {      if( obj[ i ].geom[ k ] )         {           dGeomDestroy( obj[ i ].geom[ k ] );         }       }     // 破棄したオブジェクトのメモリを0でクリアする    memset( &obj[ i ], 0,sizeof( obj[ i ] ) );     }   // ボディを作成する  obj[ i ].body = dBodyCreate( world );  for( k = 0; k < 3; k++ )     {       sides[ k ] = dRandReal() * 0.5 + 0.1;     }      dMatrix3 R;  if( random_pos )     {       dBodySetPosition(         obj[ i ].body,         dRandReal() * 2 - 1,         dRandReal() * 2 - 1,         dRandReal() + 2         );        dRFromAxisAndAngle(         R,         dRandReal() * 2.0 - 1.0,         dRandReal() * 2.0 - 1.0,         dRandReal() * 2.0 - 1.0,         dRandReal() * 10.0 - 5.0         );     }  else  {       dReal maxheight = 0;     for( k = 0; k < num; k++ )       {      constdReal *pos = dBodyGetPosition( obj[ k ].body );       if( pos[ 2 ] > maxheight )         {           maxheight = pos[ 2 ];         }       }        dBodySetPosition( obj[ i ].body, 0, 0, maxheight + 1 );        dRSetIdentity( R );//    dRFromAxisAndAngle( R, 0, 0, 1, /* dRandReal() * 10.0 - 5.0 */ 0 );  }      dBodySetRotation( obj[ i ].body, R );     dBodySetData( obj[ i ].body, (void* )i );   if( cmd == 'b' )// 直方体 (Box)  {       dMassSetBox( &m, DENSITY, sides[ 0 ], sides[ 1 ], sides[ 2 ] );       obj[ i ].geom[ 0 ] = dCreateBox( space, sides[ 0 ], sides[ 1 ], sides[ 2 ] );     }  elseif( cmd == 'c' )// カプセル (Capsule)  {       sides[ 0 ] *= 0.5;        dMassSetCapsule( &m, DENSITY, 3, sides[ 0 ], sides[ 1 ] );       obj[ i ].geom[ 0 ] = dCreateCapsule( space, sides[ 0 ], sides[ 1 ] );     }  elseif( cmd == 'v' )// 凸形状オブジェクト (Convex Object)  {       dMassSetBox( &m, DENSITY, 0.25, 0.25, 0.25 );#if0     obj[ i ].geom[ 0 ] = dCreateConvex(       space,       planes,       planecount,       points,       pointcount,       polygons       );#else  obj[ i ].geom[ 0 ] = dCreateConvex(       space,       Sphere_planes,       Sphere_planecount,       Sphere_points,       Sphere_pointcount,       Sphere_polygons       );#endif  }  elseif( cmd == 'y' )// 円柱 (Cylinder)  {       dMassSetCylinder( &m, DENSITY, 3, sides[ 0 ], sides[ 1 ] );       obj[ i ].geom[ 0 ] = dCreateCylinder( space, sides[ 0 ], sides[ 1 ] );     }  elseif( cmd == 's' )// 球 (Sphere)  {       sides[ 0 ] *= 0.5;        dMassSetSphere( &m, DENSITY, sides[ 0 ] );       obj[ i ].geom[ 0 ] = dCreateSphere( space, sides[ 0 ] );     }  elseif( cmd == 'x' && USE_GEOM_OFFSET )// (重心オフセット) 混成オブジェクト (Composite Object)  {       setBody = 1;// ボディとの関連付け不要     dMass m2;       dMassSetZero( &m );        dReal dpos[ GPB ][ 3 ]; // ジオメトリ間の位置のずれ    dMatrix3 drot[ GPB ];     // ランダムな位置を設定する for( j = 0; j < GPB; j++ )       {      for( k = 0; k < 3; k++ )         {           dpos[ j ][ k ] = dRandReal() * 0.3 - 0.15;         }       }     // 総質量を求める for( k = 0; k < GPB; k++ )       {      if( k == 0 )// 球 (Sphere)      {           dReal radius = dRandReal() * 0.25 + 0.05;            obj[ i ].geom[ k ] = dCreateSphere( space, radius );           dMassSetSphere( &m2, DENSITY, radius );         }      elseif( k == 1 )// 直方体 (Box)      {           obj[ i ].geom[ k ] = dCreateBox( space, sides[ 0 ], sides[ 1 ], sides[ 2 ] );           dMassSetBox( &m2, DENSITY, sides[ 0 ], sides[ 1 ], sides[ 2 ] );         }      else// カプセル (Capsule)      {           dReal radius = dRandReal() * 0.1 + 0.05;           dReal length = dRandReal() * 1.0 + 0.1;            obj[ i ].geom[ k ] = dCreateCapsule( space, radius, length );           dMassSetCapsule( &m2, DENSITY, 3, radius, length );         }           dRFromAxisAndAngle(           drot[ k ],           dRandReal() * 2.0 - 1.0,           dRandReal() * 2.0 - 1.0,           dRandReal() * 2.0 - 1.0,           dRandReal() * 10.0 - 5.0           );          dMassRotate( &m2, drot[ k ] );         dMassTranslate( &m2, dpos[ k ][ 0 ], dpos[ k ][ 1 ], dpos[ k ][ 2 ] );       // 総質量に加算する      dMassAdd( &m, &m2 );       }     for( k = 0; k < GPB; k++ )       {         dGeomSetBody( obj[ i ].geom[ k ], obj[ i ].body );       // ジオメトリの重心をオフセットさせる      dGeomSetOffsetPosition(           obj[ i ].geom[ k ],           dpos[ k ][ 0 ] - m.c[ 0 ],           dpos[ k ][ 1 ] - m.c[ 1 ],           dpos[ k ][ 2 ] - m.c[ 2 ]           );          dGeomSetOffsetRotation( obj[ i ].geom[ k ], drot[ k ] );       }        dMassTranslate( &m, -m.c[ 0 ], -m.c[ 1 ], -m.c[ 2 ] );       dBodySetMass( obj[ i ].body, &m );     }  elseif( cmd == 'x' )// 混成オブジェクト (Composite Object)  {       dGeomID g2[ GPB ];     // ジオメトリ    dReal dpos[ GPB ][ 3 ];// ジオメトリ間の位置のずれ     dMass m2;       dMassSetZero( &m );     // ランダムな位置を設定する for( j = 0; j < GPB; j++ )       {      for( k = 0; k < 3; k++ )         {           dpos[ j ][ k ] = dRandReal() * 0.3 - 0.15;         }       }     for( k = 0; k < GPB; k++ )       {      // ジオメトリ変換オブジェクトを作成する      obj[ i ].geom[ k ] = dCreateGeomTransform( space );         dGeomTransformSetCleanup( obj[ i ].geom[ k ], 1 );        if( k == 0 )// 球(Sphere)      {           dReal radius = dRandReal() * 0.25 + 0.05;           g2[ k ] = dCreateSphere( 0, radius );           dMassSetSphere( &m2, DENSITY, radius );         }      elseif( k == 1 )// 直方体(Box)      {           g2[ k ] = dCreateBox( 0, sides[ 0 ], sides[ 1 ], sides[ 2 ] );           dMassSetBox( &m2, DENSITY, sides[ 0 ], sides[ 1 ], sides[ 2 ] );         }      else// カプセル(Capsule)      {           dReal radius = dRandReal() * 0.1 + 0.05;           dReal length = dRandReal() * 1.0 + 0.1;           g2[ k ] = dCreateCapsule( 0, radius, length );           dMassSetCapsule( &m2, DENSITY, 3, radius, length );         }        // ジオメトリ変換オブジェクトにジオメトリを格納する      dGeomTransformSetGeom( obj[ i ].geom[ k ], g2[ k ] );           dMatrix3 Rtx;         dRFromAxisAndAngle(           Rtx,           dRandReal() * 2.0 - 1.0,           dRandReal() * 2.0 - 1.0,           dRandReal() * 2.0 - 1.0,           dRandReal() * 10.0 - 5.0           );       // ジオメトリの位置と姿勢を設定する      dGeomSetPosition( g2[ k ], dpos[ k ][ 0 ], dpos[ k ][ 1 ], dpos[ k ][ 2 ] );         dGeomSetRotation( g2[ k ], Rtx );        // 質量パラメータを回転させ移動する      dMassRotate( &m2, Rtx );         dMassTranslate( &m2, dpos[ k ][ 0 ], dpos[ k ][ 1 ], dpos[ k ][ 2 ] );       // 総質量に加算する      dMassAdd( &m, &m2 );       }     // 重心が ( 0, 0, 0 ) となるように、すべてのカプセル化されたオブジェクトを移動する for( k = 0; k < GPB; k++ )       {         dGeomSetPosition(           g2[ k ],           dpos[ k ][ 0 ] - m.c[ 0 ],           dpos[ k ][ 1 ] - m.c[ 1 ],           dpos[ k ][ 2 ] - m.c[ 2 ]           );       }        dMassTranslate( &m, -m.c[ 0 ], -m.c[ 1 ], -m.c[ 2 ] );     }   // ボディとの関連付けが不要とされていないならば、関連付けを行うif( !setBody )     {    for( k = 0; k < GPB; k++ )       {      if( obj[ i ].geom[ k ] )         {           dGeomSetBody( obj[ i ].geom[ k ], obj[ i ].body );         }       }     }      dBodySetMass( obj[ i ].body, &m );   } if( cmd == ' ' )   {  // 選択されているオブジェクトを変更する  selected++;   if( selected >= num )     {       selected = 0;     }   if( selected < 0 )     {       selected = 0;     }   }elseif( cmd == 'd' && selected >= 0 && selected < num )   {  // 選択されているオブジェクトを無効にする  dBodyDisable( obj[ selected ].body );   }elseif( cmd == 'e' && selected >= 0 && selected < num )   {  // 選択されているオブジェクトを有効にする  dBodyEnable( obj[ selected ].body );   }elseif( cmd == 'a' )   {     show_aabb ^= 1;   }elseif( cmd == 't' )   {     show_contacts ^= 1;   }elseif( cmd == 'r' )   {     random_pos ^= 1;   }elseif( cmd == '1' )   {     write_world = 1;   }elseif( cmd == 'p' && selected >= 0 )   {  // 選択されているオブジェクトの位置と姿勢を表示するconstdReal *pos = dGeomGetPosition( obj[ selected ].geom[ 0 ] );  constdReal *rot = dGeomGetRotation( obj[ selected ].geom[ 0 ] );      printf( "POSITION:\n\t[ %f, %f, %f ]\n\n", pos[ 0 ], pos[ 1 ], pos[ 2 ] );     printf( "ROTATION:\n\t[ %f, %f, %f, %f ]\n\t[ %f, %f, %f, %f ]\n\t[ %f, %f, %f, %f ]\n\n",       rot[ 0 ], rot[ 1 ], rot[ 2 ], rot[ 3 ],       rot[ 4 ], rot[ 5 ], rot[ 6 ], rot[ 7 ],       rot[ 8 ], rot[ 9 ], rot[ 10 ], rot[ 11 ]       );   }elseif( cmd == 'f' && selected >= 0 && selected < num )   {  if( dBodyIsEnabled( obj[ selected ].body ) )     {       doFeedback = 1;     }   } }

drawGeom

// ジオメトリを描画するvoiddrawGeom( dGeomID g,constdReal *pos,constdReal *R,intshow_aabb ) {inti; if( !g )   {  return;   }  if( !pos )   {     pos = dGeomGetPosition( g );   } if( !R )   {     R = dGeomGetRotation( g );   }  // ジオメトリの種類を取得するinttype = dGeomGetClass( g ); if( type == dBoxClass )// 直方体{     dVector3 sides;     dGeomBoxGetLengths( g, sides );      dsDrawBox( pos, R, sides );   }elseif( type == dSphereClass )// 球{     dsDrawSphere( pos, R, dGeomSphereGetRadius( g ) );   }elseif( type == dCapsuleClass )// カプセル{     dReal radius, length;     dGeomCapsuleGetParams( g, &radius, &length );      dsDrawCapsule( pos, R, length, radius );   }elseif( type == dConvexClass )// 凸形状{#if0     dsDrawConvex(       pos,       R,       planes,       planecount,       points,       pointcount,       polygons     );#else  dsDrawConvex(       pos,       R,       Sphere_planes,       Sphere_planecount,       Sphere_points,       Sphere_pointcount,       Sphere_polygons     );#endif}elseif( type == dCylinderClass )// 円柱{     dReal radius, length;     dGeomCylinderGetParams( g, &radius, &length );      dsDrawCylinder( pos, R, length, radius );   }elseif( type == dGeomTransformClass )// ジオメトリ変換オブジェクト{  // ジオメトリ変換オブジェクトに格納されているジオメトリを取得する  dGeomID g2 = dGeomTransformGetGeom( g );   constdReal *pos2 = dGeomGetPosition( g2 );  constdReal *R2 = dGeomGetRotation( g2 );      dVector3 actual_pos;     dMatrix3 actual_R;     dMULTIPLY0_331( actual_pos, R, pos2 );      actual_pos[ 0 ] += pos[ 0 ];     actual_pos[ 1 ] += pos[ 1 ];     actual_pos[ 2 ] += pos[ 2 ];     dMULTIPLY0_333( actual_R, R, R2 );   // ジオメトリ変換オブジェクトに格納されていたジオメトリで描画し直すdrawGeom( g2, actual_pos, actual_R, 0 );   }  // ジオメトリgのボディを描画するif( show_body )   {     dBodyID body = dGeomGetBody( g );   if( body )     {    constdReal *bodypos = dBodyGetPosition( body );    constdReal *bodyr = dBodyGetRotation( body );        dReal bodySides[ 3 ] = { 0.1, 0.1, 0.1 };// 描画サイズ    dsSetColorAlpha( 0, 1, 0, 1 );        dsDrawBox( bodypos, bodyr, bodySides );     }   } // ジオメトリgの境界ボックスを描画するif( show_aabb )   {  // 境界ボックスを取得する  dReal aabb[ 6 ];     dGeomGetAABB( g, aabb );      dVector3 bbpos;  for( i = 0; i < 3; i++ )     {       bbpos[ i ] = 0.5 * ( aabb[ i * 2 ] + aabb[ i * 2 + 1 ] );     }      dVector3 bbsides;  for( i = 0; i < 3; i++ )     {       bbsides[ i ] = aabb[ i * 2 + 1 ] - aabb[ i * 2 ];     }      dMatrix3 RI;     dRSetIdentity( RI );      dsSetColorAlpha( 1, 0, 0, 0.5 );     dsDrawBox( bbpos, RI, bbsides );   } }

simLoop

// シミュレーション ループstaticvoidsimLoop(intpause ) {   dsSetColor( 0, 0, 2 ); // 衝突するボディを検出するdSpaceCollide( space, 0, &nearCallback); if( !pause )   {  // シミュレーションのステップを進める  dWorldQuickStep( world, 0.02 );   }  // ワールドの状態をファイルに出力するif( write_world )   {     FILE *f = fopen( "state.dif", "wt" );   if( f )     {       dWorldExportDIF( world, f, "X" );       fclose( f );     }      write_world = 0;   }  // フィードバックを表示するif( doFeedback )   {  if( fbnum>MAX_FEEDBACKNUM )     {       printf( "joint feedback buffer overflow!\n" );     }  else  {       dVector3 sum = { 0, 0, 0 };       printf( "\n" );     for(inti = 0; i < fbnum; i++ )       {         dReal *f =           feedbacks[ i ].first ?           feedbacks[ i ].fb.f1 :// ジョイントがボディ1に作用する力        feedbacks[ i ].fb.f2;// ジョイントがボディ2に作用する力       printf( "%f %f %f\n", f[ 0 ], f[ 1 ], f[ 2 ] );          sum[ 0 ] += f[ 0 ];         sum[ 1 ] += f[ 1 ];         sum[ 2 ] += f[ 2 ];       }        printf( "Sum: %f %f %f\n", sum[ 0 ], sum[ 1 ], sum[ 2 ] );        dMass m;       dBodyGetMass( obj[ selected ].body, &m );        printf( "Object G=%f\n", GRAVITY * m.mass );     }      doFeedback = 0;     fbnum = 0;   } // ジョイント グループを破棄する (すべての接触ジョイントを破棄する)dJointGroupEmpty( contactgroup );     dsSetColor( 1, 1, 0 );   dsSetTexture( DS_WOOD );  for(inti = 0; i < num; i++ )   {  for(intj = 0; j < GPB; j++ )     {    // 描画色を設定する if( i == selected )// オブジェクトが選択されている    {         dsSetColor( 0, 0.7, 1 );       }    elseif( ! dBodyIsEnabled( obj[ i ].body ) )// ボディが無効状態    {         dsSetColor( 1, 0.8, 0 );       }    else    {         dsSetColor( 1, 1, 0 );       }     // ジオメトリを描画する drawGeom( obj[ i ].geom[ j ], 0, 0, show_aabb );     }   } }

main

intmain(intargc,char**argv ) {// drawstuffの設定をするdsFunctions fn;   fn.version = DS_VERSION;   fn.start = &start;   fn.step = &simLoop;   fn.command = &command;   fn.stop = 0;   fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;     dInitODE2( 0 ); // ワールドを作成するworld = dWorldCreate();   space = dHashSpaceCreate( 0 );   contactgroup = dJointGroupCreate( 0 );    dWorldSetGravity( world, 0, 0, -GRAVITY );   dWorldSetCFM( world, 1e-5 );        // CFMdWorldSetAutoDisableFlag( world, 1 );// 自動無効化を有効#if1   dWorldSetAutoDisableAverageSamplesCount( world, 10 );#endif dWorldSetLinearDamping( world, 0.00001 );// 速度の減衰率dWorldSetAngularDamping( world, 0.005 );// 角速度の減衰率dWorldSetMaxAngularSpeed( world, 200 );// 角速度の最大値 dWorldSetContactMaxCorrectingVel( world, 0.1 );// 修正速度dWorldSetContactSurfaceLayer( world, 0.001 );// 表面層の厚さ  dCreatePlane( space, 0, 0, 1, 0 );    memset( obj, 0,sizeof( obj ) );  // シミュレーションを開始するdsSimulationLoop( argc, argv, 352, 288, &fn );     dJointGroupDestroy( contactgroup );   dSpaceDestroy( space );   dWorldDestroy( world );    dCloseODE(); return0; }
最終更新:2016年07月19日 15:54