¹Ú½º Ãæµ¹

À̹øÀå¿¡¼­´Â ¹Ú½º¸¦ ƯÁ¤ ³ôÀÌ¿¡¼­ ¶³¾î ¶ß·Á º¸ÀÚ. ½ºÆäÀ̽º Å°¸¦ ´©¸£¸é ¹Ú½º°¡ Áö»óÀ¸·Î ¶³¾îÁø´Ù.

< ºñÁê¾ó ½ºÆ©µð¿À Bullet ¼³Á¤ >  
: ºñÁê¾ó ½ºÆ©µð¿À 2008¿¡¼­ Bullet ¹°¸® ¿£ÁøÀ» ºôµåÇϱâ À§ÇÑ È¯°æ ¼³Á¤µéÀÌ´Ù.

Ãß°¡ Æ÷ÇÔ µð·ºÅ丮  "c:\bullet-2.77\src"
Ãß°¡ ¶óÀ̺귯¸® µð·ºÅ丮 "C:\bullet-2.77\msvc\2008\lib\Debug"

¶óÀ̺귯¸® Ãß°¡
BulletDynamics.lib BulletCollision.lib LinearMath.lib

Äڵ忡¼­ Çì´õ Ãß°¡
#include <btBulletDynamicsCommon.h>

< ±¸Çö >
Bullet ¹°¸® ¿£ÁøÀ» ó¸®Çϱâ À§ÇÑ ±¸ÇöÀº Å©°Ô ´ÙÀ½°ú °°´Ù.

1. InitBullet - ¹°¸® ¿£Áø ÃʱâÈ­
2. UnInitBullet - ¹°¸® ¿£Áø¿¡ »ç¿ëµÈ ÀÚ¿øµéÀÇ ÇØÁ¦
3. CreateGround - Á¤ÀûÀÎ Ãæµ¹ Plane ¸¸µé±â
4. CreateBox - µ¿ÀûÀÎ Ãæµ¹ ¹Ú½º ¸¸µé±â
5. SimulationBullet - ¹°¸® ½Ã¹Ä·¹À̼Ç

 

1. InitBullet ÇÔ¼ö
: Bullet ÃʱâÈ­

¨ç broadphase »ý¼º
broadphase¸¦ »ý¼ºÇÏ´Â ÀÌÀ¯´Â aabb-overlapping ¿ÀºêÁ§Æ® ½ÖÀ» ã¾Æ³»¾î,¿ùµå ¾È¿¡¼­ Ãæµ¹ÇÏÁö ¾ÊÀº ¿ÀºêÁ§Æ® ½ÖµéÀ» ¹Ì¸® Á¦°ÅÇÏ¿© Ãæµ¹ ó¸® ½Ã°£À» ÁÙÀδÙ.

btDbvtBroadphase ¾Ë°í¸®Áò: 2°³ÀÇ µ¿ÀûÀÎ AABB bounding volume hierarchies/tree¸¦ »ç¿ëÇÑ´Ù. Çϳª´Â Á¤ÀûÀÎ ¿ÀºêÁ§Æ®, ¶Ç ´Ù¸¥ Çϳª´Â µ¿ÀûÀÎ ¿ÀºêÁ§Æ®¸¦ À§ÇØ »ç¿ëÇÑ´Ù. ¿ÀºêÁ§Æ®µéÀº ÇϳªÀÇ Æ®¸®¿¡¼­ ´Ù¸¥Æ®¸®·Î À̵¿ ÇÒ ¼ö ÀÖ´Ù. ¿ÀºêÁ§Æ®¸¦ Ãß°¡, Á¦°ÅÇÏ´Â µ¿ÀÛÀº sweep and prune( btAxisSweep3 ¿Í bt32BitAxisSweep3 )º¸´Ù ºü¸£´Ù.  

¨è collision configuration »ý¼º

¨é collision dispatcher »ý¼º
broadphase ¿¡ ÀÇÇØ °É·¯ÁöÁö ¾ÊÀº ¿ÀºêÁ§Æ®µéÀ» Ãæµ¹ ó¸®ÇÒ Äݹé ÇÔ¼ö¸¦ µî·ÏÇϱâ À§Çؼ­ collision dispatcher¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. À̶§ collision configurationÀ» »ç¿ëÇÏ¿© ¼¼ºÎ Ãæµ¹ °¨Áö ¾Ë°í¸®ÁòÀ» Æ©´×ÇÑ´Ù.

