场景查询
创建查询的代价比较大,而执行不是。SceneQueryResualt只定义了两种成员:movables与worldFragments.
掩码也需要自己定义,自己解释。在一个轴对齐盒子中查询灯光的例子如下:
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_QUERY_MASK);
// sometime later in the application's code, find out what lights are in the box
SceneQueryResult& results = lightQuery->execute(); //查询
// iterate through the list of items returned; there should only be one, and it
// should be light2 created above. The list iterator is MovableObject type.
SceneQueryResultMovableList::iterator it = results.movables.begin();
for (; it != results.movables.end(); it++)
{
// act only on the lights, which should be all we have
assert ((*it)->getQueryFlags() & LIGHT_QUERY_MASK) != 0);
// do whatever it was we needed to do with the lights
}
// destroy the query when we are done with it
mSceneMgr->destroyQuery(lightQuery);
我们知道地形总是起伏不平的,当主角在上面行走时需要根据地形的高度调整,可以光线查询来实现。
原理比较简单:向主角脚下执行光线查询,与地形有一个交点,根据交点的高度调整主角位置。
Terrain Clamping
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) {
// then we are under the terrain and need to pop above it
updateRay.setOrigin(m_controlledNode->getPosition());
updateRay.setDirection(Ogre::Vector3::UNIT_Y);
m_raySceneQuery->setRay(updateRay);
}
qryResult = m_raySceneQuery->execute();
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()
{
// lots of other irrelevant entity init stuff goes here
m_raySceneQuery = sm->createRayQuery(
Ogre::Ray(m_controlledNode->getPosition(),
Ogre::Vector3::NEGATIVE_UNIT_Y));
// move this node is such a way that it is above the terrain
clampToTerrain();
}
posted on 2007-03-11 17:24
清源游民 阅读(1141)
评论(0) 编辑 收藏 引用 所属分类:
OGRE