pozitiffcat |
26.02.2012 01:57 |
Загрузка сцены из 3ds Max (Туториал)
Вложений: 1
Я выбрал плагин oFusion, т.к. у него нет ни каких ограничений в отличие от OgreMax. Качайте отсюда http://www.ofusiontechnologies.com/o...on_ce_1.86.exe
Для его использования понадобится макс не выше 9 версии.
Далее качаем архив с загрузчиком (в аттаче).
Создаем проект, настраиваем (вы должны уже это уметь).
Распаковываем OSM.zip в каталог с исходниками. Из этих папок все cpp файлы перетаскиваем в проект. В проекте подключаем файлы
PHP код:
#include "OSM\OgreOSMScene.h" #include "OSM\IOSMSceneCallbacks.h"
Сделаем например сценку, и игрока, который будет по ней перемещаться.
Создаем сцену в максе, экспортируем в OSM (меню oFusion->Export Scene), и создаем отдельно игрока, при экспорте снимаем галку экспортировать сцену, тогда он отэкспортирует только модель.
Все это ложим в какой нибудь каталог, и настраиваем на него resources.cfg.
В createScene прописываем загрузку сцены
PHP код:
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, на его месте я поставлю игрока, а бокс удалю.
Вот код класса перехватчика
PHP код:
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); } };
код класса игрока и удалятора
PHP код:
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; } };
Как то так.
Вот, что у меня получилось:
Исходный код:
PHP код:
#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; }
|