//在小地图中描画出路径的轮廓.仿造艾尔之光副本中小地图
//粗糙的版本.自行修改.
#ifndef __UI3DRadarMap_H__ #define __UI3DRadarMap_H__ #include "Loki/Singleton.h" #include "SeerBaseConfig.h" #include <Ogre/Ogre.h> #include <map> #include "SeerNetProcotolData.h" #include "Loki/Singleton.h" #define UI3DRadarMapExport __declspec( dllexport ) namespace Orz { class CSeerEntityInterface; class UI3DRadarMapExport UI3DRadarMap { public: typedef std::vector<Ogre::Vector3> WayPointList; typedef std::map<std::string, WayPointList> PathList; private: typedef Loki::SingletonHolder<UI3DRadarMap> MySingleton; public: inline static UI3DRadarMap& Instance() { return MySingleton::Instance(); } UI3DRadarMap(); void init(Ogre::SceneManager* sm = NULL); void shutdown(); void update(TimeType time); void setup(); void loadPath(); void drawWay(WayPointList & waylist); void reset(); void updateMonstersCursor(); void hideMonsterCursor(guid_t id); void setSceneVisible(bool visible); struct Compare { typedef guid_t key_type; bool operator () (const key_type& ls, const key_type& rs) const { return ls.id < rs.id || ls.id == rs.id && ls.type < rs.type || ls.id == rs.id && ls.type == rs.type && ls.index < rs.index; } }; typedef std::map<guid_t, ComponentPtr, Compare> MonsterCursorMap; CEGUI::Window* _window; CEGUI::OgreRenderer* _render; CEGUI::RenderingWindow* _cerenderwindow; Ogre::SceneManager* _scenemgr; Ogre::TexturePtr _rtttexture; Ogre::RenderTarget * _renderTarget; Ogre::Camera * _camera; Ogre::SceneNode * _node; Ogre::ManualObject* _3dobject; Ogre::Entity* _entity; float _aspectFactor; MonsterCursorMap _monstersCursors; ComponentPtr _charCursorComp; CSeerEntityInterface* _charCursor; PathList _paths; }; } #endif
#include "SeerUIComponentStableHeaders.h" #include "UI3DRadarMap.h" #include <cegui/CEGUI.h> #include <cegui/RendererModules/Ogre/CEGUIOgreRenderer.h> #include <Orz/View_CEGUI/CEGUIManager.h> #include "SimpleLogManager.h" #include "RadarMapCursorInterface.h" #include "SeerInterfaceManager.h" #include "SeerMonsterLayoutInterface.h" #include "CSeerEntityInterface.h" #include "SeerInterfaceManager.h" #include "SeerCharactorMoveInterface.h" #include "SeerInterfaceManager.h" #include "SeerHelper.h" #include "SeerSquareInterface.h" static float G_WIDTH_X = 3000; static float G_HEIGHT_Y = 1500; #define SMALLDELTA 0.05 namespace Orz { ////////////////////////////////////////////////////////////////////////// UI3DRadarMap::UI3DRadarMap(): _window(NULL), _scenemgr(NULL), _cerenderwindow(NULL), _render(NULL), _renderTarget(NULL), _camera(NULL), _node(NULL), _3dobject(NULL) { } void UI3DRadarMap::init(Ogre::SceneManager* sm) { _window = CEGUI::WindowManager::getSingleton().getWindow("KJMainGame2_Nmap"); _cerenderwindow = (CEGUI::RenderingWindow*)_window->getRenderingSurface(); _render = Orz::CEGUIManager::getSingletonPtr()->getRenderer(); _aspectFactor = _window->getPixelSize().d_width / _window->getPixelSize().d_height; _rtttexture = Ogre::TextureManager::getSingleton().createManual("rtt_3dradarmap", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 256, 256, 1, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET); _renderTarget = _rtttexture->getBuffer()->getRenderTarget(); _renderTarget->setActive(true); _renderTarget->setAutoUpdated(true); if (sm!=NULL) { _scenemgr = sm; } else { _scenemgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "ui3dradarmap_scenemanager"); } _node = _scenemgr->getRootSceneNode()->createChildSceneNode("ui3dradarmap_rootnode"); _camera = _scenemgr->createCamera("ui3dradarmap_camera"); _node->attachObject(_camera); _camera->setNearClipDistance(5); _camera->move(Ogre::Vector3(0, 0.0f, 100.0f)); _camera->lookAt(Ogre::Vector3(0, 0.0f, -100.0f)); _camera->setProjectionType(Ogre::PT_PERSPECTIVE); _camera->setAspectRatio(_aspectFactor);//图片比例 _camera->setFOVy(Ogre::Degree(45.0f)); Ogre::Viewport *vp = _renderTarget->addViewport(_camera); vp->setAutoUpdated(true); vp->setBackgroundColour(Ogre::ColourValue(0,0,0,0)); vp->setOverlaysEnabled(false); vp->setClearEveryFrame(true); vp->setSkiesEnabled(false); CEGUI::Texture &ctex = CEGUIManager::getSingletonPtr()->getRenderer()->createTexture(_rtttexture,false); CEGUI::Imageset &imgset = CEGUI::ImagesetManager::getSingleton().create("ui3dradarmap_imageset",ctex); imgset.defineImage("RttImage",CEGUI::Point(0,0),ctex.getSize(),CEGUI::Point(0,0)); _window->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imgset.getImage("RttImage"))); _window->show(); _charCursorComp = Orz::ComponentFactories::getInstance().create("entity"); _charCursor = _charCursorComp->queryInterface<CSeerEntityInterface>(); _charCursor->load("ui3dradarmap_char_cursor", "Effect/map/cursor/char/char_cursor.mesh", false, _node); _charCursor->getSceneNode()->setScale(2.5, 2.5, 2.5); } void UI3DRadarMap::loadPath() { _paths.clear(); SeerSquareInterface* square = SeerInterfaceManager::getSingleton().queryInterface<SeerSquareInterface>(); typedef std::vector<SeerHelperPtr> PathNodeList; std::vector<SeerHelperPtr>& pathnodes = square->getHelperMap(); std::vector<SeerHelperPtr>::iterator it = pathnodes.begin(); for (; it != pathnodes.end(); ++it) { SeerHelperPtr helper = *it; if(helper->type == "path") continue; PathList::iterator it_path = _paths.find(helper->name); if (it_path == _paths.end()) { WayPointList waylist; if(helper->node) waylist.push_back(helper->node->_getDerivedPosition()); _paths.insert(std::make_pair(helper->name, waylist)); } else { if(helper->node) it_path->second.push_back(helper->node->_getDerivedPosition()); } } } void UI3DRadarMap::setup() { reset(); PathList::iterator it_path = _paths.begin(); for (; it_path != _paths.end(); ++it_path) { drawWay(it_path->second); } //WayPointList waylist; //for (int i = 0; i < 50; i+=2) //{ // waylist.push_back(Ogre::Vector3(-10000+400*i, -200, 0)); // waylist.push_back(Ogre::Vector3(-10000+400*(i+1), -200, 0)); // waylist.push_back(Ogre::Vector3(-10000+400*(i+1), 200, 0)); // waylist.push_back(Ogre::Vector3(-10000+400*(i+2), 200, 0)); //} //drawWay(waylist); //waylist.clear(); //waylist.push_back(Ogre::Vector3(-10000, -50, 0)); //waylist.push_back(Ogre::Vector3(-5000, 50, 0)); //waylist.push_back(Ogre::Vector3(5000, -50, 0)); //waylist.push_back(Ogre::Vector3(10000, 50, 0)); //drawWay(waylist); } void UI3DRadarMap::drawWay(WayPointList & waylist) { static int width = 40; _3dobject->begin("ui3dradarmap_road"); WayPointList::iterator it_p = waylist.begin(); _3dobject->position(*it_p); _3dobject->position(*it_p + width* Ogre::Vector3::UNIT_Y); ++it_p; if(it_p == waylist.end()) return; for (; (it_p + 1) != waylist.end(); ++it_p) { Ogre::Vector3 cur_point = *it_p; Ogre::Vector3 pre_point = *(it_p-1); Ogre::Vector3 nex_point = *(it_p+1); Ogre::Vector3 pre_dir = cur_point - pre_point; Ogre::Vector3 nex_dir = nex_point - cur_point; Ogre::Vector3 mid_dir = (nex_dir - pre_dir) / 2; Ogre::Vector3 vertical_dir(-pre_dir.y, pre_dir.x, pre_dir.z); pre_dir.normalise(); nex_dir.normalise(); mid_dir.normalise(); vertical_dir.normalise(); Ogre::Vector3 offset; float cos_v = nex_dir.dotProduct(pre_dir); float angle_v = std::acos(cos_v); if(angle_v < SMALLDELTA ) { offset = width * vertical_dir; } else { if(nex_dir.crossProduct(pre_dir).z > 0) mid_dir = - mid_dir; offset = ( width / std::abs(sin(angle_v/2)) ) * mid_dir; } Ogre::Vector3 cur_point_up = cur_point + offset; _3dobject->position(cur_point); _3dobject->position(cur_point_up); } _3dobject->position(*it_p); _3dobject->position(*it_p + width* Ogre::Vector3::UNIT_Y); for (size_t i = 0; i < waylist.size()-1; i++) _3dobject->quad(2*i+3, 2*i+1, 2*i, 2*i+2); _3dobject->end(); } void UI3DRadarMap::shutdown() { } void UI3DRadarMap::update(TimeType time) { if(!_camera) return; Ogre::Camera* cam = OgreGraphicsManager::getSingletonPtr()->getCamera(); _camera->setPosition(cam->getDerivedPosition()); _camera->setDirection(cam->getDerivedDirection()); SeerCharactorMoveInterface* move = SeerInterfaceManager::getSingletonPtr()->queryInterface<SeerCharactorMoveInterface>(); if(move == NULL) return; Ogre::Vector3 charpos = move->getBodySceneNode()->_getDerivedPosition(); _charCursor->getSceneNode()->_setDerivedPosition(charpos); updateMonstersCursor(); } void UI3DRadarMap::updateMonstersCursor() { SeerMonsterLayoutInterface* monsterLayout = SeerInterfaceManager::getSingleton().queryInterface<SeerMonsterLayoutInterface>(); if(monsterLayout == NULL) return; std::vector<std::pair<guid_t, Ogre::Vector3>> monstersPosList = monsterLayout->getMonstersPosition(); std::vector<std::pair<guid_t, Ogre::Vector3>>::iterator it_pair = monstersPosList.begin(); for (; it_pair != monstersPosList.end(); ++it_pair) { MonsterCursorMap::iterator it = _monstersCursors.find(it_pair->first); ComponentPtr cursorComp; CSeerEntityInterface* cursorEnt; if (it == _monstersCursors.end()) { cursorComp = Orz::ComponentFactories::getInstance().create("entity"); cursorEnt = cursorComp->queryInterface<CSeerEntityInterface>(); cursorEnt->setSceneManager(_scenemgr); cursorEnt->load( "ui3dradarmap_monster_cursor_"+boost::lexical_cast<std::string>(_monstersCursors.size()), "Effect/map/cursor/monster/monster_cursor.mesh", false, _node); cursorEnt->getSceneNode()->setScale(2.5, 2.5, 2.5); _monstersCursors.insert(std::make_pair(it_pair->first, cursorComp)); } else { cursorComp = it->second; cursorEnt = cursorComp->queryInterface<CSeerEntityInterface>(); } cursorEnt->getSceneNode()->_setDerivedPosition(it_pair->second); } } void UI3DRadarMap::reset() { _monstersCursors.clear(); if(_3dobject) { _3dobject->detachFromParent(); if(_scenemgr) { _scenemgr->destroyManualObject(_3dobject->getName()); } } _3dobject = _scenemgr->createManualObject("ui3dradarmap_manualobject"); _node->attachObject(_3dobject); } void UI3DRadarMap::hideMonsterCursor(guid_t id) { MonsterCursorMap::iterator it = _monstersCursors.find(id); if(it == _monstersCursors.end()) return; CSeerEntityInterface* radarCursor = it->second->queryInterface<CSeerEntityInterface>(); radarCursor->getSceneNode()->setVisible(false); } void UI3DRadarMap::setSceneVisible(bool visible) { if(_node) _node->setVisible(visible); CEGUI::Window* roleCursor = CEGUI::WindowManager::getSingleton().getWindow("KJMainGame2_mapRole"); if(roleCursor) roleCursor->setVisible(!visible); } }