From 4249d2c53699fe42fdc9da3553a7ac5fc9403b90 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 28 Mar 2012 03:15:10 +0200 Subject: [PATCH 1/9] add getNorthVector method --- apps/openmw/mwworld/world.cpp | 16 ++++++++++++++++ apps/openmw/mwworld/world.hpp | 3 +++ 2 files changed, 19 insertions(+) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a636ce288..a1d582491 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -701,6 +701,7 @@ namespace MWWorld void World::update (float duration) { + getNorthVector(mWorldScene->getCurrentCell()); mWorldScene->update (duration); mWeatherManager->update (duration); @@ -754,4 +755,19 @@ namespace MWWorld { return mRendering->getFader(); } + + Ogre::Vector2 World::getNorthVector(Ptr::CellStore* cell) + { + ESMS::CellRefList statics = cell->statics; + ESMS::LiveCellRef* ref = statics.find("northmarker"); + if (!ref) + { + std::cout << "No north marker found." << std::endl; + return Vector2(0, 1); + } + Ogre::SceneNode* node = ref->mData.getBaseNode(); + Vector3 dir = -node->_getDerivedOrientation().zAxis(); + Vector2 d = Vector2(dir.x, dir.z); + return d; + } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 71cca3545..2607c3830 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -129,6 +129,9 @@ namespace MWWorld bool isCellExterior() const; bool isCellQuasiExterior() const; + Ogre::Vector2 getNorthVector(Ptr::CellStore* cell); + ///< get north vector (OGRE coordinates) for given interior cell + Globals::Data& getGlobalVariable (const std::string& name); Globals::Data getGlobalVariable (const std::string& name) const; From 37e6db69d83a82892be8463b36daea5926b131cc Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Mar 2012 17:07:59 +0200 Subject: [PATCH 2/9] fix --- apps/openmw/mwworld/world.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a1d582491..5c661b4a2 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -766,7 +766,7 @@ namespace MWWorld return Vector2(0, 1); } Ogre::SceneNode* node = ref->mData.getBaseNode(); - Vector3 dir = -node->_getDerivedOrientation().zAxis(); + Vector3 dir = node->_getDerivedOrientation().yAxis(); Vector2 d = Vector2(dir.x, dir.z); return d; } From 35f40b99adb5cd6b04499b5c78f8909eccad27a4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Mar 2012 18:10:01 +0200 Subject: [PATCH 3/9] remove the bounding box hack, not needed because calculation is correct now --- apps/openmw/mwrender/localmap.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ed218dc97..2c0a4e76b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -65,9 +65,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); - /// \todo why is this workaround needed? - min *= 1.3; - max *= 1.3; Vector2 length = max-min; // divide into segments @@ -108,10 +105,6 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); - /// \todo why is this workaround needed? - min *= 1.3; - max *= 1.3; - Vector2 length = max-min; Vector2 center(bounds.getCenter().x, bounds.getCenter().z); @@ -243,7 +236,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& else { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - min *= 1.3; x = std::ceil((pos.x - min.x)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1; @@ -264,7 +256,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& else { Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - min *= 1.3; u = (pos.x - min.x - sSize*x)/sSize; v = (pos.y - min.y - sSize*y)/sSize; From 01ecf3e0be726f028bd662f89c2b26177c169a3d Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Mar 2012 18:16:11 +0200 Subject: [PATCH 4/9] attempt at rotation (BROKEN) --- apps/openmw/mwrender/localmap.cpp | 16 +++++++++++++--- apps/openmw/mwrender/localmap.hpp | 2 ++ apps/openmw/mwworld/world.cpp | 4 ---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 2c0a4e76b..47b8171a5 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -2,6 +2,7 @@ #include "renderingmanager.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" #include "../mwgui/window_manager.hpp" #include @@ -14,12 +15,17 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* en { mRendering = rend; mEnvironment = env; - + + mCameraRotNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); + mCameraNode = mCameraRotNode->createChildSceneNode(); + mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); // look down -y const float sqrt0pt5 = 0.707106781; mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); + + mCameraNode->attachObject(mCellCamera); } LocalMap::~LocalMap() @@ -100,11 +106,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, { mInterior = true; mBounds = bounds; - + Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); + const Vector2& north = mEnvironment->mWorld->getNorthVector(cell); + Radian angle(std::atan2(north.x, north.y)); + mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0)); + Vector2 length = max-min; Vector2 center(bounds.getCenter().x, bounds.getCenter().z); @@ -141,7 +151,7 @@ void LocalMap::render(const float x, const float y, // make everything visible mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); - mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); + mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); mCellCamera->setFarClipDistance(0); // infinite diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index efbccf884..42603885a 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -73,6 +73,8 @@ namespace MWRender static const int sSize = 8192; Ogre::Camera* mCellCamera; + Ogre::SceneNode* mCameraNode; + Ogre::SceneNode* mCameraRotNode; void render(const float x, const float y, const float zlow, const float zhigh, diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 5c661b4a2..24d055c35 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -701,7 +701,6 @@ namespace MWWorld void World::update (float duration) { - getNorthVector(mWorldScene->getCurrentCell()); mWorldScene->update (duration); mWeatherManager->update (duration); @@ -761,10 +760,7 @@ namespace MWWorld ESMS::CellRefList statics = cell->statics; ESMS::LiveCellRef* ref = statics.find("northmarker"); if (!ref) - { - std::cout << "No north marker found." << std::endl; return Vector2(0, 1); - } Ogre::SceneNode* node = ref->mData.getBaseNode(); Vector3 dir = node->_getDerivedOrientation().yAxis(); Vector2 d = Vector2(dir.x, dir.z); From 0c2317ce9d7f9fb2877605301d53785dc3b472ac Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Mar 2012 19:20:09 +0200 Subject: [PATCH 5/9] player arrow works again --- apps/openmw/mwrender/localmap.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 47b8171a5..ef21e2658 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -11,7 +11,8 @@ using namespace MWRender; using namespace Ogre; -LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) : + mInterior(false), mCellX(0), mCellY(0) { mRendering = rend; mEnvironment = env; @@ -93,6 +94,8 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) { mInterior = false; + mCameraRotNode->setOrientation(Quaternion::IDENTITY); + std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY); int x = cell->cell->data.gridX; @@ -235,7 +238,12 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& // retrieve the x,y grid coordinates the player is in int x,y; - Vector2 pos(position.x, position.z); + Vector3 _pos(position.x, 0, position.z); + _pos = mCameraRotNode->convertWorldToLocalPosition(_pos); + Vector2 pos(_pos.x, _pos.z); + + Vector3 playerdirection = mCameraRotNode->convertWorldToLocalPosition(direction); + if (!mInterior) { x = std::ceil(pos.x / sSize)-1; @@ -273,7 +281,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& texName = mInteriorName + "_" + coordStr(x,y); } mEnvironment->mWindowManager->setPlayerPos(u, v); - mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z); + mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z); // explore radius (squared) const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; From 8d224f009fc34957572d4c8a3a8695936856197a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 29 Mar 2012 19:45:19 +0200 Subject: [PATCH 6/9] toggleFogOfWar script command --- apps/openmw/mwgui/layouts.cpp | 35 ++++++++++++++++++++------ apps/openmw/mwgui/layouts.hpp | 5 ++++ apps/openmw/mwgui/window_manager.cpp | 6 +++++ apps/openmw/mwgui/window_manager.hpp | 2 ++ apps/openmw/mwrender/localmap.cpp | 1 - apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/guiextensions.cpp | 19 ++++++++++++++ 7 files changed, 62 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index de74214ee..223c072b7 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -278,6 +278,7 @@ LocalMapBase::LocalMapBase() : mCurX(0) , mCurY(0) , mInterior(false) + , mFogOfWar(true) , mLocalMap(NULL) , mPrefix() , mChanged(true) @@ -297,6 +298,32 @@ void LocalMapBase::setCellPrefix(const std::string& prefix) mChanged = true; } +void LocalMapBase::toggleFogOfWar() +{ + mFogOfWar = !mFogOfWar; + applyFogOfWar(); +} + +void LocalMapBase::applyFogOfWar() +{ + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + std::string image = mPrefix+"_"+ boost::lexical_cast(mCurX + (mx-1)) + "_" + + boost::lexical_cast(mCurY + (mInterior ? (my-1) : -1*(my-1))); + MyGUI::ImageBox* fog; + mLayout->getWidget(fog, name+"_fog"); + fog->setImageTexture(mFogOfWar ? + ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" + : "black.png" ) + : ""); + } + } +} + void LocalMapBase::setActiveCell(const int x, const int y, bool interior) { if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell @@ -312,23 +339,17 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) MyGUI::ImageBox* box; mLayout->getWidget(box, name); - MyGUI::ImageBox* fog; - mLayout->getWidget(fog, name+"_fog"); if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) box->setImageTexture(image); else box->setImageTexture("black.png"); - - if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) - fog->setImageTexture(image+"_fog"); - else - fog->setImageTexture("black.png"); } } mInterior = interior; mCurX = x; mCurY = y; mChanged = false; + applyFogOfWar(); } diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 614479ccc..6719e967c 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -40,12 +40,17 @@ namespace MWGui void setCellPrefix(const std::string& prefix); void setActiveCell(const int x, const int y, bool interior=false); + void toggleFogOfWar(); + protected: int mCurX, mCurY; bool mInterior; MyGUI::ScrollView* mLocalMap; std::string mPrefix; bool mChanged; + bool mFogOfWar; + + void applyFogOfWar(); OEngine::GUI::Layout* mLayout; }; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index a04e2dcb8..e7aa7690f 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -469,3 +469,9 @@ void WindowManager::setPlayerDir(const float x, const float y) map->setPlayerDir(x,y); hud->setPlayerDir(x,y); } + +void WindowManager::toggleFogOfWar() +{ + map->toggleFogOfWar(); + hud->toggleFogOfWar(); +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 582f438e8..204774f5f 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -156,6 +156,8 @@ namespace MWGui void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell void setPlayerPos(const float x, const float y); ///< set player position in map space void setPlayerDir(const float x, const float y); ///< set player view direction in map space + + void toggleFogOfWar(); void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ef21e2658..803899110 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -269,7 +269,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& u = std::abs((pos.x - (sSize*x))/sSize); v = 1-std::abs((pos.y + (sSize*y))/sSize); texName = "Cell_"+coordStr(x,y); - } else { diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index eab5bf846..d7e81531d 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -123,4 +123,5 @@ op 0x200013d: FadeOut op 0x200013e: FadeTo op 0x200013f: GetCurrentWeather op 0x2000140: ChangeWeather -opcodes 0x2000141-0x3ffffff unused +op 0x2000145: ToggleFogOfWar (tfow) +opcodes 0x2000146-0x3ffffff unused diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 484c0d3ab..426378efc 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -67,6 +67,19 @@ namespace MWScript } }; + class OpToggleFogOfWar : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + InterpreterContext& context = + static_cast (runtime.getContext()); + + context.getEnvironment().mWindowManager->toggleFogOfWar(); + } + }; + const int opcodeEnableBirthMenu = 0x200000e; const int opcodeEnableClassMenu = 0x200000f; const int opcodeEnableNameMenu = 0x2000010; @@ -79,6 +92,7 @@ namespace MWScript const int opcodeEnableRest = 0x2000017; const int opcodeShowRestMenu = 0x2000018; const int opcodeGetButtonPressed = 0x2000137; + const int opcodeToggleFogOfWar = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) { @@ -100,6 +114,9 @@ namespace MWScript extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu); extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed); + + extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar); + extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -135,6 +152,8 @@ namespace MWScript new OpShowDialogue (MWGui::GM_Rest)); interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); + + interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar); } } } From fc5cd703bb189d774a1d843d44e508772389a1c7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 30 Mar 2012 16:34:36 +0200 Subject: [PATCH 7/9] maps are now rendered with correct rotation, however for interiors the arrow is wrong --- apps/openmw/mwrender/localmap.cpp | 37 +++++++++++++++++------ apps/openmw/mwrender/localmap.hpp | 5 +-- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 803899110..063b25301 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -17,7 +17,8 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* en mRendering = rend; mEnvironment = env; - mCameraRotNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); + mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); + mCameraRotNode = mCameraPosNode->createChildSceneNode(); mCameraNode = mCameraRotNode->createChildSceneNode(); mCellCamera = mRendering->getScene()->createCamera("CellCamera"); @@ -101,6 +102,8 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) int x = cell->cell->data.gridX; int y = cell->cell->data.gridY; + mCameraPosNode->setPosition(Vector3(0,0,0)); + render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); } @@ -110,17 +113,26 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, mInterior = true; mBounds = bounds; - Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); - Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); - Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); + Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y); const Vector2& north = mEnvironment->mWorld->getNorthVector(cell); - Radian angle(std::atan2(north.x, north.y)); + Radian angle(std::atan2(-north.x, -north.y)); mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0)); - Vector2 length = max-min; + mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM))); + mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM))); + mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM))); + mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM))); + Vector2 center(bounds.getCenter().x, bounds.getCenter().z); + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); + + Vector2 length = max-min; + + mCameraPosNode->setPosition(Vector3(center.x, 0, center.y)); + // divide into segments const int segsX = std::ceil( length.x / sSize ); const int segsY = std::ceil( length.y / sSize ); @@ -134,7 +146,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, Vector2 start = min + Vector2(sSize*x,sSize*y); Vector2 newcenter = start + 4096; - render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize, + render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize, cell->cell->name + "_" + coordStr(x,y)); } } @@ -227,7 +239,7 @@ void LocalMap::render(const float x, const float y, mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } -void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction) +void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation) { if (sFogOfWarSkip != 0) { @@ -240,9 +252,13 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& int x,y; Vector3 _pos(position.x, 0, position.z); _pos = mCameraRotNode->convertWorldToLocalPosition(_pos); + + //if (mInterior) + /// \todo + Vector2 pos(_pos.x, _pos.z); - Vector3 playerdirection = mCameraRotNode->convertWorldToLocalPosition(direction); + Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); if (!mInterior) { @@ -279,6 +295,9 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& texName = mInteriorName + "_" + coordStr(x,y); } + + //std::cout << " x,y " << x << ", " << y << " u,v " << u << "," << v << std::endl; + mEnvironment->mWindowManager->setPlayerPos(u, v); mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 42603885a..cb294a656 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -44,9 +44,9 @@ namespace MWRender * @remarks This is used to draw a "fog of war" effect * to hide areas on the map the player has not discovered yet. * @param position (OGRE coordinates) - * @param view direction (OGRE coordinates) + * @param camera orientation (OGRE coordinates) */ - void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction); + void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation); /** * Save the fog of war for the current cell to disk. @@ -74,6 +74,7 @@ namespace MWRender Ogre::Camera* mCellCamera; Ogre::SceneNode* mCameraNode; + Ogre::SceneNode* mCameraPosNode; Ogre::SceneNode* mCameraRotNode; void render(const float x, const float y, diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c947b67f5..5df93ab32 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -171,7 +171,7 @@ void RenderingManager::update (float duration){ mRendering.update(duration); - mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() ); + mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); checkUnderwater(); } From 342464530de5f88da0a6728e6ad2f8a99ff08e00 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 2 Apr 2012 19:37:24 +0200 Subject: [PATCH 8/9] rotated map working --- apps/openmw/mwrender/localmap.cpp | 37 ++++++++++++++--------- apps/openmw/mwrender/localmap.hpp | 8 ++++- apps/openmw/mwrender/objects.cpp | 32 ++++++++++++++++++++ apps/openmw/mwrender/objects.hpp | 4 +++ apps/openmw/mwrender/renderingmanager.cpp | 12 +++++++- apps/openmw/mwrender/renderingmanager.hpp | 3 ++ 6 files changed, 80 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 063b25301..e88557f20 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -11,10 +11,11 @@ using namespace MWRender; using namespace Ogre; -LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) : +LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) : mInterior(false), mCellX(0), mCellY(0) { mRendering = rend; + mRenderingManager = rendering; mEnvironment = env; mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); @@ -35,6 +36,12 @@ LocalMap::~LocalMap() deleteBuffers(); } +const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle) +{ + return Vector2( Math::Cos(angle) * (p.x - c.x) - Math::Sin(angle) * (p.y - c.y) + c.x, + Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y); +} + void LocalMap::deleteBuffers() { mBuffers.clear(); @@ -117,6 +124,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, const Vector2& north = mEnvironment->mWorld->getNorthVector(cell); Radian angle(std::atan2(-north.x, -north.y)); + mAngle = angle.valueRadians(); mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0)); mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM))); @@ -124,7 +132,9 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM))); mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM))); - Vector2 center(bounds.getCenter().x, bounds.getCenter().z); + mBounds.scale(Vector3(2,2,2)); + + Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); @@ -165,6 +175,7 @@ void LocalMap::render(const float x, const float y, // make everything visible mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); + mRenderingManager->disableLights(); mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); @@ -233,7 +244,8 @@ void LocalMap::render(const float x, const float y, //rtt->writeContentsToFile("./" + texture + ".jpg"); } } - + + mRenderingManager->enableLights(); // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); @@ -251,15 +263,18 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni // retrieve the x,y grid coordinates the player is in int x,y; Vector3 _pos(position.x, 0, position.z); - _pos = mCameraRotNode->convertWorldToLocalPosition(_pos); - - //if (mInterior) - /// \todo - Vector2 pos(_pos.x, _pos.z); + if (mInterior) + { + pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle); + } + + Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); + Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); + if (!mInterior) { x = std::ceil(pos.x / sSize)-1; @@ -269,8 +284,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni } else { - Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - x = std::ceil((pos.x - min.x)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1; @@ -288,16 +301,12 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni } else { - Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); - u = (pos.x - min.x - sSize*x)/sSize; v = (pos.y - min.y - sSize*y)/sSize; texName = mInteriorName + "_" + coordStr(x,y); } - //std::cout << " x,y " << x << ", " << y << " u,v " << u << "," << v << std::endl; - mEnvironment->mWindowManager->setPlayerPos(u, v); mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index cb294a656..95685167c 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -12,13 +12,15 @@ namespace MWWorld namespace MWRender { + class RenderingManager; + /// /// \brief Local map rendering /// class LocalMap { public: - LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env); + LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env); ~LocalMap(); /** @@ -58,6 +60,7 @@ namespace MWRender private: OEngine::Render::OgreRenderer* mRendering; + MWRender::RenderingManager* mRenderingManager; MWWorld::Environment* mEnvironment; // 1024*1024 pixels for a cell @@ -77,6 +80,9 @@ namespace MWRender Ogre::SceneNode* mCameraPosNode; Ogre::SceneNode* mCameraRotNode; + float mAngle; + const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle); + void render(const float x, const float y, const float zlow, const float zhigh, const float xw, const float yw, diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 94ccb6e97..05b7e3b0b 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -169,6 +169,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f assert(insert); Ogre::Light *light = mRenderer.getScene()->createLight(); light->setDiffuseColour (r, g, b); + mLights.push_back(light->getName()); float cval=0.0f, lval=0.0f, qval=0.0f; @@ -274,3 +275,34 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) { return mBounds[cell]; } + +void Objects::enableLights() +{ + std::vector::iterator it = mLights.begin(); + while (it != mLights.end()) + { + if (mMwRoot->getCreator()->hasLight(*it)) + { + mMwRoot->getCreator()->getLight(*it)->setVisible(true); + ++it; + } + else + it = mLights.erase(it); + } +} + +void Objects::disableLights() +{ + std::vector::iterator it = mLights.begin(); + while (it != mLights.end()) + { + if (mMwRoot->getCreator()->hasLight(*it)) + { + mMwRoot->getCreator()->getLight(*it)->setVisible(false); + ++it; + } + else + it = mLights.erase(it); + } +} + diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 265de875b..5911aa4cc 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -16,6 +16,7 @@ class Objects{ std::map mStaticGeometry; std::map mStaticGeometrySmall; std::map mBounds; + std::vector mLights; Ogre::SceneNode* mMwRoot; bool mIsStatic; static int uniqueID; @@ -44,6 +45,9 @@ public: void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius); + void enableLights(); + void disableLights(); + Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); ///< get a bounding box that encloses all objects in the specified cell diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 18675203c..92e6d9edd 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -64,7 +64,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mSun = 0; mDebugging = new Debugging(mMwRoot, environment, engine); - mLocalMap = new MWRender::LocalMap(&mRendering, &environment); + mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment); } RenderingManager::~RenderingManager () @@ -411,4 +411,14 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) mLocalMap->saveFogOfWar(cell); } +void RenderingManager::disableLights() +{ + mObjects.disableLights(); +} + +void RenderingManager::enableLights() +{ + mObjects.enableLights(); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 81907a938..ff9cd168e 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -109,6 +109,9 @@ class RenderingManager: private RenderingInterface { void sunEnable(); void sunDisable(); + void disableLights(); + void enableLights(); + bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }; OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }; From d4a2bdfa3d33263481a82b0a3e28b98613bd5c30 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 2 Apr 2012 20:46:42 +0200 Subject: [PATCH 9/9] fix crash when hardware occlusion queries unsupporetd --- apps/openmw/mwrender/sky.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 2fdf9b2cd..781f7abd5 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -746,6 +746,7 @@ void SkyManager::setGlare(const float glare) Vector3 SkyManager::getRealSunPos() { + if (!mCreated) return Vector3(0,0,0); return mSun->getNode()->_getDerivedPosition(); }