80后应该对CS游戏十分熟悉,键盘上WSAD键估计多数已字迹模糊。除了轨迹球外,个人最喜欢CS模式操作器,我不知道这种操作器叫什么中文名字,第一人称射击游戏操作器有些繁琐,就暂时叫CS操作器吧。在OSG2.8.0后的某个版本,出现了这个FirstPersonManipulator,但是稀奇的是代码里有
/// Move camera right by distance parameter.
void FirstPersonManipulator::moveRight( const double distance )
{
assert( 0 && "Not implemented yet." );
}
直到最新版本,这个还是Not implemented yet。呵呵,既然人家不implemented ,那就自己来吧。估计作者对这个操作器有很高的期望值,想做的完美,所以暂时没有实现。我在这里先替作者完成个初稿吧,当然不完美,期待电脑前的您把它做的完美。我在办公室的计算机里对这个操作器做了很详细的改进,可恶的是无法导出,所以不能和大家分享成果,实在是遗憾,今天利用2个多小时的时间,整理思路,又重新在家里做了一次,由于时间短只对重要的部分进行了梳理,并写出来粗糙的文档,请原谅这粗糙的文字。
现在是凌晨2:40,写完就不知道几点啦,老婆孩子0点睡了。我写程序在家是被禁止的,所以只能等老婆孩子睡熟了才能偷爬起来干。
---------------------------------------------------------------------正事开始------------------------------------------------------------------------------------
第一步,你需要最新版的OSG源代码,并编译通过,记得要编译示例程序。因为要用其中某些程序来测试修改后的操作器。
第二步,修改osgGA部分的一些代码,重新编译osgGA。
第三步,修改示例程序中的osgPick代码,把FirstPersonManipulator填进去,重新编译,用来测试修改效果。
第四步,运行osgPick,感受CS的操作体验,记得把osg的数据模型文件拷贝到与osgPick.exe同一目录。
现在开始详细的说明步骤。
打开vc2005,别的版本也可以。修改FirstPersonManipulator.cpp,将
/// Move camera right by distance parameter.
void FirstPersonManipulator::moveRight( const double distance )
{
assert( 0 && "Not implemented yet." );
}
修改为,
/// Move camera right by distance parameter.
void FirstPersonManipulator::moveRight( const double distance )
{
_eye += _rotation * Vec3d( distance, 0., 0. );
}
至于为什么,我暂时先不解释,以后的教程里会详细介绍相关的数学知识。
在FirstPersonManipulator.h文件里添加
virtual bool handleKeyDown( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
最好添加在protected:段落里。
在FirstPersonManipulator.cpp添加
/// Handles GUIEventAdapter::KEYDOWN event.
bool FirstPersonManipulator::handleKeyDown( const GUIEventAdapter& ea, GUIActionAdapter& us )
{
if( ea.getKey() == GUIEventAdapter::KEY_Space )
{
flushMouseEventStack();
_thrown = false;
home(ea,us);
return true;
}
if( ea.getKey() == 'w' )
{
moveForward(5.0);
return true;
}
if( ea.getKey() == 's' )
{
moveForward(-5.0);
return true;
}
if( ea.getKey() == 'a' )
{
moveRight(-5.0);
return true;
}
if( ea.getKey() == 'd' )
{
moveRight(5.0);
return true;
}
return false;
}
生成osgGA。
在osgPick的代码里添加
keyswitchManipulator->addMatrixManipulator( '5', "fps", new osgGA::FirstPersonManipulator() );
记住,在