//本代碼 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;
}