Приложения
Приложение А
Руководство пользователя
Программа для запуска приложения расположена в папке Demo и называется Present3D.exe. Для корректной работы программы, во время её старта из выпадающего списка нужно выбрать графическую библиотеку для рендера DirectX. В случае если на машине не установлена данная библиотека, в папке Demo приложен файл для установки dxwebsetup.exe.
Разработка и загрузка собственных 3D моделей.
Для разработки моделей потребуется Blender 2.66. После разработки анимации у 3D модели, обязательно нужно назвать анимацию Walk.
После разработки 3D моделей, требуется настроить экспортер для использования моделей в движке. В папке с приложением находится файл io_export_ogreDotScene.py, который нужно переместить в расположение C:\Program Files\Blender\2.66\scripts\addons. После перемещения нужно зайти в Blender и активировать данный скрипт, для этого выполнить действия:
Перейти в User Preferences
Открыть вкладку Addons
Найти в списке OGRE Exporter и активировать галочку на этом скрипте
Экспорт модели проводится в меню File > Export > Ogre3D (.scene and .mesh), затем нужно выбрать директорию для сохранения файла.
Следующие файлы создаются при экспорте модели из Blender:
.mesh – основной файл модели
.material – файл материала (если материал применялся)
.skeleton – файл анимации (если модель имеет анимацию)
Все такие файлы после экспорта требуется упаковать в zip архив и переместить в папку с приложением по пути Demo/media/packs.
После перемещения архива с моделью требуется добавить в конфигурационный файл resources.cfg путь к созданной модели в таком виде Zip=media/packs/NameModel.zip
На месте NameModel должно быть такое имя модели, которое содержит расширение .mesh в архиве.
Для добавления описания в виде текста к модели, нужно создать текстовый файл с названием, которое содержит расширение .mesh в архиве, и поместить в расположение Demo\media\text.
Работа с программой.
При запуске программы перед пользователем появляются созданные им модели. При выборе модели мышкой, камера подлетает к модели и затем появляется информационный текст о модели, а также анимация модели, если она существует. Для того, чтобы вернуться на исходную позицию камеры, нужно нажать кнопку «Вернуться». Кнопка «Остановить камеру» включает режим свободного манипулирования камерой при помощью мыши и кнопок WASD.
Меню настроек.
В меню настроек можно манипулировать моделями, для этого требуется перейти в меню настроек, выделить мышкой модель и с помощью кнопок манипулирования можно перемещать модель в пространстве и разворачивать вокруг своей оси.
Приложение Б
Программный код
BasicApp.h
#ifndef BASICAPP_H
#define BASICAPP_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "textMgr.h"
#include
#include
#include
class BasicApp
: public Ogre::WindowEventListener,
public Ogre::FrameListener,
public OIS::KeyListener,
public OIS::MouseListener
{
public:
BasicApp();
~BasicApp();
void go();
private:
bool mShutdown;
//Setup - Main
Ogre::Root* mRoot;
Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::RenderWindow* mWindow;
Ogre::String mResourcesCfg;
Ogre::String mPluginsCfg;
OgreBites::SdkCameraMan* mCameraMan;
Ogre::SceneNode* lNode;//записываем подгружаемые меши
Ogre::Entity* room;
Ogre::SceneNode* roomNode;
Ogre::AnimationState* anim;
//Setup - Render
virtual bool frameRenderingQueued(const Ogre::FrameEvent& fe);
//Setup - Keyboard
virtual bool keyPressed(const OIS::KeyEvent& ke);
virtual bool keyReleased(const OIS::KeyEvent& ke);
float mRotSpd;
bool mMovableFound;
bool mLMouseDown, mRMouseDown;
Ogre::Vector3 prevPositionModel;
//Setup - Mouse
virtual bool mouseMoved(const OIS::MouseEvent& me);
virtual bool mousePressed(const OIS::MouseEvent& me, OIS::MouseButtonID id);
virtual bool mouseReleased(const OIS::MouseEvent& me, OIS::MouseButtonID id);
//Setup - Window
virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw);
//Setup - application
bool setup();
bool configure();
void chooseSceneManager();
void createCamera();
void createScene();
void destroyScene();
void createFrameListener();
void createViewports();
void setupResources();
void createResourceListener();
void loadResources();
// CEGUI
CEGUI::OgreRenderer* mRenderer;
bool setupCEGUI();
// OIS
OIS::Mouse* mMouse;
OIS::Keyboard* mKeyboard;
OIS::InputManager* mInputMgr;
//Terrain
Ogre::TerrainGroup* mTerrainGroup;
Ogre::TerrainGlobalOptions* mTerrainGlobals;
//Setup - Scene
Ogre::RaySceneQuery* mRayScnQuery;//луч, опрашиваемый сцену
bool goDefaultPosition;//останавливает камеру при нажатии
void handleCameraCollision();
//GUI - Buttons
CEGUI::Window *buttonCameraSetPosition;//возвращения камеры на позицию
CEGUI::Window *buttonQuit;//выход
CEGUI::Window* textbox1;//текст для модели
CEGUI::Window* textShadow;
CEGUI::Window* menuButton; //меню настроек
CEGUI::Window* scalePlusButton; //увеличение скейла
CEGUI::Window* scaleMinusButton; //уменьшение скейла
CEGUI::Window* translateModelToLeftButton; //модельку влево
CEGUI::Window* translateModelToRightButton; //модельку вправо
CEGUI::Window* translateModelToTopButton; //модельку вперёд
CEGUI::Window* translateModelToBackButton; //модельку назад
CEGUI::Window* translateModelToUpButton; //модельку вверх
CEGUI::Window* translateModelToDownButton; //модельку вниз
CEGUI::Window* rotateRightModelButton; //поворачиваем модельку вправо
CEGUI::Window* rotateLeftModelButton; //поворачиваем модельку влево
CEGUI::Window* backMainWindowButton;//назад из меню настроек на главную
CEGUI::Window* checkShadow;
CEGUI::Window* releaseCamera;
CEGUI::Window* tipsText;
CEGUI::Window* tipsSettingText;
CEGUI::Window* tipsRoomText;
CEGUI::Window* tipsObjectText;
CEGUI::Window* scaleRoomPlusButton; //увеличение скейла
CEGUI::Window* scaleRoomMinusButton; //уменьшение скейла
//GUI - Subscribes buttons
void eventRoomScalePlus();
void eventRoomScaleMinus();
void eventModelScalePlus();
void eventModelScaleMinus();
void eventModelTranslateLeft();
void eventModelTranslateRight();
void eventModelTranslateTop();
void eventModelTranslateBack();
void eventModelTranslateUp();
void eventModelTranslateDown();
void eventModelRotateRight();
void eventModelRotateLeft();
bool eventMenuButton(const CEGUI::EventArgs &e);
bool quit(const CEGUI::EventArgs &e);//обработчик кнопки выхода
bool setDefaultPosition(const CEGUI::EventArgs &e);//обработчик кнопки cameraDefaultPosition
bool eventBackWindow(const CEGUI::EventArgs &e);//обработчик кнопки backMainWindow
void checkShadows();
//Timers
Ogre::Timer timer1;
Ogre::Timer timer2;
//Work with text model
std::vector myVector; //вектор названий мешей в конфиге
char result[100]; //выходное название меша
CEGUI::String encodeRussian(wchar_t string[100]); //декодируем в русский текст
//Inside classes & SDK
textMgr* textManager;
TiXmlDocument *file_settings;
TiXmlDocument *file_room_settings;
//GUI - Alpha
void goInAlpha(CEGUI::Window* win); //функция ухода в альфу
void goFromAlpha(CEGUI::Window* win); //функция выхода из альфы
bool goFromAlphaButton;//если моделька выделена, вытаскиваем кнопку из альфы
//GUI - Widgets
CEGUI::Window* sheetMgr;//менеджер виджетов
CEGUI::Window *sheetMainWindow;//виджет главного окна
CEGUI::Window *sheetMainMenu;//виджет меню настроек
//Setup - XML setting
void configureXmlSettings();
void removeFromXmlElderData();
void configureXmlSettingsD(const char * nameModel, Ogre::Vector3 &locationVector, Ogre::Vector3 &scaleVector, double &rotate, Ogre::Vector3 &scaleRoomVector);
bool tipsEnabled;
};
#endif
BasicApp.cpp
#include "BasicApp.h"
BasicApp::BasicApp()
: mShutdown(false),
mRoot(0),
mCamera(0),
mSceneMgr(0),
mWindow(0),
mResourcesCfg(Ogre::StringUtil::BLANK),
mPluginsCfg(Ogre::StringUtil::BLANK),
mCameraMan(0),
mRenderer(0),
mMouse(0),
mKeyboard(0),
mInputMgr(0),
mTerrainGroup(0),
mTerrainGlobals(0),
mRotSpd(0.1),
mLMouseDown(false),
mRMouseDown(false),
mRayScnQuery(0),
goDefaultPosition(false),
goFromAlphaButton(false),
sheetMainWindow(0),
textManager(0),
sheetMainMenu(0),
sheetMgr(0)
{
myVector.clear();
file_settings = new TiXmlDocument("modelSettings.xml");
file_room_settings = new TiXmlDocument("settings.xml");
}
BasicApp::~BasicApp()
{
if (mCameraMan) delete mCameraMan;
mSceneMgr->destroyQuery(mRayScnQuery);
Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
windowClosed(mWindow);
delete mRoot;
}
void BasicApp::go()
{
#ifdef _DEBUG
mResourcesCfg = "resources_d.cfg";
mPluginsCfg = "plugins_d.cfg";
#else
mResourcesCfg = "resources.cfg";
mPluginsCfg = "plugins.cfg";
#endif
if (!setup())
return;
mRoot->startRendering();
destroyScene();
}
bool BasicApp::frameRenderingQueued(const Ogre::FrameEvent& fe)
{
if (mKeyboard->isKeyDown(OIS::KC_ESCAPE))
mShutdown = true;
if (mShutdown)
return false;
if (mWindow->isClosed())
return false;
mKeyboard->capture();
mMouse->capture();
mCameraMan->frameRenderingQueued(fe);
eventRoomScalePlus();
eventRoomScaleMinus();
eventModelScalePlus();
eventModelScaleMinus();
eventModelTranslateLeft();
eventModelTranslateRight();
eventModelTranslateTop();
eventModelTranslateBack();
eventModelTranslateUp();
eventModelTranslateDown();
eventModelRotateRight();
eventModelRotateLeft();
checkShadows();
for(int i = 0; i < myVector.size(); i++)
{
//если активно главное окно и выделена моделька
if ( mSceneMgr->getSceneNode(myVector[i])->getShowBoundingBox() && sheetMainWindow->isActive() )
{
Ogre::Vector3 needPosition = mSceneMgr->getSceneNode(myVector[i])->getPosition() + Ogre::Vector3(200,50,50);
mCamera->move( (needPosition - mCamera->getPosition() ) * fe.timeSinceLastFrame );
mCamera->lookAt(mSceneMgr->getSceneNode(myVector[i])->getPosition() + Ogre::Vector3(0,50,50) );
textbox1->setVisible(true);
prevPositionModel = mSceneMgr->getSceneNode(myVector[i])->getPosition();
tipsEnabled = false;
wchar_t cameraText[100] = L"Вернуться";
buttonCameraSetPosition->setText( encodeRussian(cameraText) );
if (mSceneMgr->getEntity(myVector[i])->hasAnimationState("Walk"))
{
anim = mSceneMgr->getEntity(myVector[i])->getAnimationState("Walk");
anim->setLoop(true);
anim->setEnabled(true);
anim->addTime(fe.timeSinceLastFrame);
}
}
}
if (goDefaultPosition)
{
Ogre::Vector3 needPosition(500, 350, 150);
mCamera->move( (needPosition - mCamera->getPosition() ) * fe.timeSinceLastFrame );
mCamera->lookAt(prevPositionModel);
wchar_t cameraText[100] = L"Остановить камеру";
buttonCameraSetPosition->setText( encodeRussian(cameraText) );
for(int i = 0; i < myVector.size(); i++)
{
if ( mSceneMgr->getSceneNode(myVector[i])->getShowBoundingBox() && mSceneMgr->getEntity(myVector[i])->hasAnimationState("Walk"))
{
anim->setEnabled(false);
}
}
}
tipsText->setVisible(tipsEnabled);
CEGUI::System::getSingleton().injectTimePulse(fe.timeSinceLastFrame);
return true;
}
void BasicApp::eventRoomScalePlus()
{
if (static_cast(scaleRoomPlusButton)->isPushed() )
{
Ogre::Real needScaleX = roomNode->getScale().x * 1.001f;
Ogre::Real needScaleY = roomNode->getScale().y;
Ogre::Real needScaleZ = roomNode->getScale().z * 1.001f;
roomNode->setScale(needScaleX, needScaleY, needScaleZ);
}
}
void BasicApp::eventRoomScaleMinus()
{
if (static_cast(scaleRoomMinusButton)->isPushed() )
{
Ogre::Real needScaleX = roomNode->getScale().x * 0.999f;
Ogre::Real needScaleY = roomNode->getScale().y;
Ogre::Real needScaleZ = roomNode->getScale().z * 0.999f;
roomNode->setScale(needScaleX, needScaleY, needScaleZ);
}
}
void BasicApp::eventModelScalePlus()
{
for(int i = 0; i < myVector.size(); i++)
{
if ( mSceneMgr->getSceneNode(myVector[i])->getShowBoundingBox() && static_cast(scalePlusButton)->isPushed() )
{
Ogre::Vector3 needScale = mSceneMgr->getSceneNode(myVector[i])->getScale() * 1.001f; //костыль на скейл
mSceneMgr->getSceneNode(myVector[i])->setScale(needScale);
}
}
}
void BasicApp::eventModelScaleMinus()
{
for(int i = 0; i < myVector.size(); i++)
{
if ( mSceneMgr->getSceneNode(myVector[i])->getShowBoundingBox() && static_cast(scaleMinusButton)->isPushed() )
|