Ogre的BSP地图和简单机器人动作控制实例

 

//本代码 BSP地图 简单 机器人动作控制

#include <Ogre.h>   //OGRE主文件
#include <OIS/OIS.h> //输入控制文件

#include "ExampleFrameListener.h" //监听类

using namespace Ogre;     //使用 命名空间
SceneManager* sceneMgr;    //主场景 管理器 对象
Camera*    cam;     //主摄像机 对象
RenderWindow* window;     //渲染 窗口 对象
String mQuakeLevel;     //BSP地图 配置文件路径

class myFrameListener : public ExampleFrameListener
{
public:
myFrameListener(RenderWindow* wnd, Camera* cams,SceneNode *nodes,SceneNode *camnode) : ExampleFrameListener(wnd,cams,false,false),
   mNode(nodes),mCamnode(camnode),mChildnode(0),mEntity(0),mAnimationState(0),mStarstate(true)
{
   //移动速度
   mMoveSpeed = 200;
   //showDebugOverlay(false);
   //读取模型动画
   AnimationStar();
   //设置动画是否循环播放
   if (mAnimationState)
   {
    mAnimationState->setLoop(true);
    mAnimationState2->setLoop(true);
   }
}
~myFrameListener()
{

}

bool frameRenderingQueued(const FrameEvent& evt)
{

   //如果窗口被关闭 则 退出
   if(mWindow->isClosed()) return false;

   mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;

   //获取 键盘鼠标 状态
   mKeyboard->capture();
   mMouse->capture();
   if( mJoy ) mJoy->capture();

   bool buffJ = (mJoy) ? mJoy->buffered() : true;

   //Ogre::Vector3 lastMotion = mTranslateVector;

   if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
   {
    if (mTimeUntilNextToggle >= 0)
     mTimeUntilNextToggle -= evt.timeSinceLastFrame;

    mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
    mRotScale = mRotateSpeed * evt.timeSinceLastFrame;

    mRotX = 0;
    mRotY = 0;
    //无输入 则 初始化 人物移动 变量
    mTranslateVector = Ogre::Vector3::ZERO;

   }

   //调用键盘 鼠标 控制函数
   if( !mKeyboard->buffered() )
    if( processUnbufferedKeyInput(evt) == false )
     return false;
   if( !mMouse->buffered() )
    if( processUnbufferedMouseInput(evt) == false )
     return false;

   //如果人物移动中
   if (mTranslateVector == Ogre::Vector3::ZERO)
   {
    mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;
    //mTranslateVector = lastMotion;
   
    if(mStarstate)//动作控制
    {
     mAnimationState->setEnabled(true);
     mAnimationState2->setEnabled(false);
     mStarstate = false;
    }
    //动作速度控制
    mAnimationState->addTime(evt.timeSinceLastFrame);
   }
   else//人物静止中
   {
    if (!mStarstate)//动作控制
    {
     mAnimationState2->setEnabled(true);
     mAnimationState->setEnabled(false);
     mStarstate = true;
    }
    mCurrentSpeed += evt.timeSinceLastFrame;
    //动作速度控制
    mAnimationState2->addTime(evt.timeSinceLastFrame);
   }
   if (mCurrentSpeed > 1.0)
    mCurrentSpeed = 1.0;
   if (mCurrentSpeed < 0.0)
    mCurrentSpeed = 0.0;

   mTranslateVector *= mCurrentSpeed;

   //如果 键盘或鼠标 被使用 则调用函数
   if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
    moveCamera();

  
   return true;
}

//移动人物与摄像机
void moveCamera()
{
   mNode->yaw(mRotX);
   mCamnode->pitch(mRotY);
   mNode->translate(mTranslateVector,Node::TS_LOCAL);

}
//获取模型动作
void AnimationStar()
{
   //获得第一子节点(挂钩模型节点)
   mChildnode = static_cast<SceneNode*>(mNode->getChild(0));
   //获得模型
   mEntity = static_cast<Entity*>(mChildnode->getAttachedObject(0));

   //获取模型所以动作
   mAnimationStateSet = mEntity->getAllAnimationStates();
   //载入动作到MAP数据结构中
   if (mAnimationStateSet)
   {
    AnimationStateIterator mitr = mAnimationStateSet->getAnimationStateIterator();
    while (mitr.hasMoreElements())//到结尾 返回false 否则返回ture
    {
     AnimationState *anistate = mitr.getNext();
     //插入一条数据
     mAnimationmap.insert( make_pair(anistate->getAnimationName(),anistate) );
    }

   }
   //查找 读取 动作
   if (!mAnimationmap.empty())
   {
    mAnmapit = mAnimationmap.find("Idle");
    if (mAnmapit != mAnimationmap.end())
     mAnimationState = mAnmapit->second;
    mAnmapit = mAnimationmap.find("Walk");
    if (mAnmapit != mAnimationmap.end())
     mAnimationState2 = mAnmapit->second;
   }

}
protected:
SceneNode *mNode,*mCamnode,*mChildnode;
Entity *mEntity;
AnimationStateSet *mAnimationStateSet;
AnimationState *mAnimationState,*mAnimationState2;
std::map<String,AnimationState*> mAnimationmap;
std::map<String,AnimationState*>::iterator mAnmapit;
bool mStarstate;
Real mStargap;
private:

};
//初始化函数
void Create_Game(void)
{
//摄像机剪切最远距离
cam->setFarClipDistance(4000);
//摄像机禁止Z轴转动
cam->setFixedYawAxis(true, Vector3::UNIT_Z);
ViewPoint vp = sceneMgr->getSuggestedViewpoint(true);

/*
创建 场景节点 以及挂钩对象
    root
    |
     nodec1
     /    \
   nodea1 nodec1c1
    /    \
[entity] nodec1c1c1
      \
      [Camera]
*/
SceneNode *node = sceneMgr->getRootSceneNode()->createChildSceneNode("nodec1",vp.position);
node->pitch(Degree(90));
Entity *entity = sceneMgr->createEntity("entity2","robot.mesh");
SceneNode *nodec1 = node->createChildSceneNode("nodea1");
//绑定 对象
nodec1->attachObject(entity);
//旋转90度
nodec1->yaw(Degree(90));
node->scale(0.5,0.5,0.5);

SceneNode *nodec1c1 = node->createChildSceneNode("nodec1c1");
SceneNode *nodec1c1c1 = nodec1c1->createChildSceneNode("nodec1c1c1",Vector3(0, 100, 200));
nodec1c1c1->attachObject(cam);
cam->setAutoTracking(true,nodec1,Vector3(0,0,30));

/*
// 设置关键帧之间的插值方法为样条插值
Animation::setDefaultInterpolationMode(Animation::IM_SPLINE);
// 得到实体“走”动作的AnimationState类对象
mAnimState = nodec1->getAnimationState("Walk");
// “Enable”(起始)该动作
mAnimState->setEnabled(true);
*/


}

