4. 3D グラフィクス
å¤ä¼‘ã¿ã«å…¥ã‚Šæ™‚é–“ãŒã§ããŸã®ã§ï¼ŒODEåˆç´šè¬›åº§ã®ï¼”回目を開講ã—ã¾ã™ï¼Žä»Šå›žã¯ODE(Open Dynamics Engine)ã®3Dグラフィクスã«ã¤ã„ã¦å¦ã³ã¾ã™ï¼ŽODEã®ãƒ‡ãƒ¢ã‚’実行ã™ã‚‹ã¨æ£šå¼•ã雲や地é¢ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®è³ªãŒè‰¯ã,シミュレーションã®è¦‹æ „ãˆãŒè‰¯ã„ã§ã™ã.ã“れã¯ï¼ŒODEã«ã‚‚れãªã付ã„ã¦ãã‚‹3Dグラフィクスライブラリdrawstuffã®ä»•æ¥ã§ã™ï¼ŽODEã§ã¯drawstuffã¯å˜ãªã‚‹ãƒ‡ãƒ¢ãƒ—ãƒã‚°ãƒ©ãƒ 表示用ã¨ã„ã†ä½ç½®ã¥ã‘ãªã®ã§ç°¡å˜ãªæ©Ÿèƒ½ã—ã‹ã‚りã¾ã›ã‚“ã—,ãƒãƒªã‚´ãƒ³ã®æç”»ã‚‚é…ã„ã®ã§drawstuffã§ä¸å分ãªå ´åˆã¯ä»–ã®ãƒ©ã‚¤ãƒ–ラリを使ã†ã¨è‰¯ã„ã§ã—ょã†ï¼ŽWindowsã®ä»–ã«Linuxã§ã‚‚利用ã—ãŸã„ãªã‚‰irrlichtã‚„Ogre3DãŒå€™è£œã«ä¸Šã‚‹ã¨æ€ã„ã¾ã™ï¼Ž
drawstuffã¯OpenGLã¨å‘¼ã°ã‚Œã‚‹3Dグラフィクスライブラリを使ã£ã¦æ›¸ã‹ã‚Œã¦ãŠã‚Šï¼Œã¨ã¦ã‚‚シンプルãªãƒ©ã‚¤ãƒ–ラリã§ã™ï¼Žç°¡å˜ãªã®ã§OpenGLã®å‹‰å¼·ã«ã‚‚ピッタリã§ã™ï¼ŽãªãŠï¼Œdrawstuffã«é–¢ã™ã‚‹API(関数)ã¯å°æ–‡å—ã®dsã§å§‹ã¾ã‚Šï¼ŒODEã«é–¢ã™ã‚‹APIã¯å°æ–‡å—ã®dã§å§‹ã¾ã‚Šã¾ã™ï¼Ž
drawstuffã®ä½¿ã„æ–¹
- ヘッダファイルをインクルードã™ã‚‹
[code] #include <drawstuff/drawstuff.h> [/code]
- è¨ã€€å®š
drawstuffを使ã†ãŸã‚ã«ã¯ä¸‹ã®dsFunctionsæ§‹é€ ä½“ã®å„メンãƒã‚’è¨å®šã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“.
// drawstuffã§ä½¿ã‚れるdsFunctionsæ§‹é€ ä½“ã®å®šç¾©
typedef struct dsFunctions
{
int version; /* DS_VERSIONを入れる */
void (*start)(); /* シミュレーションループãŒå§‹ã¾ã‚‹å‰ã«å‘¼ã³å‡ºã•れる */
void (*step) (int pause); /* シミュレーションループ毎呼ã³å‡ºã•れる */
void (*command) (int cmd); /* ã‚ãƒ¼ãŒæŠ¼ã•れるã¨å‘¼ã³å‡ºã•れる */
void (*stop)(); /* シミュレーションループã®å¾Œã«å‘¼ã³å‡ºã•れる */
const char *path_to_textures; /* テクスãƒãƒ£ã¸ã®ãƒ‘ス */
}
dsFunctions;
-
- ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š DS_VERSIONを代入ã™ã‚‹
- fn.version = DS_VERSION
- å‰å‡¦ç†é–¢æ•°ï¼šã€€ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒ«ãƒ¼ãƒ—ãŒå§‹ã¾ã‚‹å‰ã«å‘¼ã³å‡ºã•れã¾ã™ï¼Žã“ã“ã§ï¼Œã‚«ãƒ¡ãƒ©ã®è¦–点ã¨è¦–ç·šã‚’è¨å®šã™ã‚‹ã®ãŒä¸€èˆ¬çš„ã§ã™ï¼Ž
- fn.start = &start;
- カメラã®è¦–点,視線
dsSetViewpoint(視点,視線);
- シミュレーションループ関数:シミュレーションã®å„ãƒ«ãƒ¼ãƒ—ã§æ¯Žå›žå‘¼ã³å‡ºã•れã¾ã™ï¼Žã“ã®é–¢æ•°ã«å‹•力å¦è¨ˆç®—,è¡çªæ¤œå‡ºè¨ˆç®—ã‚„æç”»ã«é–¢ã™ã‚‹å‡¦ç†ã‚’書ãã¾ã™ï¼Žã‚µãƒ³ãƒ—ルプãƒã‚°ãƒ©ãƒ ã§ã¯æç”»ã«é–¢ã™ã‚‹å‡¦ç†ã ã‘を書ã„ã¦ã„ã¾ã™ï¼Ž
- fn.step = &simLoop;
- æç”»ã«é–¢ã™ã‚‹APIを書ã
- ã‚ー処ç†é–¢æ•°ï¼šã€€ã‚ãƒ¼ãŒæŠ¼ã•れる度ã«å‘¼ã³å‡ºã•れã¾ã™ï¼Žå¿…è¦ãŒãªã„å ´åˆã¯NULL(ヌルãƒã‚¤ãƒ³ã‚¿ï¼‰ã‚’代入ã—ã¾ã™ï¼ŽNULLã¯ï¼ç•ªåœ°ã‚’指ã™ç‰¹åˆ¥ãªãƒã‚¤ãƒ³ã‚¿ã§ã—ãŸã.
- fn.command = &command;
- 後処ç†é–¢æ•°ï¼šã€€ã‚·ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒ«ãƒ¼ãƒ—ãŒçµ‚ã‚ã£ãŸå¾Œã«å‘¼ã³å‡ºã•れã¾ã™ï¼Žå¿…è¦ãŒãªã„å ´åˆã¯NULL(ヌルãƒã‚¤ãƒ³ã‚¿ï¼‰ã‚’代入ã—ã¾ã™ï¼Ž
- fn.stop = &stop;
- テクスãƒãƒ£ã®ãƒ‘ス
- fn.path_to_textures = “パス”;
- ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š DS_VERSIONを代入ã™ã‚‹
- 実 行
- 以下ã®APIを一度ã ã‘呼ã³å‡ºã™ã¨æç”»ã•れã¾ã™ï¼Žå†…部ã¯whileループã«ãªã£ã¦ã„ã¾ã™ï¼Ž
dsSimulationLoop(argc, argv, witdh, height, &fn);
- argc, argv: main関数ã®å¼•æ•°
- width: ウインドウã®å¹…
- height: ウインドウã®é«˜ã•
- fn: ドãƒãƒ¼ã‚¹ã‚¿ãƒƒãƒ•æ§‹é€ ä½“dsFunctionsã®å¤‰æ•°
- 以下ã®APIを一度ã ã‘呼ã³å‡ºã™ã¨æç”»ã•れã¾ã™ï¼Žå†…部ã¯whileループã«ãªã£ã¦ã„ã¾ã™ï¼Ž
サンプルプãƒã‚°ãƒ©ãƒ
/* ODE tutorial by Kosei Demura */
/* Lesson 4 3D Graphics */
// çƒï¼Œå††æŸ±ï¼Œã‚«ãƒ—セル,ボックス,線をæç”»ã™ã‚‹ãƒ—ãƒã‚°ãƒ©ãƒ
// è¡çªæ¤œå‡ºï¼Œå‹•力å¦è¨ˆç®—ã¯ã—ã¦ã„ã¾ã›ã‚“.
#include <ode/ode.h>
#include <drawstuff/drawstuff.h>
#ifdef _MSC_VER
#pragma warning(disable:4244 4305) // VC++用è¦å‘Šã‚’æ¢ã‚ã‚‹
#endif
#ifdef dDOUBLE
#define dsDrawBox dsDrawBoxD
#define dsDrawSphere dsDrawSphereD
#define dsDrawCylinder dsDrawCylinderD
#define dsDrawCapsule dsDrawCapsuleD
#define dsDrawLine dsDrawLineD
#endif
#define DENSITY (5.0) // 密度
struct MyObject {
dBodyID body; // ボディ(剛体)
};
dReal radius = 0.25; // åŠå¾„
dReal length = 1.0; // é•·ã•
dReal sides[3] = {0.5,0.5,1.0}; // 辺ã®é•·ã•
static dWorldID world; // 動力å¦è¨ˆç®—ワールド
static MyObject sphere, box, capsule, cylinder; // 物体
// start simulation
static void start()
{
static float xyz[3] = {5,3,0.5}; // 視点[m]
static float hpr[3] = {-180, 0, 0}; // 視線[°]
dsSetViewpoint (xyz,hpr); // 視点ã¨è¦–ç·šã®è¨å®š
}
// シミュレーションループ
static void simLoop (int pause)
{
const dReal *pos1,*R1,*pos2,*R2,*pos3,*R3; // çƒã®æç”»
dsSetColor(1,0,0); // 色ã®è¨å®š (赤,緑,é’ï¼‰å„æˆåˆ†ã¯0ã‹ã‚‰1
dsSetSphereQuality(3); // çƒã®è³ªã‚’高ã‚ã‚‹
pos1 = dBodyGetPosition(sphere.body); // ä½ç½®ã®å–å¾—
R1 = dBodyGetRotation(sphere.body); // å§¿å‹¢(回転行列)ã®å–å¾—
dsDrawSphere(pos1,R1,radius); // çƒã®æç”»
// å††æŸ±ã®æç”»
dsSetColorAlpha (0,1,0,1);
pos2 = dBodyGetPosition(cylinder.body);
R2 = dBodyGetRotation(cylinder.body);
dsDrawCylinder(pos2,R2,length,radius); // å††æŸ±ã®æç”»
// ã‚«ãƒ—ã‚»ãƒ«ã®æç”»
dsSetColorAlpha (1,1,1,1);
pos2 = dBodyGetPosition(capsule.body);
R2 = dBodyGetRotation(capsule.body);
dsDrawCapsule(pos2,R2,length,radius); // ã‚«ãƒ—ã‚»ãƒ«ã®æç”»
// ãƒœãƒƒã‚¯ã‚¹ã®æç”»
dsSetColorAlpha (0,0,1,1);
pos3 = dBodyGetPosition(box.body);
R3 = dBodyGetRotation(box.body);
dsDrawBox(pos3,R3,sides); // ãƒœãƒƒã‚¯ã‚¹ã®æç”»
// ç·šã®æç”»
dReal posA[3] = {0, 5, 0}, posB[3]={0, 5, 1.9};
dsDrawLine(posA,posB); // ç·šã®æç”»
}
int main (int argc, char **argv)
{
// drawstuffã®è¨å®š
dsFunctions fn;
fn.version = DS_VERSION;
fn.start = &start;
fn.step = &simLoop;
fn.command = NULL;
fn.stop = NULL;
fn.path_to_textures = "../../drawstuff/textures";
dInitODE(); // ODEã®åˆæœŸåŒ–
world = dWorldCreate(); // 動力å¦è¨ˆç®—用ワールドã®ç”Ÿæˆ
dMass m; // 質é‡ãƒ‘ラメータ
dMassSetZero (&m); // 質é‡ãƒ‘ラメータã®è¨å®š
// çƒ
sphere.body = dBodyCreate (world); // ボディã®ç”Ÿæˆ
dReal radius = 0.5; // åŠå¾„ [m]
dMassSetSphere (&m,DENSITY,radius);
// 質é‡ãƒ‘ラメータã®è¨ˆç®—
dBodySetMass (sphere.body,&m); // ボディã«è³ªé‡ãƒ‘ラメータをè¨å®šã™ã‚‹
dBodySetPosition (sphere.body,0,1, 1); // ボディã®ä½ç½®ã‚’è¨å®š
// ボックス
box.body = dBodyCreate (world);
dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
dBodySetMass (box.body,&m); dBodySetPosition (box.body,0,2,1);
// カプセル capsule.body = dBodyCreate (world);
dMassSetCapsule(&m,DENSITY,3,radius,length);
dBodySetMass (capsule.body,&m);
dBodySetPosition (capsule.body,0,4,1);
// 円柱
cylinder.body = dBodyCreate (world);
dMassSetCylinder(&m,DENSITY,3,radius,length);
dBodySetMass (cylinder.body,&m);
dBodySetPosition (cylinder.body,0,3,1);
// シミュレーションã®å®Ÿè¡Œ
dsSimulationLoop (argc,argv,960,480,&fn);
dWorldDestroy (world); // ワールドã®ç ´å£Š
dCloseODE(); // ODEã®çµ‚了
return 0;
}
ダウンãƒãƒ¼ãƒ‰
