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); + Vector2 pos(_pos.x, _pos.z); - //if (mInterior) - /// \todo + if (mInterior) + { + pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle); + } - Vector2 pos(_pos.x, _pos.z); 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; };