//加载资源配置文件
void setupResources(void)
{
// 加载配置文件
ConfigFile cf;
cf.load("resources.cfg");

// 读配置文件 的 组迭代器(用于读取整组内容)
ConfigFile::SectionIterator seci = cf.getSectionIterator();

String secName, typeName, archName;
while (seci.hasMoreElements())
{
   //读取配置文件 KEY 键名(循环读取各组)
   secName = seci.peekNextKey();
   ConfigFile::SettingsMultiMap *settings = seci.getNext();
   ConfigFile::SettingsMultiMap::iterator i;
   //循环读取 每组内 的内容
   for (i = settings->begin(); i != settings->end(); ++i)
   {
    //i 为 make_pair 类型
    typeName = i->first;
    archName = i->second;
    //添加 资源路径 资源类型 资源名 到 资源组管理器
    ResourceGroupManager::getSingleton().addResourceLocation(
     archName, typeName, secName);
   }
}

//读取 BSP 地图 配置文件
cf.load("quake3settings.cfg");

//指向地图文件的压缩包
String mQuakePk3;
mQuakePk3 = cf.getSetting("Pak0Location");
//压缩包内的路径
mQuakeLevel = cf.getSetting("Map");
添加 资源包路径 类型 到 资源组管理器
ResourceGroupManager::getSingleton().addResourceLocation(
   mQuakePk3, "Zip", ResourceGroupManager::getSingleton().getWorldResourceGroupName(), true);
}

void loadResources(void)
{
//创建地图
//sceneMgr->setWorldGeometry(mQuakeLevel);


// Turn off rendering of everything except overlays
sceneMgr->clearSpecialCaseRenderQueues();
sceneMgr->addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
sceneMgr->setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);

// Set up the world geometry link
ResourceGroupManager::getSingleton().linkWorldGeometryToResourceGroup(
   ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
   mQuakeLevel, sceneMgr);

// Initialise the rest of the resource groups, parse scripts etc
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
ResourceGroupManager::getSingleton().loadResourceGroup(
   ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
   false, true);

// Back to full rendering
sceneMgr->clearSpecialCaseRenderQueues();
sceneMgr->setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);


}

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
//创建日志管理
LogManager* logMgr = new LogManager;
Log* log1 = logMgr->getSingleton().createLog("mylog.log", true, true, false);
//创建主对象
Root* root = new Root();
//读入资源文件配置
setupResources();
//显示Ogre配置对话框
if(!root->showConfigDialog()) return 0;
//初始化 ROOT主对象 并创建窗口
window = root->initialise(true,"love mnn");

//创建 场景管理器
sceneMgr = root->createSceneManager("BspSceneManager");
//创建 摄像机
cam = sceneMgr ->createCamera("MainCamera");
//设置摄像机位置 Z 500
//cam->setPosition(Vector3(0,0,0));
//摄像机视点 Z -300
//cam->lookAt(Vector3(0,0,-300));
//设置 临近 距离
cam->setNearClipDistance(5);
//创建 视口 绑定摄像机
Viewport* vp = window->addViewport(cam);
//设置背景颜色
vp->setBackgroundColour(ColourValue(1,1,1));
//设置摄像机屏幕比例 cam->setAspectRatio(1.333333);4:3 1.77777 16:9
cam->setAspectRatio(
   Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
//创建纹理管理
TextureManager::getSingleton().setDefaultNumMipmaps(5);
//创建资源管理加载资源
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

loadResources();
//功能实现函数
Create_Game();

//创建监听对象
myFrameListener* myListener = new myFrameListener( window, cam ,sceneMgr->getSceneNode("nodec1"),sceneMgr->getSceneNode("nodec1c1"));
//关闭FPS提示框
//myListener->showDebugOverlay(false);
//在这里你需要在调用startRendering()方法前,注册你的帧监听对象!!!
root->addFrameListener(myListener);
//开始渲染
root->startRendering();

if (myListener)
   delete myListener;
if (root)
   delete root;

return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值