Я выбрал плагин oFusion, т.к. у него нет ни каких ограничений в отличие от OgreMax. Качайте отсюда
http://www.ofusiontechnologies.com/o...on_ce_1.86.exe
Для его использования понадобится макс не выше 9 версии.
Далее качаем архив с загрузчиком (в аттаче).
Создаем проект, настраиваем (вы должны уже это уметь).
Распаковываем OSM.zip в каталог с исходниками. Из этих папок все cpp файлы перетаскиваем в проект. В проекте подключаем файлы
#include "OSM\OgreOSMScene.h"
#include "OSM\IOSMSceneCallbacks.h"
Сделаем например сценку, и игрока, который будет по ней перемещаться.
Создаем сцену в максе, экспортируем в OSM (меню oFusion->Export Scene), и создаем отдельно игрока, при экспорте снимаем галку экспортировать сцену, тогда он отэкспортирует только модель.
Все это ложим в какой нибудь каталог, и настраиваем на него resources.cfg.
В createScene прописываем загрузку сцены
oScene = new OSMScene();//создаем экземпляр класса oFusion сцены
oSceneCallback oe_Callback;//создаем перехватчик событий
oScene->initialise("level_01.osm", &oe_Callback);//загружаем сцену
oScene->createScene();//создание сцены из загруженных данных
mSceneMgr = oScene->getSceneManager();//получить огровский указатель на сцену
OSMScene::CameraList camList = oScene->getCameraList();//получить список камер
if(!camList.empty()) {//если есть камеры делаем первую текущей
mCamera = camList[0];
}
Нужно создать класс, который будет перехватывать события создания ентити. Я в максе создал бокс с именем player, на его месте я поставлю игрока, а бокс удалю.
Вот код класса перехватчика
class oSceneCallback : public OSMSceneCallbacks {
public:
void OnNodeCreate(Ogre::SceneNode* pNode, TiXmlElement* pNodeDesc)//проверяем все создаваемые узлы
{
if(pNode->getName() == "player")//если находится узел с именем player
{
player = new CCommando(oScene->getSceneManager(), pNode->getPosition());//создаем класс игрока
CDeleteAfterCreate::AddNode(oScene->getSceneManager(),pNode);//а бокс добавляем в удалятор
}
}
void OnCameraCreate(Ogre::Camera* pCamera, TiXmlElement* pCameraDesc) {//стандартные действия с камерой
if(pCamera->getName() == "Camera01")
Ogre::Root::getSingleton().getAutoCreatedWindow()->getViewport(0)->setCamera(pCamera);
}
};
код класса игрока и удалятора
class CCommando : public Ogre::FrameListener
{
public:
Ogre::Entity* body;
Ogre::SceneNode* node;
Ogre::AnimationState* currentAnimation;
OIS::InputManager* _man;
OIS::Keyboard* _key;
Ogre::String animName;
CCommando(Ogre::SceneManager *mSceneMgr, Ogre::Vector3 pos = Ogre::Vector3::ZERO) : Ogre::FrameListener()
{
body = mSceneMgr->createEntity("commando.mesh");//загружаем модель
node = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos);//ставим узел в то место где был бокс
node->attachObject(body);
Ogre::Root::getSingletonPtr()->addFrameListener(this);
animationStop();//не анимируем
createOIS();
}
void animationRun()//функция запуска анимации бега
{
if(animName == "stop")//если стоим
{
currentAnimation = body->getAnimationState("run");
currentAnimation->setEnabled(true);
currentAnimation->setLoop(true);
}
animName = "run";
}
void animationStop()//функция остановки анимации вообще
{
if(animName == "run")
{
currentAnimation->setEnabled(false);
}
currentAnimation = NULL;
animName = "stop";
}
bool frameStarted(const Ogre::FrameEvent &evt)
{
if(currentAnimation != NULL) currentAnimation->addTime(evt.timeSinceLastFrame);
_key->capture();//обновляем состояние клавиатуры
if(_key->isKeyDown(OIS::KC_ESCAPE))
{
return false;//если ESC то выйти из приложения
}
bool run = false;//временная переменная состояния игрока
Ogre::Vector3 vec = Ogre::Vector3::ZERO;
if(_key->isKeyDown(OIS::KC_UP))//если мы нажимаем клавиши управления игроком, изменяем его состояние
{
vec += Ogre::Vector3(0,0,-1);
node->resetOrientation();
node->yaw(Ogre::Degree(180));
run = true;
}
if(_key->isKeyDown(OIS::KC_DOWN))
{
vec += Ogre::Vector3(0,0,1);
node->resetOrientation();
node->yaw(Ogre::Degree(0));
run = true;
}
if(_key->isKeyDown(OIS::KC_LEFT))
{
vec += Ogre::Vector3(-1,0,0);
node->resetOrientation();
node->yaw(Ogre::Degree(-90));
run = true;
}
if(_key->isKeyDown(OIS::KC_RIGHT))
{
vec += Ogre::Vector3(1,0,0);
node->resetOrientation();
node->yaw(Ogre::Degree(90));
run = true;
}
//применяем состояние игрока
node->translate(vec*(evt.timeSinceLastFrame*50),Ogre::SceneNode::TS_PARENT);
if(run)
{
animationRun();
}
else
{
animationStop();
}
return true;
}
~CCommando()
{
_man->destroyInputObject(_key);
OIS::InputManager::destroyInputSystem(_man);
}
private:
void createOIS()//настройка клавиатуры (из книги, все стандартно)
{
size_t windowHnd = 0;
std::stringstream windowHndStr;
win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
OIS::ParamList pl;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
_man = OIS::InputManager::createInputSystem( pl );
_key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard, false ));
}
};
class CDeleteAfterCreate : public Ogre::FrameListener//код удалятора
//он нужен, что бы удалить не нужный узел player и т.п. после создания сцены. Во время создания сцены его удалить нельзя, так устроен OSM загрузчик.
{
public:
static void AddNode(Ogre::SceneManager *_mSceneMgr, Ogre::SceneNode* _node)//статическая функция, для удобства
{
CDeleteAfterCreate *ac = new CDeleteAfterCreate(_mSceneMgr, _node);
}
Ogre::SceneNode* node;
Ogre::SceneManager *mSceneMgr;
CDeleteAfterCreate(Ogre::SceneManager *_mSceneMgr, Ogre::SceneNode* _node) : Ogre::FrameListener()
{
node = _node;
mSceneMgr = _mSceneMgr;
Ogre::Root::getSingleton().addFrameListener(this);
}
bool frameStarted(const Ogre::FrameEvent &evt)
{
mSceneMgr->destroySceneNode(node);//удаляем узел
Ogre::Root::getSingleton().removeFrameListener(this);//убираем фрейм листенер, он уже не нужен
return true;
}
};
Как то так.
Вот, что у меня получилось:
Исходный код:
#include <OGRE\ExampleApplication.h>
#include "OSM\OgreOSMScene.h"
#include "OSM\IOSMSceneCallbacks.h"
#pragma comment(lib,"OgreMain_d.lib")
#pragma comment(lib,"OIS_d.lib")
class CCommando;
OSMScene* oScene;
CCommando* player;
Ogre::RenderWindow* win;
class CCommando : public Ogre::FrameListener
{
public:
Ogre::Entity* body;
Ogre::SceneNode* node;
Ogre::AnimationState* currentAnimation;
OIS::InputManager* _man;
OIS::Keyboard* _key;
Ogre::String animName;
CCommando(Ogre::SceneManager *mSceneMgr, Ogre::Vector3 pos = Ogre::Vector3::ZERO) : Ogre::FrameListener()
{
body = mSceneMgr->createEntity("commando.mesh");
node = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos);
node->attachObject(body);
Ogre::Root::getSingletonPtr()->addFrameListener(this);
animationStop();
createOIS();
}
void animationRun()
{
if(animName == "stop")
{
currentAnimation = body->getAnimationState("run");
currentAnimation->setEnabled(true);
currentAnimation->setLoop(true);
}
animName = "run";
}
void animationStop()
{
if(animName == "run")
{
currentAnimation->setEnabled(false);
}
currentAnimation = NULL;
animName = "stop";
}
bool frameStarted(const Ogre::FrameEvent &evt)
{
if(currentAnimation != NULL) currentAnimation->addTime(evt.timeSinceLastFrame);
_key->capture();
if(_key->isKeyDown(OIS::KC_ESCAPE))
{
return false;
}
bool run = false;
Ogre::Vector3 vec = Ogre::Vector3::ZERO;
if(_key->isKeyDown(OIS::KC_UP))
{
vec += Ogre::Vector3(0,0,-1);
node->resetOrientation();
node->yaw(Ogre::Degree(180));
run = true;
}
if(_key->isKeyDown(OIS::KC_DOWN))
{
vec += Ogre::Vector3(0,0,1);
node->resetOrientation();
node->yaw(Ogre::Degree(0));
run = true;
}
if(_key->isKeyDown(OIS::KC_LEFT))
{
vec += Ogre::Vector3(-1,0,0);
node->resetOrientation();
node->yaw(Ogre::Degree(-90));
run = true;
}
if(_key->isKeyDown(OIS::KC_RIGHT))
{
vec += Ogre::Vector3(1,0,0);
node->resetOrientation();
node->yaw(Ogre::Degree(90));
run = true;
}
node->translate(vec*(evt.timeSinceLastFrame*50),Ogre::SceneNode::TS_PARENT);
if(run)
{
animationRun();
}
else
{
animationStop();
}
return true;
}
~CCommando()
{
_man->destroyInputObject(_key);
OIS::InputManager::destroyInputSystem(_man);
}
private:
void createOIS()
{
size_t windowHnd = 0;
std::stringstream windowHndStr;
win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
OIS::ParamList pl;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
_man = OIS::InputManager::createInputSystem( pl );
_key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard, false ));
}
};
class CDeleteAfterCreate : public Ogre::FrameListener
{
public:
static void AddNode(Ogre::SceneManager *_mSceneMgr, Ogre::SceneNode* _node)
{
CDeleteAfterCreate *ac = new CDeleteAfterCreate(_mSceneMgr, _node);
}
Ogre::SceneNode* node;
Ogre::SceneManager *mSceneMgr;
CDeleteAfterCreate(Ogre::SceneManager *_mSceneMgr, Ogre::SceneNode* _node) : Ogre::FrameListener()
{
node = _node;
mSceneMgr = _mSceneMgr;
Ogre::Root::getSingleton().addFrameListener(this);
}
bool frameStarted(const Ogre::FrameEvent &evt)
{
mSceneMgr->destroySceneNode(node);
Ogre::Root::getSingleton().removeFrameListener(this);
return true;
}
};
class oSceneCallback : public OSMSceneCallbacks {
public:
void OnNodeCreate(Ogre::SceneNode* pNode, TiXmlElement* pNodeDesc)
{
if(pNode->getName() == "player")
{
player = new CCommando(oScene->getSceneManager(), pNode->getPosition());
CDeleteAfterCreate::AddNode(oScene->getSceneManager(),pNode);
}
}
void OnCameraCreate(Ogre::Camera* pCamera, TiXmlElement* pCameraDesc) {
if(pCamera->getName() == "Camera01")
Ogre::Root::getSingleton().getAutoCreatedWindow()->getViewport(0)->setCamera(pCamera);
}
};
class Game : public ExampleApplication
{
public:
void createFrameListener()
{
}
void createScene()
{
win = mWindow;
oScene = new OSMScene();
oSceneCallback oe_Callback;
oScene->initialise("level_01.osm", &oe_Callback);
oScene->createScene();
mSceneMgr = oScene->getSceneManager();
//mSceneMgr->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
OSMScene::CameraList camList = oScene->getCameraList();
if(!camList.empty()) {
mCamera = camList[0];
}
}
};
int main()
{
Game game;
game.go();
return 0;
}