¨ê constraint solver »ý¼º
ÀÌÁ¦ ¿ÀºêÁ§Æ®µé¿¡ Áß·Â, Èû, Ãæµ¹, °üÀý Á¦¾à µéÀ» Àû¿ëÇϱâ À§ÇÏ¿© solver°¡ ÇÊ¿äÇÏ´Ù.
solver ´Â ¼º´É ½Ã¹Ä·¹À̼ÇÀÇ º´¸ñÀ» ÃÊ·¡ÇÏ´Â ±ØÇѱîÁö Àû¿ëÇÏÁö ¾Ê´Â´Ù¸é ²Ï ÁÁÀº ±â´ÉÀ» ÇÑ´Ù. ¶ÇÇÑ ¸î °¡Áö º´·Ä ¾²·¹µù ¸ðµ¨ (threading model)µµ Á¸ÀçÇÑ´Ù.

¨ë dynamics world »ý¼º
btDiscreteDynamicsWorld Ŭ·¡½ºÀÇ »ý¼ºÀÚ ÇÁ·ÎŸÀÔÀº ´ÙÀ½°ú °°´Ù.
btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(
                       btDispatcher* dispatcher,
                       btBroadphaseInterface* pairCache,
                       btConstraintSolver* constraintSolver,
                       btCollisionConfiguration* collisionConfiguration)

Áß·Â ¹æÇâÀ» ¼³Á¤ÇÑ´Ù.  Up ¹æÇâÀÌ ¾çÀÇ YÀ̹ǷΠÁß·ÂÀº -YÀÌ´Ù.
g_world->setGravity( btVector3(0,-10,0) )

btBroadphaseInterface*                g_broadphase = NULL;

btDefaultCollisionConfiguration*    g_collisionConfiguration = NULL;

btCollisionDispatcher*                g_dispatcher = NULL;

btConstraintSolver*                    g_solver = NULL;

btDynamicsWorld*                    g_world = NULL;       

btAlignedObjectArray<btCollisionShape*>    g_collisionShapes;

 

bool InitBullet()

{

    //¨ç broadphase »ý¼º

    btVector3 worldAabbMin(-10000,-10000,-10000);

    btVector3 worldAabbMax(10000,10000,10000);

    g_broadphase = new btAxisSweep3( worldAabbMin, worldAabbMax, 100);

 

    //¨è collision configuration »ý¼º

    g_collisionConfiguration = new btDefaultCollisionConfiguration();

 

    //¨é collision dispatcher »ý¼º

    g_dispatcher = new btCollisionDispatcher(g_collisionConfiguration);

 

    //¨ê constraint solver »ý¼º

    g_solver = new btSequentialImpulseConstraintSolver;

 

    //¨ë dynamics world »ý¼º

    g_world = new btDiscreteDynamicsWorld( g_dispatcher, g_broadphase, g_solver, g_collisionConfiguration);

    g_world->setGravity( btVector3(0,-10,0) );

    return true;

}

2. UnInitBullet  ÇÔ¼ö
InitBullet¿¡¼­ »ý¼ºµÈ ÀÚ¿øµéÀ» ÇØÁ¦ÇÑ´Ù.

void UnInitBullet()

{

    for (int i = g_world->getNumCollisionObjects()-1; i>=0 ;i--)

    {

        btCollisionObject* obj = g_world->getCollisionObjectArray()[i];

        btRigidBody* body = btRigidBody::upcast(obj);

        if (body && body->getMotionState())

        {

            delete body->getMotionState();

        }

        g_world->removeCollisionObject( obj );

        delete obj;

    }

 

    //

    for (int j=0;j<g_collisionShapes.size();j++)

    {

        btCollisionShape* shape = g_collisionShapes[j];

        delete shape;

    }

 

    //

    SAFE_DELETE( g_broadphase );

    SAFE_DELETE( g_dispatcher );

    SAFE_DELETE( g_solver );

    SAFE_DELETE( g_world );

    SAFE_DELETE( g_collisionConfiguration );

}

3. CreateGround ÇÔ¼ö

Ãæµ¹Àº Å©°Ô Áú·®, ¸¶Âû·Â, º¹¿ø·Â, °ü¼º¿¡ ÀÇÇØ ¿µÇâÀ» ¹Þ´Â´Ù. ÀÌµé ¿ë¾îÀ» Á¤¸®ÇØ º»´Ù.

Áú·®(Mass): µ¿¿ªÇÐ ¿ùµå¿¡¼­ ¿òÁ÷ÀÌ´Â ¹°Ã¼ÀÇ Áú·®Àº ¾çÀÇ °ªÀÌ°í, Bullet ¿£Áø¿¡¼­ ¿òÁ÷ÀÌÁö ¾Ê´Â Á¤ÀûÀÎ ¹°Ã¼´Â 0 ÀÌ´Ù. Bullet ¿£Áø¿¡¼­ ´ÜÀ§´Â KgÀÌ´Ù.

