Ogre中的碰撞检测(完整版)

Ogre中的碰撞检测(完整版)  
  原创UI动力     韩举  
http://www.uipower.com/
  请注明转载地址  
  Ogre是开源的封装了DirectX和OpenGL的3D引擎  
  Ogre的下载和安装见http://www.uipower.com/bbs/dispbbs.asp?boardID=24&ID=225&page=1  
  此主题相关图片如下:  
  [img]http://www.uipower.com/bbs/UploadFile/2004-12/20041221342286.jpg[/img]
  下载代码  
http://www.uipower.com/bbs/dispbbs.asp?boardid=24&id=233
  Ogre采用树桩管理场景中的各种"元素"(摄像机、灯光、物体等),所有的东西都挂在"树"上,不在"树"上的东西不会被渲染。  
  Ogre::SceneManager就是"树"的管理者,Ogre::SceneNode是从SceneManager中创建的(当然BSP和8*树的管理也和这两个类有关,这暂时不讨论)。  
  AABB(轴对齐包围盒)  
  这个东西是碰撞检测的基础(怎么总想起JJYY呢),和它类似的还有OBB(有向包围盒),由于OBB创建复杂,所以Ogre采用了AABB。  
  最简单的碰撞检测:  
  通过Ogre::SceneNode::_getWorldAABB()可以取得这个叶子节点的AABB(Ogre::AxisAlignedBox), Ogre::AxisAlignedBox封装了对AABB的支持,该类的成员函数Ogre::AxisAlignedBox::intersects ()可以判断一个AABB和"球体、点、面以及其他面"的相交情况(碰撞情况)。  
          m_SphereNode树的叶子,挂了一个"球"  
          m_CubeNode树的叶子,挂了一个"正方体"   

  AxisAlignedBox   spbox=m_SphereNode->_getWorldAABB();   
  AxisAlignedBox   cbbox
=m_CubeNode->_getWorldAABB();   
  
if(spbox.intersects(cbbox))   
  
{   
            
//相交   
  }
 

   区域查询:  
  简单的讲就是,查询某一区域中有什么东西,分为AABB、球体、面查询。 

//创建一个球体查询,这里的100是m_SphereNode挂着的那个球体的半径   
SphereSceneQuery   *   pQuery=m_SceneMgr->createSphereQuery(Sphere(m_SphereNode->getPosition(),100));   
//执行这个查询   
SceneQueryResult   QResult=pQuery->execute();   
//遍历查询列表找出范围内的物体   
for(std::list<MovableObject*>::iterator iter = QResult.movables.begin();iter != QResult.movables.end();++iter)   
{   
    MovableObject
*   pObject=static_cast<MovableObject*>(*iter);   
    
if(pObject)   
    
{   
        
if(pObject->getMovableType()=="Entity")   
        
{   
            Entity
*   ent   =   static_cast<Entity*>(pObject);   
            
//这里简化了操作,由于只有一个"球体"和一个"正方体",   
              
//所以只判断了球体和正方体的相交   
              if(ent->getName()=="cube")   
            
{   
               
//改变位置防止物体重叠   
                 vtl=-vtl;   
               m_SphereNode
->translate(vtl);   
               
break;   
             }
   
         }
   
     }
   
}
   

  相交查询  
  遍历所有的对象,找到一对一对的相交物体(废话呀,相交当然至少两个物体)。            

//创建相交检测   
IntersectionSceneQuery*   pISQuery=m_SceneMgr->createIntersectionQuery();   
//执行查询   
IntersectionSceneQueryResult   QResult=pISQuery->execute();   
//遍历查询列表找出两个相交的物体   
for(SceneQueryMovableIntersectionList::iterator iter = QResult.movables2movables.begin();iter!=QResult.movables2movables.end();++iter)   
{   
    SceneQueryMovableObjectPair   pObject
=static_cast<SceneQueryMovableObjectPair>(*iter);   
    
//if(pObject)   
    {   
        String   strFirst
=pObject.first->getName();   
        String   strSecond
=pObject.second->getName();   
        
//下面加入你自己的两个物体相交判断代码,或者简单的用AABB的判断方法,   
     }
   
}
   

 

posted @ 2009-08-05 17:35  回忆1919  阅读(1273)  评论(0编辑  收藏  举报