#include "OGRE/Ogre.h"
#include "OIS/OIS.h"
class MyFrameListener:public Ogre::FrameListener
{
public:
bool frameStarted(const Ogre::FrameEvent &evt)
{
//std::cout<<"Frame Start"<<std::endl;
bool walked = false;
Ogre::Vector3 SinbadTranslate(0,0,0);
_key->capture();
if (_key->isKeyDown(OIS::KC_ESCAPE))
{
return false;
}
Ogre::Vector3 translate(0,0,0);
if(_key->isKeyDown(OIS::KC_W))
{
translate += Ogre::Vector3(0,0,-10);
}
if(_key->isKeyDown(OIS::KC_S))
{
translate += Ogre::Vector3(0,0,10);
}
if(_key->isKeyDown(OIS::KC_A))
{
translate += Ogre::Vector3(-10,0,0);
}
if(_key->isKeyDown(OIS::KC_D))
{
translate += Ogre::Vector3(10,0,0);
}
if(_key->isKeyDown(OIS::KC_UP))
{
SinbadTranslate += Ogre::Vector3(0,0,-1);
_rotation = 0.0f;
walked = true;
}
if(_key->isKeyDown(OIS::KC_DOWN))
{
SinbadTranslate += Ogre::Vector3(0,0,1);
_rotation = 3.14f;
walked = true;
}
if(_key->isKeyDown(OIS::KC_LEFT))
{
SinbadTranslate += Ogre::Vector3(-1,0,0);
_rotation = 1.57f;
walked = true;
}
if(_key->isKeyDown(OIS::KC_RIGHT))
{
SinbadTranslate += Ogre::Vector3(1,0,0);
_rotation = -1.57f;
walked = true;
}
if (walked)
{
_aniStateBase->setEnabled(true);
//_aniStateTop->setEnabled(true);
_aniStateIdle->setEnabled(false);
if (_aniStateBase->hasEnded())
{
_aniStateBase->setTimePosition(0.0f);
}
/*if (_aniStateTop->hasEnded())
{
_aniStateTop->setTimePosition(0.0f);
} */
}
else
{
_aniStateBase->setEnabled(false);
//_aniStateTop->setEnabled(false);
_aniStateIdle->setEnabled(true);
_aniStateBase->setTimePosition(0.0f);
//_aniStateTop->setTimePosition(0.0f);
}
if (_mouse->getMouseState().buttonDown(OIS::MB_Left))
{
_aniStateSword->setEnabled(true);
if (_aniStateSword->hasEnded()) //关闭动作循环再加上这个,终于只挥一次刀了
{
_aniStateSword->setTimePosition(0.0f);
}
}
if (_key->isKeyDown(OIS::KC_LSHIFT))
{
_movementSpeed = 100.0f;
}
_cam->moveRelative(translate*evt.timeSinceLastFrame * _movementSpeed);
_mouse->capture();
float rotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame * -1;
float rotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;
_cam->yaw(Ogre::Radian(rotX));
_cam->pitch(Ogre::Radian(rotY));
//_sinbadNode->setPosition(_cam->getPosition()+translate);
_aniStateBase->addTime(evt.timeSinceLastFrame); //运动自从上一次更新到现在已经过去多长时间
//_aniStateTop->addTime(evt.timeSinceLastFrame); //不使用这个函数的话,动作是不会播放的
_aniStateIdle->addTime(evt.timeSinceLastFrame);
_aniStateSword->addTime(evt.timeSinceLastFrame);
_sinbadNode->translate(SinbadTranslate * evt.timeSinceLastFrame * _WalkingSpeed);
_sinbadNode->resetOrientation(); //重置旋转,因为我们要的是绝对的旋转而不是相对的旋转
_sinbadNode->yaw(Ogre::Radian(_rotation));
_camPivot->setPosition(_sinbadNode->getPosition()+Ogre::Vector3(0,30,0));
_camNode->setPosition(_camPivot->getPosition()+((Ogre::SceneNode*)_camPivot->getChild("mCameraGoal"))->getPosition());
return true;
}
bool frameEnded(const Ogre::FrameEvent& evt)
{
//std::cout<<"Frame End"<<std::endl;
return true;
}
bool frameRenderingQueued(const Ogre::FrameEvent& evt)
{
//std::cout<<"Frame Queued"<<std::endl;
return true;
}
MyFrameListener(Ogre::RenderWindow* win, Ogre::Camera* cam, Ogre::Viewport* viewport, Ogre::SceneNode* sinbadNode)
{
_sinbadNode = sinbadNode;
_camPivot = (Ogre::SceneNode*)cam->getSceneManager()->getRootSceneNode()->getChild("mCameraPivot");
_camNode = (Ogre::SceneNode*)cam->getSceneManager()->getRootSceneNode()->getChild("mCameraNode");
//暂时不知道怎么从节点中调用实体,放弃
_ent = (Ogre::Entity*)sinbadNode->getAttachedObject("Sinbad");
//_ent = ent;
_cam = cam;
_movementSpeed = 50.0f;
OIS::ParamList pl;
unsigned int windowHandle = 0;
std::ostringstream windowHandleStr; //该类通常用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf
win->getCustomAttribute("WINDOW",&windowHandle);
windowHandleStr << windowHandle; //格式化
pl.insert(std::make_pair("WINDOW",windowHandleStr.str()));
_man = OIS::InputManager::createInputSystem(pl);
_key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard,false));
_mouse = static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse,false));
_viewport = viewport;
_comp1 = false;
_comp2 = false;
_comp3 = false;
_down1 = false;
_down2 = false;
_down3 = false;
_aniStateIdle = _ent->getAnimationState("Idle3");
_aniStateIdle->setEnabled(true);
_aniStateIdle->setLoop(true);
_aniStateBase = _ent->getAnimationState("Walk"); //从实体中获取动作指针
_aniStateBase->setEnabled(false); //是否可用
_aniStateBase->setLoop(false); //是否循环
/*_aniStateTop = _ent->getAnimationState("RunTop");
_aniStateTop->setEnabled(false);
_aniStateTop->setLoop(false); */
_aniStateSword = _ent->getAnimationState("Attack3");
//_aniStateSword->getLength();
_aniStateSword->setLoop(false);
_WalkingSpeed = 50.0f;
_rotation = 0.0f;
//_sinbadNode->attachObject(_cam);
}
~MyFrameListener()
{
_man->destroyInputObject(_key);
_man->destroyInputObject(_mouse);
OIS::InputManager::destroyInputSystem(_man);
}
private:
OIS::InputManager* _man;
OIS::Keyboard* _key;
OIS::Mouse* _mouse;
Ogre::Camera* _cam;
float _movementSpeed;
Ogre::Viewport* _viewport;
bool _comp1, _comp2, _comp3;
bool _down1, _down2, _down3;
Ogre::SceneNode* _sinbadNode;
float _WalkingSpeed; //控制走路的速度
float _rotation; //控制旋转
Ogre::Entity* _ent; //想要运动的实体
Ogre::AnimationState* _aniStateBase; //运动状态指针
Ogre::AnimationState* _aniStateTop;
Ogre::AnimationState* _aniStateIdle;
Ogre::AnimationState* _aniStateSword;
Ogre::SceneNode* _camPivot;
Ogre::SceneNode* _camNode;
};
class MyApplication
{
private:
Ogre::SceneManager* _sceneManager; //场景管理器
Ogre::Root* _root; //根节点
Ogre::SceneNode* _sinbadNode;
MyFrameListener* _listener;
bool _keepRunning;
Ogre::Entity* _ent;
Ogre::SceneNode* mCameraPivot;
Ogre::SceneNode* mCameraGoal;
Ogre::SceneNode* mCameraNode;
public:
//载入资源
void loadResources()
{
Ogre::ConfigFile cf; //助手类,用于加载配置文件
cf.load("resources_d.cfg"); //载入配置文件
Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator();//得到一个遍历块的迭代器
Ogre::String sectionName, typeName, dataname; //块名,键,值
//开始通过迭代器遍历资源
while (sectionIter.hasMoreElements())
{
sectionName = sectionIter.peekNextKey(); //得到块
Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext(); //得到map
Ogre::ConfigFile::SettingsMultiMap::iterator i; //定义一个map的迭代器
for (i = settings->begin(); i != settings->end(); ++i) //对块里头的键-值进行迭代
{
typeName = i->first; //获得键
dataname = i->second; //获得值
//根据块,键,值来载入资源
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname, typeName, sectionName);
}
}
//初始化所有的资源组
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
//创建场景
void createScene()
{
_ent = _sceneManager->createEntity("Sinbad","ninja.mesh");
_sinbadNode = _sceneManager->getRootSceneNode()->createChildSceneNode("SinbadNode",Ogre::Vector3::UNIT_Y*5);
_sinbadNode->attachObject(_ent);
_sinbadNode->setScale(0.1f,0.1f,0.1f);
_sinbadNode->setPosition(Ogre::Vector3(0,-10,0));
//定义平面
Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -10);
Ogre::MeshManager::getSingleton().createPlane("plane",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,1500,1500,200,200,true,1,5,5,Ogre::Vector3::UNIT_Z);
//平面实体化,并作为场景根节点的子节点
Ogre::Entity* ent = _sceneManager->createEntity("LightPlaneEntity", "plane");
_sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
ent->setMaterialName("Examples/BeachStones");
//定义个灯光
Ogre::Light* light = _sceneManager->createLight("light1");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(Ogre::Vector3(1,-1,0));
//_sceneManager->setShadowTechnique();
}
//开始渲染,该函数的一切似乎只是初始化
int startup()
{
_root = new Ogre::Root("plugins_d.cfg"); //载入插件
if(!_root->showConfigDialog()) //弹出黑框框,如果出错或者用户点取消则返回
{
return -1;
}
//通过root,初始化-----渲染窗口和场景管理器
Ogre::RenderWindow* window = _root->initialise(true,"Ogre3D Beginners Guide");
_sceneManager = _root->createSceneManager(Ogre::ST_GENERIC);
//天空盒资源暂时还不知道如何载入,所以不能调用天空盒
//_sceneManager->setSkyBox(true, "Examples/SpaceSkyBox", 50 );
//通过场景管理器实例化------摄像头
Ogre::Camera* camera = _sceneManager->createCamera("Camera");
camera->setPosition(Ogre::Vector3(0,0,50));
camera->lookAt(Ogre::Vector3(0,0,0));
camera->setNearClipDistance(5);
//camera->setFixedYawAxis(true);
//通过渲染窗口和摄像机实例化------视口
Ogre::Viewport* viewport = window->addViewport(camera);
viewport->setBackgroundColour(Ogre::ColourValue(0.0,0.0,0.0)); //设置视口为黑色
camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight()));
//放置摄像机
mCameraPivot = camera->getSceneManager()->getRootSceneNode()->createChildSceneNode("mCameraPivot");
mCameraGoal = mCameraPivot->createChildSceneNode("mCameraGoal",Ogre::Vector3(0, 0, 15));
mCameraNode = camera->getSceneManager()->getRootSceneNode()->createChildSceneNode("mCameraNode");
mCameraNode->setPosition(mCameraPivot->getPosition() + mCameraGoal->getPosition());
camera->setNearClipDistance(0.1);
camera->setFarClipDistance(2000);
mCameraNode->attachObject(camera);
loadResources(); //载入资源
createScene(); //画画
_listener = new MyFrameListener(window,camera,viewport,_sinbadNode);
_root->addFrameListener(_listener);
//打印所有动作
Ogre::AnimationStateSet* set = _ent->getAllAnimationStates();
Ogre::AnimationStateIterator iter = set->getAnimationStateIterator();
while(iter.hasMoreElements())
{
std::cout << iter.getNext()->getAnimationName() << std::endl;
}
//因为剧情需要,把startRendering注释了╮(╯▽╰)╭
//_root->startRendering(); //开始渲染,因为我们给了root很多东西,他就在他的循环里头自己玩了,不会返回
return 0;
}
void renderOneFrame()
{
Ogre::WindowEventUtilities::messagePump();
_keepRunning = _root->renderOneFrame();
}
bool keepRunning()
{
return _keepRunning;
}
MyApplication()
{
_sceneManager = NULL;
_root = NULL;
_listener = NULL;
}
~MyApplication()
{
delete _root;
delete _listener;
}
};
int main()
{
/* Ogre::Root* root = new Ogre::Root("plugins_d.cfg");
if (!root->showConfigDialog())
{
return -1;
}
Ogre::RenderWindow* window = root->initialise(true,"Ogre3D Beginners Guide");
Ogre::SceneManager* sceneManager = root->createSceneManager(Ogre::ST_GENERIC);
Ogre::Camera* camera = sceneManager->createCamera("Camera");
camera->setPosition(0,0,50);
camera->lookAt(0,0,0);
camera->setNearClipDistance(5);
Ogre::Viewport* viewport = window->addViewport(camera);
viewport->setBackgroundColour(Ogre::ColourValue(0,0,0));
camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight()));
Ogre::ConfigFile cf;
cf.load("resources_d.cfg");
Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator(); //迭代器好像都不是指针
Ogre::String sectionName, typeName, dataname;
while (sectionIter.hasMoreElements())
{
sectionName = sectionIter.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
dataname = i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname,typeName,sectionName);
}
}
//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../Media/packs/Sinbad.zip","Zip");
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
Ogre::Entity* ent = sceneManager->createEntity("Sinbad.mesh");
sceneManager->getRootSceneNode()->attachObject(ent);
root->startRendering();*/
MyApplication app;
app.startup();
while(app.keepRunning())
{
app.renderOneFrame();
}
return 0;
}