¸¶Âû·Â(friction):
¸¶Âû·ÂÀº µÎ°³ÀÇ ¹°Ã¼°¡ ¼­·Î ºÎµ÷Èú ¶§ ¹ß»ýµÇ´Â ¿¡³ÊÁö¸¦ ÃøÁ¤ÇÏ´Â °ÍÀ¸·Î ¾Æ·¡¿Í °°ÀÌ ¿©·¯ ´ÜÀ§·Î ±¸ºÐÇÑ´Ù. ¸¶Âû·ÂÀº ¹°Ã¼°¡ ¶Ç ´Ù¸¥ ¹°Ã¼¿Í ºÎµ÷Ä¥ ¶§ »ý°Ü³ª´Â ÈûÀ» ÃøÁ¤ÇÏ´Â ´ÜÀ§·Î ¸¶Âû°è¼ö(COEFFICIENT OF FRICTION)¶ó ÇÑ´Ù.
¸¶Âû°è¼ö´Â ¹°Ã¼ÀÇ ¹«°Ô¿¡ µû¶ó¼­ ´Þ¶óÁö´Âµ¥, ÇϳªÀÇ ¹°Ã¼°¡ ´Ù¸¥ ¹°Ã¼ À§¸¦ ¹Ì²ô·¯Áú ¶§ ÇÊ¿äÇÑ ÈûÀ» ÃøÁ¤ÇÏ´Â ´ÜÀ§¸¦ ¸¶Âû°è¼ö¶ó ÇÑ´Ù.

º¹¿ø·Â(restitution):
ÆòÇà À§Ä¡¿¡¼­ ¹þ¾î³­ ¹°Ã¼(º¼)°¡ ¿ø·¡ÀÇ À§Ä¡·Î º¹±ÍÇÏ·Á´Â ÈûÀ» ¸»Çϸç, µ¿Àû »óÅ¿¡¼­ º¼ÀÌ ÇÉ°ú Ãßµ¹ÇÒ ¶§ °¨¼ÒÇÏ´Â º¼ÀÇ ¿¡³ÊÁö »óŸ¦ ȸº¹½ÃÅ°´Â °ÍÀ» º¹¿ø·ÂÀ̶ó ÇÑ´Ù. º¹¿ø°è¼ö Ç¥¸é ÀçÁú°ú µÎ²²¿¡ µû¶ó ¸¹Àº ¿µÇâÀ» ³¢Ä¡°Ô µÈ´Ù.

°ü¼º(inertia):
¹°Ã¼(º¼)°¡ ¿Ü·ÂÀÇ ÀÛ¿ëÀ» ¹ÞÁö ¾Ê´Â ÇÑ Á¤Áö ¶Ç´Â ¿îµ¿ »óŸ¦ Áö¼ÓÇÏ·Á´Â ¼ºÁú·Î ¿ÜºÎ·ÎºÎÅÍ ÈûÀÇ ÀÛ¿ëÀ» ¹ÞÁö ¾Ê´Â ¹°Ã¼(º¼)´Â óÀ½¿¡ ¾î¶² ¼Óµµ¸¦ °¡Áö¸é ±× ¼Óµµ¸¦ À¯ÁöÇÏ¿© µî¼Óµµ ¿îµ¿À» °è¼ÓÇÏ°Ô µÈ´Ù. ÀÌ°ÍÀ» °ü¼º ¹ýÄ¢À̶ó°í ÇÑ´Ù.
¹°Ã¼(º¼)¿¡ ÈûÀÌ ÀÛ¿ëÇÏ¸é ¼Óµµ°¡ º¯ÇÏ°í ¼Óµµ º¯È­ÀÇ ½Ã°£ ºñÀ²Àº °¡¼Óµµ·Î ³ªÅ¸³ª´Âµ¥, °°Àº ¹°Ã¼¿¡ ¿©·¯ °¡Áö ÈûÀ» °¡ÇßÀ» ¶§ »ý±â´Â °¡¼Óµµ´Â Èû¿¡ ºñ·ÊÇϸç, ¹æÇâµµ ÈûÀÇ ¹æÇâ°ú ÀÏÄ¡ÇÏ°Ô µÈ´Ù.

Ãæµ¹ ÇüÅÂ(shape)¸¦ »ý¼ºÇÏ´Â ´Ü°è´Â 5´Ü°è·Î ¿ä¾à ÇÒ ¼ö ÀÖ´Ù.

¨ç collision shape »ý¼º

