ODE講座11:å˜ä½ç³»ã¨åº§æ¨™ç³»ï¼ˆä½ç½®ãƒ»å§¿å‹¢ã®è¨å®šå–得)

ODEã®åº§æ¨™ç³»ï¼ˆå³æ‰‹ç³»ï¼‰
ゲーム開発やãƒãƒœãƒƒãƒˆã®ç ”究者ã«ã‚‚使ã‚れã¦ã„るオープンソースã®ç‰©ç†è¨ˆç®—エンジンODE(Open Dynamics Engineã€ã‚ªãƒ¼ãƒ—ン ダイナミクスエンジン)をå¦ã¶ODEè¬›åº§ã®æ„›ï¼‘1回目ã§ã™ã€‚
今回ã¯ODEã®å˜ä½ç³»ä¸¦ã³ã«åº§æ¨™ç³»ã®ãŠè©±ã‚’ã—ã€å‰›ä½“ã®ä½ç½®ãƒ»å§¿å‹¢ã‚’è¨å®šåŠã³å–å¾—ã™ã‚‹æ–¹æ³•を説明ã—ã¾ã™ã€‚
å˜ä½ç³»
ODEã®å˜ä½ç³»ã¯åŸºæœ¬çš„ã«ä½•ã§ã‚‚ã‹ã¾ã„ã¾ã›ã‚“。ãŸã ã—ã€è§’度ã ã‘ã¯radianã«ãªã£ã¦ã„ã¾ã™ã€‚本講座ã§ã¯ä¸–界標準ã§ã‚ã‚‹SIå˜ä½ç³»ã‚’用ã„ã¾ã™ã€‚ ã“れã¯ç‰©ç†ãªã©ã§å¾¡ãªã˜ã¿ã®é•·ã•ã¯mã€è³ªé‡ã¯kgã€æ™‚é–“ã¯sã§ã™ã€‚
座標系
ODEã®åº§æ¨™ç³»ã¯ä¸Šå›³ã«ç¤ºã™ã‚ˆã†ã«ç‰©ç†ã‚„æ•°å¦ã§ä¸€èˆ¬çš„ã«ä½¿ã‚れã¦ã„ã‚‹å³æ‰‹ç³»ã®ç›´äº¤åº§æ¨™ã§ã™ã€‚原点ã¯ï¼™å€‹ã‚ã‚‹å°ã•ã„ピラミッドã®ä¸å¿ƒã§ã€ä¸å¿ƒã‹ã‚‰èµ¤ã„ピラミッド方å‘ãŒx軸ã€é’ã„ピラミッド方å‘ãŒy軸ã€ä¸Šç©ºæ–¹å‘ãŒz軸ã¨ãªã£ã¦ã„ã¾ã™ã€‚ãªãŠã€å˜ä½ç³»ã¯ä½•ã§ã‚‚よã„ã®ã§ã™ãŒã€ã“ã®è¬›åº§ã§ã¯ï¼³ï¼©å˜ä½ç³»ã‚’採用ã—ã¦ã„ã‚‹ã®ã§ã€å„ピラミッドã¯1mãšã¤ã®é–“éš”ã§ä¸¦ã‚“ã§ã„ã¾ã™ã€‚
ä½ç½®ã¨å§¿å‹¢ã®è¨å®š
剛体を3次元空間上ã«è¨å®šã™ã‚‹ãŸã‚ã«ã¯ã€ä½ç½®ã¨å§¿å‹¢ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚å§¿å‹¢ã¯å›žè»¢å¤‰æ›è¡Œåˆ—ã§æ±ºã‚ã‚‹ã“ã¨ãŒã§ãã€ODEã§ã‚‚以下ã®APIã«ã‚ˆã‚Šè¨å®šå¯èƒ½ã§ã™ã€‚
void dBodySetPosition(dBodyID, dReal x, dReal y, dReal z);
剛体dBodyIDã®é‡å¿ƒã‚’絶対座標系ã®ä½ç½®(x, y, z)ã«è¨å®šã™ã‚‹ã€‚
void dRFromAxisAndAngle(dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle);
回転軸ベクトル(ax, ay, az)ã®å›žã‚Šã‚’åæ™‚計方å‘ã«angle[rad]回転ã—ãŸã¨ãã®å›žè»¢å¤‰æ›è¡Œåˆ—Rã‚’å–å¾—ã™ã‚‹ã€‚
void dBodySetRotation(dBodyID, const dMatrix3 R);
剛体dBodyIDã®å§¿å‹¢ã‚’回転行列Rã«è¨å®šã™ã‚‹ã€‚
ã¾ãŸã€ï¼¯ï¼¤ï¼¥ã§ã¯ã“ã®ã»ã‹ã«ã‚¯ã‚ªãƒ¼ã‚¿ãƒ‹ã‚ªãƒ³ã«é–¢ã™ã‚‹APIã€void dBodySetQuaternion (dBodyID, const dQuaternion q)ã‚‚ã‚りã¾ã™ã€‚
ä½ç½®ã¨å§¿å‹¢ã®å–å¾—
const dReal * dBodyGetPosition(dBodyID);
剛体dBodyIDã®ä½ç½®ã‚’å–å¾—ã™ã‚‹ã€‚戻り値ã¯çµ¶å¯¾åº§æ¨™ç³»ã§ã®ä½ç½®ãŒæ ¼ç´ã•れã¦ã„ã‚‹é…列ã¸ã®ãƒã‚¤ãƒ³ã‚¿ã€‚
const dReal * dBodyGetRotation(dBodyID);
剛体dBodyIDã®å›žè»¢è¡Œåˆ—å–å¾—ã™ã‚‹ã€‚戻り値ã¯å›žè»¢è¡Œåˆ—ãŒæ ¼ç´ã•れã¦ã„ã‚‹é…列ã¸ã®ãƒã‚¤ãƒ³ã‚¿ã€‚
サンプルコード
次ã®ã‚µãƒ³ãƒ—ルコードã¯å††æŸ±ã‚’ä½ç½®ï¼ˆ0.0, 0.0, 1.0)ã€ï½˜è»¸ã®ã¾ã‚りã«ï¼”5度(M_PI/4.0)回転ã—ãŸå§¿å‹¢ã«è¨å®šã—ã¦ã„ã¾ã™ã€‚ã•らã«ã€ç‰©ä½“ã®é‡å¿ƒä½ç½®ã‚’表示ã™ã‚‹é–¢æ•°printPos()ã‚‚è¿½åŠ ã—ã¾ã—ãŸã€‚ãªãŠã€å††æŸ±ã¯å§¿å‹¢ã‚’è¨å®šã—ãªã„ã¨é•·è»¸ãŒz軸方å‘ã¨ä¸€è‡´ã—ãŸç›´ç«‹ã®å§¿å‹¢ã¨ãªã£ã¦ã„ã¾ã™ã€‚
[code]
typedef struct {
dBodyID body;
dGeomID geom;
} MyObject;
MyObject pillar;
void createPillar()
{
dMass m1;
dReal radius = 0.1, length = 0.5, mass = 1.0;  // åŠå¾„ã€é•·ã•ã€è³ªé‡
pillar.body = dBodyCreate(world);
dMassSetZero(&m1);
dMassSetCylinderTotal(&m1,mass,3,radius,length);
dBodySetMass(pillar.body,&m1);
dBodySetPosition(pillar.body, 0.0, 0.0, 1.0); // (0.0, 0.0, 1.0) [m]ã«é‡å¿ƒã‚’è¨å®š
dMatrix3 R;
dRFromAxisAndAngle(R, 1.0, 0.0, 0.0, M_PI/ 4.0); // x軸ã¾ã‚りã«Ï€/4[rad]回転
dBodySetRotation(pillar.body,R);
pillar.geom = dCreateCylinder(space,radius,length);
dGeomSetBody(pillar.geom,pillar.body);
}
void printPos(dBodyID obj_body) // é‡å¿ƒä½ç½®ã®è¡¨ç¤º
{
const dReal *pos;              // constを忘れるã¨ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã™
dReal x, y, z;
pos = dBodyGetPosition(obj_body);  // dBodyGetPostionã¯é…列ã¸ã®const ãƒã‚¤ãƒ³ã‚¿
x = pos[0];                  // é…列ã«ã¯x, y, zã®é †ç•ªã§åº§æ¨™å€¤ãŒæ ¼ç´ã•れã¦ã„ã‚‹
y = pos[1];
z = pos[2];
printf("x=%f y=%f z=%f \n", x, y, z);
}
[/code]
ã§ã¯ã€ã¾ãŸæ¬¡å›žï¼
æ›´æ–°å±¥æ´
- 2008-1-13: コードを整形ã—ãŸ
- 2007-1-14: å˜ä½ç³»ã®è¨˜è¿°ã‚’è¿½åŠ ã€ã‚³ãƒ¡ãƒ³ãƒˆã‚’補足