MerGC_Team | Дата: Четверг, 03.04.2014, 17:45 | Сообщение # 1 |
Веселый админ
Группа: Администраторы
Сообщений: 32
Статус: Оффлайн
| Начиная с версии 1.1, Irrlicht позволяет загружать и сохранять данные сцены из/в .irr файлы, на базе xml формата. Присутствует также редактор позволяющий хранить данные в этом формате, называется irrEdit (http://www.ambiera.com/irredit), который можно также использовать как редактор частиц и мира. В этом туториале я покажу, как использовать .irr файлы непосредственно из движка.
Как обычно, подключим заголовочный файл Irrlicht, включим по умолчанию пространство имен .irr Код #include < irrlicht.h > #include "driverChoice.h"
using namespace irr;
int main(int argc, char** argv) { // запрашиваем драйвер (OpenGL, DirectX и т.д.) video::E_DRIVER_TYPE driverType=driverChoiceConsole(); if (driverType==video::EDT_COUNT) return 1; // выходим, если драйвер не выбран
IrrlichtDevice* device = createDevice(driverType, core::dimension2d< u32 >(640, 480));
if (device == 0) return 1; // выходим, если движок не создан.
device->setWindowCaption(L"Load .irr file example");
video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager();
Теперь приступим к загрузке. Файлы.irr могут хранить всю сцену целиком включая аниматоры, материалы, системы частиц, источники света и т.д., вдобавок в файле могут хранится произвольные пользовательские данные для каждого узла(ноды) сцены. Чтобы пример был прост, мы не будем его наворачивать, а просто загрузим заранее заготовленную сцену. Поштудируйте документацию на тему методов Код ISceneManager::loadScene и ISceneManager::saveScene для больших подробностей. // загружаем сцену if (argc>1) smgr->loadScene(argv[1]); // пытаемся взять имя файла из комадной строки else smgr->loadScene("../../media/example.irr");
Создаем камеру и прикручиваем к менеджеру столкновений, построенному на основе геометрии загруженной сцены. Код scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0, 50.f, 0.1f);
// создаем селектор геометрии (triangle selector) загруженной сцены. scene::IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector();
Теперь переберем все узлы(ноды) на сцене и поместим в селекторе те, что содержат геометрию. Когда вам потребуется несколько селекторов и группировать узлы относительно них, то вам надо будет в редакторе сцены присвоить узлам(нодам) специальные идентификаторы(id) по которым в цикле определять к какому селектору отнести узел(ноду). Код core::array< scene::ISceneNode* > nodes; smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // получаем все ноды
for (u32 i=0; i < nodes.size(); ++i) { scene::ISceneNode * node = nodes[i]; scene::ITriangleSelector * selector = 0;
switch(node->getType()) { case scene::ESNT_CUBE: case scene::ESNT_ANIMATED_MESH: // Т.к. селектор не обрабатывает анимацию мешей // и используется для определения столкновений с камерой, мы будем использовать // bounding box вместо ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0) selector = smgr->createTriangleSelectorFromBoundingBox(node); break;
case scene::ESNT_MESH: case scene::ESNT_SPHERE: // наследуется от IMeshSceneNode selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node); break;
case scene::ESNT_TERRAIN: selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node); break;
case scene::ESNT_OCTREE: selector = smgr->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node); break;
default: // для остальных типов нод не создаем селектор break; }
if(selector) { // добавляем в мета селектор meta->addTriangleSelector(selector); // дропаем для себя, т.к. селектор уже хранит ссылку на него. selector->drop(); } }
И так, теперь наша сцена имеет набор селекторов объединенных в мета селекторе и аниматор отвечающий за столкновения. Код scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( meta, camera, core::vector3df(5,5,5), core::vector3df(0,0,0)); meta->drop(); // дропаем мета селектор
camera->addAnimator(anim); anim->drop(); // дропаем анимато
// помещаем камеру в начальную позицию camera->setPosition(core::vector3df(0.f, 20.f, 0.f));
// направляем камеру на первый кубик, найдя его по типу ESNT_CUBE scene::ISceneNode * cube = smgr->getSceneNodeFromType(scene::ESNT_CUBE); if(cube) camera->setTarget(cube->getAbsolutePosition());
Подготовка завершена. Начинаем рисовать. Код int lastFPS = -1;
while(device->run()) if (device->isWindowActive()) { driver->beginScene(true, true, video::SColor(0,200,200,200)); smgr->drawAll(); driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps) { core::stringw str = L"Load Irrlicht File example - Irrlicht Engine ["; str += driver->getName(); str += "] FPS:"; str += fps;
device->setWindowCaption(str.c_str()); lastFPS = fps; }
}
device->drop();
return 0; }
Все, компилируем, запускаем!
|
|
| |