»ý¼ºÀÚ btStaticPlaneShape( const btVector3& planeNormal, btScalar planeConstant )
ù¹ø° Àμö´Â Æò¸éÀÇ ³ë¸Ö°ªÀÌ°í, µÎ¹ø° Àμö´Â ¹«ÇÑ Æò¸éÀÇ À§Ä¡ °ªÀÌ´Ù.

btCollisionShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
ù ¹ø° ÀÎÀÚ¿¡ Áú·® 0, µÎ ¹ø° ÀÎÀÚ¿¡ °ü¼ºÀ» ³Ö´Â´Ù.

¨è MotionState »ý¼º
btDefaultMotionState´Â ¹°¸®¿Í ±×·¡ÇÈ ¿ÀºêÁ§Æ® »çÀÌ¿¡¼­ ¿ÀÇÁ¼ÂÀ» °¡Áö´Â ¿ùµå º¯È¯ÀÇ µ¿½Ã¼ºÀ» ¸ÂÃß´Â (synchronize) °øÅëÀûÀÎ ±¸ÇöÀ» Á¦°øÇÑ´Ù.
°ÔÀÓ¿¡¼­ ¸ÅÇÁ·¹ÀÓ ¾÷µ¥ÀÌÆ®½Ã, ¹°¸® °´Ã¼ BodyÀÇ À§Ä¡³ª ȸÀü°ªÀÌ ¹Ù²ï´Ù. ÀÌ ¶§ ¹°¸® °´Ã¼ÀÇ À§Ä¡, ȸÀü°ªÀ» ¾ò¾î ¿Ã·Á¸é MotionState°¡ ÇÊ¿äÇÏ´Ù.

¨é construction info »ý¼º

btRigidBody¿¡ Àü´ÞÇØÁÖ±â À§ÇÑ btRigidBody::btRigidBodyConstructionInfo ±¸Á¶Ã¼¸¦ ¸¸ŠÒ´Ï´Ù.

¨ê rigid body »ý¼º

btRigidBody¸¦ »ý¼º ÇÕ´Ï´Ù.

¨ë rigid body¸¦ world¿¡ Ãß°¡

btDynamicsWorld¿¡ btRidgidBody °´Ã¼¸¦ Ãß°¡ ÇÕ´Ï´Ù.

void CreateGround()

{

    //¨ç collision shape »ý¼º

    btCollisionShape* groundShape = new btStaticPlaneShape( btVector3(0,1,0), 0);

 

    g_collisionShapes.push_back(groundShape);

    btTransform groundTransform;

    groundTransform.setIdentity();

    groundTransform.setOrigin(btVector3(0,0,0));

 

    btScalar mass(0);

 

    //rigidbody is dynamic if and only if mass is non zero, otherwise static

    bool isDynamic = (mass != 0.f);

 

    btVector3 localInertia(0,0,0);

    if (isDynamic)

        groundShape->calculateLocalInertia( mass, localInertia);

 

    //¨è MotionState »ý¼º

    btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);

    //¨é construction info »ý¼º

    btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);

    //¨ê rigid body »ý¼º

    btRigidBody* body = new btRigidBody(rbInfo);

 

    //¨ë rigid body¸¦ world¿¡ Ãß°¡

    g_world->addRigidBody(body);

}

4. CreateBox

void CreateBox(const D3DXVECTOR3& vec)

{

    //¨ç collision shape »ý¼º

    btVector3 v = btVector3( vec.x, vec.y, vec.z );

    btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));

    g_collisionShapes.push_back(colShape);

 

    btTransform startTransform;       

    startTransform.setIdentity();

 

    btScalar mass(10);

 

    bool isDynamic = (mass != 0.f);

    btVector3 localInertia(0,0,0);

 

    if (isDynamic)

        colShape->calculateLocalInertia(mass,localInertia);

 

    startTransform.setOrigin(v);

 

    //¨è MotionState »ý¼º

    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);

    //¨é construction info »ý¼º

    btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);

    //¨ê rigid body »ý¼º

    btRigidBody* body = new btRigidBody(rbInfo);

 

    //¨ë rigid body¸¦ world¿¡ Ãß°¡

    g_world->addRigidBody(body);

}

 

5. SimulationBullet

int stepSimulation( btScalar timeStep,

                    int maxSubSteps=1,

                    btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)  )

