1. 场景查询
轴对称包围盒:立方体,2个对角点
球体:中心、半径
平面包围体:3个及其以上的平面包围的体积
光线:一点引出一条射线,查找与线相交的物体
任意相交:任何相交对象
const unsigned int LIGHT_QUERY_MASK = 0x00000001
Light* light1 = mSceneMgr->createLight(“Light1”);
Light* light2 = mSceneMgr->createLight(“Light2”);
light1->setPosition(12, 12, 12);
light2->setPosition(5, 5, 5);
//设置自定义掩码
light1->setQueryFlags(LIGHT_QUERY_MASK);
light2->setQueryFlags(LIGHT_QUERY_MASK);
AxisAlignedBoxSceneQuery* lightQuery = mSceneMgr->createAABBQuery(
AxisAlignedBox(0,0,0,10,10,10), LIGHT_QUERYMASK);
// 查询空间内所有的灯光。
SceneQueryResult& results = lightQuery->excute();
// 迭代查询结果。
// 迭代器中返回的是活动对象类型指针
SceneQueryResultMovableList::iterator it = results.movalbles.begin();
for(; it != results.moveables.end(); it++)
{
// 检查是否返回的都是灯光
assert(((*it)->getQueryFlags() & LIGHT_QUERY_MASK) != 0);
//在这里加入对灯光的操作。
}
103
// 结束后销毁场景查询实例
mSceneMgr->destroyQuery(lightQuery);
1. 实际运用中,应单独创建一个场景查询结构,查询很快,创建很慢。
2. 需要通过自定义的掩码来确定类型
光线投影查询:给定空间的相交查询
地形跟随:
void Entity::clampToTerrain(){
static Ogre::Ray updateRay;
updateRay.setOrigin(m_controlledNode->getposition() + Ogre::Vector3(0, 15, 0));
updateRay.setDirection(Ogre::Vector3::NeGATIVE_UNIT_Y);
m_raySceneQuery->setRay(updateRay);
Ogre::RaySceneQueryResult& qryResult = m_raySceneQuery->execute();
if (qryResult.size() == 0)
{
//当我们在地形的下面的时候,需要升到地表上面
updateRay.setQrigin(m_controlledNode->getPosition());
updateRay.setDirection(Ogre::Vector3::UNIT_Y);
m_raySceneQuery->setRay(updateRay);
qryResult = m_rayScenQuery->execute();
}
104
Ogre::RaySceneQueryResult::iterator i = qryResult.begin();
if( i != qryResult.end() && i->worldFragment)
{
Ogre::SceneQuery::WorldFragment* wf = i->worldFragment;
m_controlledNode->setPosition(m_controlledNode->getPosition().x,
i->worldFragment->singleIntersection.y,
m_controlledNode->getPosition().z);
}
}
void Entity::init()
{
// 创建光线查询
m_raySceneQuery = sm->createRayQuery(
Ogre::Ray(m_controlledNode->getPosition(),
Ogre::Vector3::NEGATIVE_UNIT_Y);
// 把这个节点移动到贴紧地表的位置
clampToTerrain();
}
首先向下检查交点,如果没有,向上检查,再设置节点位置到紧贴地面的地方。
在代码中通过每一帧调用 clampToTerrain()来实现更新。