ODE講座23:関節ä¸å¿ƒç‚¹ã®å–å¾—ã¨ã‚¹ã‚±ãƒ«ãƒˆãƒ³è¡¨ç¤º

上ã®å›³ã¯ã‚¸ãƒ§ã‚¤ãƒ³ãƒˆï¼ˆé–¢ç¯€ï¼‰ã®ä¸å¿ƒã«çƒã‚’æç”»ã—ã€å„ボディã®é‡å¿ƒã¨å„関節ä¸å¿ƒã‚’ç›´ç·šã§çµã³ã€ãれãŒå¤–部ã‹ã‚‰è¦‹ãˆã‚‹ã‚ˆã†ã«ãƒœãƒ‡ã‚£ã‚’åŠé€æ˜Žã«ã—スケルトン表示ã—ã¦ã„ã¾ã™ã€‚
ODE (Open Dynamics Engine) 講座ã®ï¼’3回目ã§ã™ã€‚ 11月ã«å…¥ã‚Šã€ã‚«ãƒ‹æ¼ãŒè§£ç¦ã«ãªã‚Šã¾ã—ãŸã€‚雄ã®ã‚ºãƒ¯ã‚¤ã‚¬ãƒ‹ã¯ã¨ã¦ã‚‚有åã§ã™ãŒã€ãã®é›Œã¯é¦™ç®±ã‚¬ãƒ‹ã¨å‘¼ã°ã‚Œä½“ã¯å°ã•ã„ã®ã§ã™ãŒã€åµãŒç¾Žå‘³ã§ç味ã¨ã—ã¦é‡å®ã•れã¦ã„ã¾ã™ã€‚今年ã¯è±Šæ¼ã®ã‚ˆã†ã§ã€é‡‘æ²¢ã§ã¯è¿‘所ã®ã‚¹ãƒ¼ãƒ‘ーã§ï¼“æ¯ï¼‘ï¼ï¼ï¼å††ç¨‹åº¦ã§è³¼å…¥ã§ãã¾ã™ã€‚金沢ã§ã¯ç¾Žå‘³ã—ã„食ã¹ç‰©ã¨ãŠé…’ã¨æ¸©æ³‰ãŒã“れã‹ã‚‰ã®æ¥½ã—ã¿ã¨ãªã‚Šã¾ã™ã€‚
ã•ã¦ã€ãƒãƒƒãƒ—ã•ã‚“ã‹ã‚‰ã€é–¢ç¯€ä¸å¿ƒç‚¹ã®å–得法ã«ã¤ã„ã¦è³ªå•ãŒã‚りã€ODE本をèªã‚“ã§ã‚‚よãã‚ã‹ã‚‰ãªã„ã¨ã®ã“ã¨ã ã£ãŸã®ã§ã“ã“ã§è£œè¶³ã—ã¾ã™ã€‚
ã“ã®ä¾‹ã§ã¯ã€é–¢ç¯€ã®ä¸å¿ƒã‚’çƒã§è¡¨ç¤ºã—ã€é‡å¿ƒã¨é–¢ç¯€ä¸å¿ƒã‚’ç·šã§è¡¨ç¤ºã—ã¦ã„ã¾ã™ã€‚ã•らã«ã€ç·šãŒè¦‹ãˆã‚‹ã‚ˆã†ã«ãƒœãƒ‡ã‚£ã‚’åŠé€æ˜Žã«ã—ã¦ã„ã¾ã™ã€‚ åŠé€æ˜Žã§æç”»ã™ã‚‹APIã¯dsSetColorAlphaã§ã™ã€‚
1. 関節ä¸å¿ƒç‚¹ã®å–å¾—
ã“ã“ã§ã¯é–¢ç¯€ã¨ã—ã¦ãƒ’ンジジョイントを例ã«å–りã¾ã™ã€‚ヒンジジョイントã®é–¢ç¯€ä¸å¿ƒç‚¹ã‚’å–å¾—ã™ã‚‹APIã¯æ¬¡ã®ï¼’ã¤ã‚りã¾ã™ã€‚
- dJointGetHingeAnchor(Â dJointIDÂ joint, dVector3 result)
- dJointGetHingeAnchor2(dJointID joint, dVector3 result)
ヒンジジョイントjointã®é–¢ç¯€ä¸å¿ƒã‚’絶対座標系ã§å–å¾—ã—ã€ãã®å€¤ã‚’resultã«ä»£å…¥ã—ã¾ã™ã€‚dVector3ã¯dRealåž‹ã®è¦ç´ 数3個ã®é…列ã§ã™ã€‚æ£ç¢ºã«ã¯è¦ç´ 数4個ã®é…列ã§ã™ãŒã€ã“れã¯è¨ˆç®—を高速ã«ã™ã‚‹ãŸã‚ã®ãƒ†ã‚¯ãƒ‹ãƒƒã‚¯ã§ã€å®Ÿéš›ã«ã¯æœ€åˆã®ï¼“個ã®è¦ç´ ã—ã‹ä½¿ã‚れã¾ã›ã‚“。
1番目ã¨ï¼’番目ã®APIã®é•ã„ã¯å‰è€…ã¯ãƒœãƒ‡ã‚£ï¼‘ã«å¯¾å¿œã™ã‚‹ãƒ’ンジã®ä¸å¿ƒç‚¹ã§ã€å¾Œè€…ã®dJointGetHingeAnchor2ã¯ãƒœãƒ‡ã‚£ï¼’ã«å¯¾å¿œã™ã‚‹ãƒ’ンジã®ä¸å¿ƒç‚¹ã§ã™ã€‚ヒンジを生æˆã—ãŸã¨ãã¯ä¸¡è€…ã®ä¸å¿ƒç‚¹ã¯ä¸€è‡´ã—ã¦ã„ã¾ã™ãŒã€ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’é‡ãる度ã«ãšã‚ŒãŒç”Ÿã˜ã¾ã™ã€‚ãれãžã‚Œã‚’ç›´ã™ã®ãŒEFPパラメータã§ã™ã€‚
2. スケルトン表示(åŠé€æ˜Žè‰²ã®è¨å®šï¼‰
シミュレーションã«ã‚ˆã£ã¦ã¯å†…éƒ¨ã®æ§‹é€ を見ã›ã‚‹ãŸã‚ã«ã‚¹ã‚±ãƒ«ãƒˆãƒ³è¡¨ç¤ºã—ãŸã„å ´åˆãŒã‚りã¾ã™ã€‚æç”»ãƒ©ã‚¤ãƒ–ラリã§ã‚ã‚‹drawstuffを使ã„åŠé€æ˜Žã®ç‰©ä½“ã‚’æç”»ã™ã‚‹ã«ã¯æ¬¡ã®APIを使ã„ã¾ã™ã€‚
- dsSetColorAlpha(float r, float g, float b, float alpha);
ã“ã“ã§ã€æœ€åˆã®å¼•数 r, g, bã¯èµ¤ã€ç·‘ã€é’ã®ä¸‰åŽŸè‰²ã€alphaã¯é€æ˜Žåº¦ã‚’表ã—ã€0ã‹ã‚‰1ã¾ã§ã®ç¯„囲をå–りã€é€æ˜Žåº¦ã§0ã¯é€æ˜Žã€1ã¯ä¸é€æ˜Žã§ã™ã€‚
ãªãŠã€ã‚¹ã‚±ãƒ«ãƒˆãƒ³è¡¨ç¤ºã™ã‚‹å ´åˆã¯æç”»ã®é †ç•ªãŒå¤§åˆ‡ã§ã™ã€‚ã“ã®ä¾‹ã®å ´åˆã¯ã€ã¾ãšä¸é€æ˜Žã®éª¨ã«ç›¸å½“ã™ã‚‹ç›´ç·šã‚’æç”»ã—ã€ãã®å¾Œã«åŠé€æ˜Žã®é–¢ç¯€ã‚„ボディをæç”»ã—ã¾ã™ã€‚ã“ã®é †ç•ªã‚’é–“é•ãˆã‚‹ã¨è¡¨ç¤ºã•れã¾ã›ã‚“。
関係部分ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’以下ã«ç¤ºã—ã¾ã™ã€‚全ソースコードã¯ã“ã“ã‹ã‚‰å–å¾—å¯èƒ½ã§ã™ã€‚
サンプルプãƒã‚°ãƒ©ãƒ ã§ã¯bã‚ーを押ã™ã¨ãƒœãƒ‡ã‚£æç”»ã®è¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚
[code]
static void simLoop (int pause)
{
const dReal *pos[BODY_NUM],*R[BODY_NUM];
dMatrix3 R1;
dVector3 ap[BODY_NUM-1]; // 関節ä¸å¿ƒç‚¹ã€€anchor point
float ar = 0.06; // 関節表示用çƒã®åŠå¾„ anchor radius
if (!pause) {
if (steps++ < 10) dBodyAddForce (leg[0].body, 0, 1.0, 0);
for (int i = 0; i < BODY_NUM-1; i++)  control(i, joint[i]);
dSpaceCollide(space,0,&nearCallback);
dWorldStep(world,0.01);
dJointGroupEmpty(contactgroup);
}
// é‡å¿ƒä½ç½®ã¨å›žè»¢è¡Œåˆ—ã®å–得 calculate positions and orientaitons
for (int i = 0; i < BODY_NUM; i++) {
pos[i] = dBodyGetPosition(leg[i].body);
R[i] = dBodyGetRotation(leg[i].body);
}
// 関節ä¸å¿ƒã®å–得  calculate anchor points
dRSetIdentity(R1);
for (int i = 0; i < BODY_NUM-1; i++) {
dJointGetHingeAnchor(joint[i], ap[i]);
}
// 関節ä¸å¿ƒã‹ã‚‰é‡å¿ƒã¾ã§ç›´ç·šã§æç”»ã€€draw lines
for (int i = 0; i < BODY_NUM-1; i++) {
dsSetColorAlpha(1.3, 1.3, 1.3, 1.0);
dsDrawLine(pos[i], ap[i]);
dsSetColorAlpha(0.0, 0.0, 0.0, 1.0);
dsDrawLine(ap[i], pos[i+1]);
}
dsSetColorAlpha(1.3, 0.0, 0.0, 0.5);
// 関節ä¸å¿ƒã‚’ä¸å¿ƒã¨ã—ãŸçƒã®æç”»ã€€draw anchors
for (int i = 0; i < BODY_NUM-1; i++) {
dJointGetHingeAnchor(joint[i], ap[i]); // 関節ä¸å¿ƒç‚¹ã®å–å¾—
dsDrawSphere(ap[i], R1, ar);
}
// ãƒœãƒ‡ã‚£ã®æç”»ã€€draw legs
dsSetColorAlpha(0.0, 0.0, 1.3, 0.5); // 逿˜Žè‰²ã®è¨å®š
for (int i = 0; i < BODY_NUM; i++) {
if (drawBody) dsDrawCapsule(pos[i],R[i],leg[i].length,leg[i].radius);
}
}
[/code]
ç¶šã…