timpStepÀº delta time Áï, ÀÌÀü ÇÁ·¹ÀÓ¿¡ ´ëÇÑ °æ°ú ½Ã°£ À¸·Î ÃÊ´ÜÀ§ÀÌ´Ù.
fixedTimeStep¿¡ ÀÇÇØ subStepÀ¸·Î timeStepÀ» ³ª´«´Ù.  subStepÀÇ ÃÖ°í ¹Ýº¹ Ƚ¼ö´Â maxSubSteps¿¡ ÀÇÇØ Á¦ÇÑ µÈ´Ù.
fixedTimeStepÀº 60ÇÁ·¹ÀÓÀ¸·Î ³ª´« °ªÀÌ´Ù.

void SimulationBullet(float fElapsedTime)

{

    if(g_world)

    {

        g_world->stepSimulation( fElapsedTime );

    }

}

 

< MotionState·Î Transform ±¸Çϱâ >

GetCollisionOb jectSize()´Â ¹°¸® ¿ÀºêÁ§Æ®ÀÇ °¹¼ö¸¦ ¸®ÅÏÇÑ´Ù.
GetCollisionObjectTransform()Àº ¹°¸® ¿ÀºêÁ§Æ®ÀÇ Çà·ÄÀ» ¸®ÅÏÇÑ´Ù. ¿©±â¼­ 0¹ø À妽º´Â óÀ½À¸·Î Ãß°¡ÇÑ Á¤ÀûÀÎ ¹«ÇÑ Æò¸éÀÌ´Ù.

int GetCollisionObjectSize()

{

    return g_world->getCollisionObjectArray().size();

}

 

D3DXMATRIX GetCollisionObjectTransform( int nIndex )

{

    btTransform trans = g_world->getCollisionObjectArray()[nIndex]->getWorldTransform();

 

    float mat[16];

    D3DXMATRIX matObj;

    trans.getOpenGLMatrix(mat);

    memcpy( &matObj, mat, sizeof(float)*16);

    return matObj;

}

 

getOpenGLMatrix·Î ±¸ÇÑ Çà·ÄÀº OpenGL Çà·ÄÀε¥ ÀüÄ¡ Çà·Ä·Î º¯È¯ÇÏÁö ¾Ê´Â ÀÌÀ¯´Â ´ÙÀ½°ú °°´Ù.

OpenGL ¿­ ¿ì¼±(column major) Çà·Ä DirectX Çà ¿ì¼±(row major) Çà·Ä
m0 m4 m8 m12
m1 m5 m9 m13
m2 m6 m10 m14
m3 m7 m11 m15
m0 m1 m2 m3
m4 m5 m6 m7
m8 m9 m10 m11
m12 m13 m14 m15

2Â÷¿ø ¹è¿­À» »ç¿ëÇÏ´Â °æ¿ì OpenGLÀº ¿­ ¿ì¼±À̹ǷΠm3¿¡ Á¢±Ù ÇÒ·Á¸é m[0][3], m12¿¡ Á¢±ÙÇÒ·Á¸é m[3][0]À» »ç¿ëÇÑ´Ù. ÀÏÂ÷¿ø ¹è¿­ÀÇ ¼ø¼­´Â m0, m1, m2, m3 ..... m13, m14, m15 ¼ø¼­ÀÌ´Ù.

DirectX´Â Çà ¿ì¼±À̹ǷΠm3¿¡ Á¢±Ù ÇÒ·Á¸é m[0[3], m12¿¡ Á¢±Ù ÇÒ·Á¸é m[3][0]ÀÌ´Ù.
ÀÏÂ÷¿ø ¹è¿­ÀÇ ¼ø¼­´Â m0, m1, m2, m3 ..... m13, m14, m15 ¼ø¼­ÀÌ´Ù.

±×·¯¹Ç·Î OpenGLÀÇ 1Â÷¿ø Çà·ÄÀ» DirectX Çà·Ä·Î ¹Ù²Ü¶§ ÀüÄ¡ Çà·Ä·Î º¯È¯ ÇÒ ÇÊ¿ä°¡ ¾ø´Ù.
1Â÷¿ø  ¹è¿­ÀÇ °ªÀ» ±×´ë·Î ¿Å±â¸é µÈ´Ù.

btAlignedObjectArray:
btAlignedObjectArrayÀº std::vector¿Í ºñ½ÁÇϸç Äü Á¤·Ä, Èü Á¤·ÄÀ» Áö¿øÇÑ´Ù.  ºñÁê¾ó ½ºÆ©µð¿À µð¹ö°Å ¸ðµå¿¡¼­ btAlignedObjectArray¿Í btVector3 ³»¿ëÀ» º¼·Á¸é, Bullet/msvc/autoexp_ext.txt¸¦ Âü°íÇÑ´Ù.

ÇÁ·ÎÁ§Æ®: BulletBox.zip