天天看點

bullet 實體引擎的角色控制器(character controller)

轉載 :http://hi.baidu.com/ae8506/item/693a7975d4fd502ed6a89c56

作者:CYM  http://hi.baidu.com/ae8506/

角色控制器(character controller)是實體引擎必不可少的一部分

在bullet中可以通過btKinematicCharacterController和btPairCachingGhostObject來實作角色控制

其中btKinematicCharacterController類是緻力于解決角色控制的類,他實作了滑動,爬梯子,跳躍等常見的動作.

在使用角色控制器之前先要包含以下幾個檔案

[cpp] view plain copy print ?

  1. #include <BulletDynamics\Character\btKinematicCharacterController.h>   
  2. #include <BulletCollision\CollisionDispatch\btGhostObject.h>  
#include <BulletDynamics\Character\btKinematicCharacterController.h>
#include <BulletCollision\CollisionDispatch\btGhostObject.h>
           

在頭檔案中聲明以下兩個對象

[cpp] view plain copy print ?

  1. btKinematicCharacterController* m_character;  
  2. btPairCachingGhostObject* m_ghostObject;  
btKinematicCharacterController* m_character;
btPairCachingGhostObject* m_ghostObject;
           

m_character就死角色控制器,m_ghostObject則是一個幽靈對象.

建立角色控制器(假設已經建立了實體世界并且可以通過physics對象調用)

[cpp] view plain copy print ?

  1. //建立膠囊對象以及角色控制器   
  2. {  
  3. m_trans.setIdentity ();  
  4. m_trans.setOrigin (btVector3(0.0, 500.0, 0.0));  
  5. m_ghostObject = new btPairCachingGhostObject();  
  6. m_ghostObject->setWorldTransform(m_trans);  
  7. physics->m_overlappingPairCache->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());  
  8. btScalar characterHeight=2.0f;  
  9. btScalar characterWidth =2.0f;  
  10. btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);  
  11. m_ghostObject->setCollisionShape (capsule);  
  12. m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);  
  13. btScalar stepHeight = btScalar(0.35);  
  14. m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);  
  15. //向世界中添加碰撞對象   
  16. physics->m_dynamicsWorld->addCollisionObject(  
  17. m_ghostObject,  
  18. btBroadphaseProxy::CharacterFilter,   
  19. btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);  
  20. physics->m_dynamicsWorld->addAction(m_character);  
  21. }  
//建立膠囊對象以及角色控制器
{
m_trans.setIdentity ();
m_trans.setOrigin (btVector3(0.0, 500.0, 0.0));
 
m_ghostObject = new btPairCachingGhostObject();
m_ghostObject->setWorldTransform(m_trans);
physics->m_overlappingPairCache->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
btScalar characterHeight=2.0f;
btScalar characterWidth =2.0f;
btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
m_ghostObject->setCollisionShape (capsule);
m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);
 
btScalar stepHeight = btScalar(0.35);
m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);
 
//向世界中添加碰撞對象
physics->m_dynamicsWorld->addCollisionObject(
m_ghostObject,
btBroadphaseProxy::CharacterFilter, 
btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
physics->m_dynamicsWorld->addAction(m_character);
}
           

根據使用者輸入,更新角色

[cpp] view plain copy print ?

  1. //根據外部輸入,更新角色   
  2. if (m_physics->m_dynamicsWorld)  
  3. {  
  4. ///設定行走方向   
  5. btTransform xform;  
  6. xform = m_ghostObject->getWorldTransform ();  
  7. //擷取本地坐标向量,并且機關化   
  8. btVector3 forwardDir = xform.getBasis()[2];  
  9. btVector3 upDir = xform.getBasis()[1];  
  10. btVector3 strafeDir = xform.getBasis()[0];  
  11. forwardDir.normalize ();  
  12. upDir.normalize ();  
  13. strafeDir.normalize ();  
  14. btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);  
  15. btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s   
  16. btScalar walkSpeed = walkVelocity* deltaTime*2.0f;  
  17. //控制前後行走,以及旋轉方向,   
  18. if (m_render->m_keyboard->isKeyDown(OIS::KC_RIGHT))  
  19. {  
  20. float yaw=0.05f;  
  21. btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();  
  22. orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),yaw));  
  23. m_ghostObject->getWorldTransform ().setBasis(orn);  
  24. }  
  25. if (m_render->m_keyboard->isKeyDown(OIS::KC_LEFT))  
  26. {  
  27. float yaw=-0.05f;  
  28. btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();  
  29. orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),yaw));  
  30. m_ghostObject->getWorldTransform ().setBasis(orn);  
  31. }  
  32. if (m_render->m_keyboard->isKeyDown(OIS::KC_UP))  
  33. {  
  34. walkDirection += forwardDir;  
  35. }  
  36. if (m_render->m_keyboard->isKeyDown(OIS::KC_DOWN))  
  37. {  
  38. walkDirection -= forwardDir;  
  39. }  
  40. if(m_render->m_keyboard->isKeyDown(OIS::KC_SPACE) && m_character && m_character->canJump())  
  41. {  
  42. m_character->jump();  
  43. }  
  44. //按照方向移動角色   
  45. m_character->setWalkDirection(walkDirection*walkSpeed);  
  46. }  
  47. //更新渲染對象   
  48. m_trans=m_ghostObject->getWorldTransform();  
  49. m_node->setPosition(m_trans.getOrigin().getX(),m_trans.getOrigin().getY(),m_trans.getOrigin().getZ());  
  50. m_node->setOrientation(m_trans.getRotation().getW(),m_trans.getRotation().getX(),m_trans.getRotation().getY(),m_trans.getRotation().getZ());  
//根據外部輸入,更新角色
if (m_physics->m_dynamicsWorld)
{
///設定行走方向
btTransform xform;
xform = m_ghostObject->getWorldTransform ();
//擷取本地坐标向量,并且機關化
btVector3 forwardDir = xform.getBasis()[2];
btVector3 upDir = xform.getBasis()[1];
btVector3 strafeDir = xform.getBasis()[0];
forwardDir.normalize ();
upDir.normalize ();
strafeDir.normalize ();
 
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s
btScalar walkSpeed = walkVelocity* deltaTime*2.0f;

//控制前後行走,以及旋轉方向,
if (m_render->m_keyboard->isKeyDown(OIS::KC_RIGHT))
{
float yaw=0.05f;
btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();
orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),yaw));
m_ghostObject->getWorldTransform ().setBasis(orn);
}
 
if (m_render->m_keyboard->isKeyDown(OIS::KC_LEFT))
{
float yaw=-0.05f;
btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();
orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),yaw));
m_ghostObject->getWorldTransform ().setBasis(orn);
}
 
if (m_render->m_keyboard->isKeyDown(OIS::KC_UP))
{
walkDirection += forwardDir;
}
 
if (m_render->m_keyboard->isKeyDown(OIS::KC_DOWN))
{
walkDirection -= forwardDir;
}
 
if(m_render->m_keyboard->isKeyDown(OIS::KC_SPACE) && m_character && m_character->canJump())
{
m_character->jump();
}
 
//按照方向移動角色
m_character->setWalkDirection(walkDirection*walkSpeed);
}
 
//更新渲染對象
m_trans=m_ghostObject->getWorldTransform();
m_node->setPosition(m_trans.getOrigin().getX(),m_trans.getOrigin().getY(),m_trans.getOrigin().getZ());
m_node->setOrientation(m_trans.getRotation().getW(),m_trans.getRotation().getX(),m_trans.getRotation().getY(),m_trans.getRotation().getZ());
           
bullet 實體引擎的角色控制器(character controller)

優酷視訊

http://v.youku.com/v_show/id_XMzc4NTgyODky.html

繼續閱讀