mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +00:00 
			
		
		
		
	Merge remote-tracking branch 'blunted2night/bug_495_v2'
This commit is contained in:
		
						commit
						649ae645f3
					
				
					 10 changed files with 268 additions and 161 deletions
				
			
		|  | @ -336,7 +336,8 @@ void OMW::Engine::go() | |||
| 
 | ||||
|     // Create the world
 | ||||
|     mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, | ||||
|         mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap)); | ||||
|         mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap, | ||||
|         mActivationDistanceOverride)); | ||||
| 
 | ||||
|     //Load translation data
 | ||||
|     mTranslationDataStorage.setEncoder(&encoder); | ||||
|  | @ -427,12 +428,7 @@ void OMW::Engine::activate() | |||
|     if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|         return; | ||||
| 
 | ||||
|     std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||
| 
 | ||||
|     if (handle.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle (handle); | ||||
|     MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getFacedObject(); | ||||
| 
 | ||||
|     if (ptr.isEmpty()) | ||||
|         return; | ||||
|  | @ -514,3 +510,9 @@ void OMW::Engine::setStartupScript (const std::string& path) | |||
| { | ||||
|     mStartupScript = path; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void OMW::Engine::setActivationDistanceOverride (int distance) | ||||
| { | ||||
|     mActivationDistanceOverride = distance; | ||||
| } | ||||
|  |  | |||
|  | @ -76,6 +76,7 @@ namespace OMW | |||
|             std::map<std::string,std::string> mFallbackMap; | ||||
|             bool mScriptConsoleMode; | ||||
|             std::string mStartupScript; | ||||
|             int mActivationDistanceOverride; | ||||
| 
 | ||||
|             Compiler::Extensions mExtensions; | ||||
|             Compiler::Context *mScriptContext; | ||||
|  | @ -167,6 +168,9 @@ namespace OMW | |||
|             /// Set path for a script that is run on startup in the console.
 | ||||
|             void setStartupScript (const std::string& path); | ||||
| 
 | ||||
|             /// Override the game setting specified activation distance.
 | ||||
|             void setActivationDistanceOverride (int distance); | ||||
| 
 | ||||
|         private: | ||||
|             Files::ConfigurationManager& mCfgMgr; | ||||
|     }; | ||||
|  |  | |||
|  | @ -149,6 +149,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat | |||
|         ("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "") | ||||
|             ->multitoken()->composing(), "fallback values") | ||||
| 
 | ||||
|         ("activate-dist", bpo::value <int> ()->default_value (-1), "activation distance override"); | ||||
| 
 | ||||
|         ; | ||||
| 
 | ||||
|     bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) | ||||
|  | @ -236,6 +238,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat | |||
|     engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap); | ||||
|     engine.setScriptConsoleMode (variables["script-console"].as<bool>()); | ||||
|     engine.setStartupScript (variables["script-run"].as<std::string>()); | ||||
|     engine.setActivationDistanceOverride (variables["activate-dist"].as<int>()); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  |  | |||
|  | @ -199,8 +199,8 @@ namespace MWBase | |||
| 
 | ||||
|             virtual void markCellAsUnchanged() = 0; | ||||
| 
 | ||||
|             virtual std::string getFacedHandle() = 0; | ||||
|             ///< Return handle of the object the player is looking at
 | ||||
|             virtual MWWorld::Ptr  getFacedObject() = 0; | ||||
|             ///< Return pointer to the object the player is looking at, if it is within activation range
 | ||||
| 
 | ||||
|             virtual void deleteObject (const MWWorld::Ptr& ptr) = 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -244,8 +244,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) | |||
|         if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) ) | ||||
|             return; | ||||
| 
 | ||||
|         std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||
|         MWWorld::Ptr object = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); | ||||
|         MWWorld::Ptr object = MWBase::Environment::get().getWorld()->getFacedObject(); | ||||
| 
 | ||||
|         if (mode == GM_Console) | ||||
|             MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object); | ||||
|  |  | |||
|  | @ -80,9 +80,8 @@ void ToolTips::onFrame(float frameDuration) | |||
|             || (mWindowManager->getMode() == GM_Container) | ||||
|             || (mWindowManager->getMode() == GM_Inventory))) | ||||
|         { | ||||
|             std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||
|             mFocusObject = MWBase::Environment::get().getWorld()->getFacedObject(); | ||||
| 
 | ||||
|             mFocusObject = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle); | ||||
|             if (mFocusObject.isEmpty ()) | ||||
|                 return; | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ namespace MWWorld | |||
|         return mEngine; | ||||
|     } | ||||
| 
 | ||||
|     std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world) | ||||
|     std::pair<float, std::string> PhysicsSystem::getFacedHandle (MWWorld::World& world, float queryDistance) | ||||
|     { | ||||
|         btVector3 dir(0, 1, 0); | ||||
|         dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); | ||||
|  | @ -56,11 +56,14 @@ namespace MWWorld | |||
|             mPlayerData.eyepos.z); | ||||
|         origin += dir * 5; | ||||
| 
 | ||||
|         btVector3 dest = origin + dir * 500; | ||||
|         return mEngine->rayTest(origin, dest); | ||||
|         btVector3 dest = origin + dir * queryDistance; | ||||
|         std::pair <std::string, float> result; | ||||
|         /*auto*/ result = mEngine->rayTest(origin, dest); | ||||
|         result.second *= queryDistance; | ||||
|         return std::make_pair (result.second, result.first); | ||||
|     } | ||||
| 
 | ||||
|     std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects () | ||||
|     std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float queryDistance) | ||||
|     { | ||||
|         btVector3 dir(0, 1, 0); | ||||
|         dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch); | ||||
|  | @ -73,22 +76,32 @@ namespace MWWorld | |||
|             mPlayerData.eyepos.z); | ||||
|         origin += dir * 5; | ||||
| 
 | ||||
|         btVector3 dest = origin + dir * 500; | ||||
|         return mEngine->rayTest2(origin, dest); | ||||
|         btVector3 dest = origin + dir * queryDistance; | ||||
|         std::vector < std::pair <float, std::string> > results; | ||||
|         /* auto */ results = mEngine->rayTest2(origin, dest); | ||||
|         std::vector < std::pair <float, std::string> >::iterator i; | ||||
|         for (/* auto */ i = results.begin (); i != results.end (); ++i) | ||||
|             i->first *= queryDistance; | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
|     std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects (float mouseX, float mouseY) | ||||
|     std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedHandles (float mouseX, float mouseY, float queryDistance) | ||||
|     { | ||||
|         Ray ray = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY); | ||||
|         Ogre::Vector3 from = ray.getOrigin(); | ||||
|         Ogre::Vector3 to = ray.getPoint(500); /// \todo make this distance (ray length) configurable
 | ||||
|         Ogre::Vector3 to = ray.getPoint(queryDistance); | ||||
| 
 | ||||
|         btVector3 _from, _to; | ||||
|         // OGRE to MW coordinates
 | ||||
|         _from = btVector3(from.x, -from.z, from.y); | ||||
|         _to = btVector3(to.x, -to.z, to.y); | ||||
| 
 | ||||
|         return mEngine->rayTest2(_from,_to); | ||||
|         std::vector < std::pair <float, std::string> > results; | ||||
|         /* auto */ results = mEngine->rayTest2(_from,_to); | ||||
|         std::vector < std::pair <float, std::string> >::iterator i; | ||||
|         for (/* auto */ i = results.begin (); i != results.end (); ++i) | ||||
|             i->first *= queryDistance; | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight) | ||||
|  | @ -110,7 +123,7 @@ namespace MWWorld | |||
|         Ray centerRay = mRender.getCamera()->getCameraToViewportRay( | ||||
|         mRender.getViewport()->getWidth()/2, | ||||
|         mRender.getViewport()->getHeight()/2); | ||||
|         btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable
 | ||||
|         btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|  | @ -118,7 +131,7 @@ namespace MWWorld | |||
|     { | ||||
|         //get a ray pointing to the center of the viewport
 | ||||
|         Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY); | ||||
|         btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable
 | ||||
|         btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,14 +41,13 @@ namespace MWWorld | |||
| 
 | ||||
|             bool toggleCollisionMode(); | ||||
|              | ||||
|             std::pair<std::string, float> getFacedHandle (MWWorld::World& world); | ||||
|             std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance); | ||||
|             std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance); | ||||
|             std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance); | ||||
| 
 | ||||
|             btVector3 getRayPoint(float extent); | ||||
|             btVector3 getRayPoint(float extent, float mouseX, float mouseY); | ||||
| 
 | ||||
|             std::vector < std::pair <float, std::string> > getFacedObjects (); | ||||
| 
 | ||||
|             std::vector < std::pair <float, std::string> > getFacedObjects (float mouseX, float mouseY); | ||||
| 
 | ||||
|             // cast ray, return true if it hit something
 | ||||
|             bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to); | ||||
|  |  | |||
|  | @ -170,10 +170,10 @@ namespace MWWorld | |||
|     World::World (OEngine::Render::OgreRenderer& renderer, | ||||
|         const Files::Collections& fileCollections, | ||||
|         const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, | ||||
|         ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> fallbackMap) | ||||
|         ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> fallbackMap, int mActivationDistanceOverride) | ||||
|     : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), | ||||
|       mSky (true), mCells (mStore, mEsm), | ||||
|       mNumFacing(0) | ||||
|       mNumFacing(0), mActivationDistanceOverride (mActivationDistanceOverride) | ||||
|     { | ||||
|         mPhysics = new PhysicsSystem(renderer); | ||||
|         mPhysEngine = mPhysics->getEngine(); | ||||
|  | @ -573,23 +573,55 @@ namespace MWWorld | |||
|         return mWorldScene->markCellAsUnchanged(); | ||||
|     } | ||||
| 
 | ||||
|     std::string World::getFacedHandle() | ||||
|     float World::getMaxActivationDistance () | ||||
|     { | ||||
|         if (mActivationDistanceOverride >= 0) | ||||
|             return mActivationDistanceOverride; | ||||
| 
 | ||||
|         return (std::max) (getNpcActivationDistance (), getObjectActivationDistance ()); | ||||
|     } | ||||
| 
 | ||||
|     float World::getNpcActivationDistance () | ||||
|     { | ||||
|         if (mActivationDistanceOverride >= 0) | ||||
|             return mActivationDistanceOverride; | ||||
| 
 | ||||
|         return getStore().get<ESM::GameSetting>().find ("iMaxActivateDist")->getInt()*5/4; | ||||
|     } | ||||
| 
 | ||||
|     float World::getObjectActivationDistance () | ||||
|     { | ||||
|         if (mActivationDistanceOverride >= 0) | ||||
|             return mActivationDistanceOverride; | ||||
| 
 | ||||
|         return getStore().get<ESM::GameSetting>().find ("iMaxActivateDist")->getInt(); | ||||
|     } | ||||
| 
 | ||||
|     MWWorld::Ptr World::getFacedObject() | ||||
|     { | ||||
|         std::pair<float, std::string> result; | ||||
| 
 | ||||
|         if (!mRendering->occlusionQuerySupported()) | ||||
|         { | ||||
|             std::pair<std::string, float> result = mPhysics->getFacedHandle (*this); | ||||
| 
 | ||||
|             if (result.first.empty() || | ||||
|                     result.second>getStore().get<ESM::GameSetting>().find ("iMaxActivateDist")->getInt()) | ||||
|                 return ""; | ||||
| 
 | ||||
|             return result.first; | ||||
|         } | ||||
|             result = mPhysics->getFacedHandle (*this, getMaxActivationDistance ()); | ||||
|         else | ||||
|         { | ||||
|             // updated every few frames in update()
 | ||||
|             return mFacedHandle; | ||||
|         } | ||||
|             result = std::make_pair (mFacedDistance, mFacedHandle); | ||||
| 
 | ||||
|         if (result.second.empty()) | ||||
|             return MWWorld::Ptr (); | ||||
| 
 | ||||
|         MWWorld::Ptr object = searchPtrViaHandle (result.second); | ||||
| 
 | ||||
|         float ActivationDistance; | ||||
| 
 | ||||
|         if (object.getTypeName ().find("NPC") != std::string::npos) | ||||
|             ActivationDistance = getNpcActivationDistance (); | ||||
|         else | ||||
|             ActivationDistance = getObjectActivationDistance (); | ||||
| 
 | ||||
|         if (result.first > ActivationDistance) | ||||
|             return MWWorld::Ptr (); | ||||
| 
 | ||||
|         return object; | ||||
|     } | ||||
| 
 | ||||
|     void World::deleteObject (const Ptr& ptr) | ||||
|  | @ -884,8 +916,6 @@ namespace MWWorld | |||
| 
 | ||||
|     void World::update (float duration, bool paused) | ||||
|     { | ||||
|         /// \todo split this function up into subfunctions
 | ||||
| 
 | ||||
|         mWorldScene->update (duration, paused); | ||||
| 
 | ||||
|         float pitch, yaw; | ||||
|  | @ -895,8 +925,15 @@ namespace MWWorld | |||
| 
 | ||||
|         mWeatherManager->update (duration); | ||||
| 
 | ||||
|         performUpdateSceneQueries (); | ||||
| 
 | ||||
|         updateWindowManager (); | ||||
|     } | ||||
| 
 | ||||
|     void World::updateWindowManager () | ||||
|     { | ||||
|         // inform the GUI about focused object
 | ||||
|         MWWorld::Ptr object = searchPtrViaHandle(mFacedHandle); | ||||
|         MWWorld::Ptr object = getFacedObject (); | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager()->setFocusObject(object); | ||||
| 
 | ||||
|  | @ -918,7 +955,10 @@ namespace MWWorld | |||
|                     screenCoords[0], screenCoords[1], screenCoords[2], screenCoords[3]); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void World::performUpdateSceneQueries () | ||||
|     { | ||||
|         if (!mRendering->occlusionQuerySupported()) | ||||
|         { | ||||
|             // cast a ray from player to sun to detect if the sun is visible
 | ||||
|  | @ -937,121 +977,154 @@ namespace MWWorld | |||
|             MWRender::OcclusionQuery* query = mRendering->getOcclusionQuery(); | ||||
|             if (!query->occlusionTestPending()) | ||||
|             { | ||||
|                 // get result of last query
 | ||||
|                 if (mNumFacing == 0) mFacedHandle = ""; | ||||
|                 else if (mNumFacing == 1) | ||||
|                 { | ||||
|                     bool result = query->getTestResult(); | ||||
|                     mFacedHandle = result ? mFaced1Name : ""; | ||||
|                 } | ||||
|                 else if (mNumFacing == 2) | ||||
|                 { | ||||
|                     bool result = query->getTestResult(); | ||||
|                     mFacedHandle = result ? mFaced2Name : mFaced1Name; | ||||
|                 } | ||||
| 
 | ||||
|                 // send new query
 | ||||
|                 // figure out which object we want to test against
 | ||||
|                 std::vector < std::pair < float, std::string > > results; | ||||
|                 if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|                 { | ||||
|                     float x, y; | ||||
|                     MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|                     results = mPhysics->getFacedObjects(x, y); | ||||
|                 } | ||||
|                 else | ||||
|                     results = mPhysics->getFacedObjects(); | ||||
| 
 | ||||
|                 // ignore the player and other things we're not interested in
 | ||||
|                 std::vector < std::pair < float, std::string > >::iterator it = results.begin(); | ||||
|                 while (it != results.end()) | ||||
|                 { | ||||
|                     if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain
 | ||||
|                     || getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself)
 | ||||
|                     { | ||||
|                         it = results.erase(it); | ||||
|                     } | ||||
|                     else | ||||
|                         ++it; | ||||
|                 } | ||||
| 
 | ||||
|                 if (results.size() == 0) | ||||
|                 { | ||||
|                     mNumFacing = 0; | ||||
|                 } | ||||
|                 else if (results.size() == 1) | ||||
|                 { | ||||
|                     mFaced1 = getPtrViaHandle(results.front().second); | ||||
|                     mFaced1Name = results.front().second; | ||||
|                     mNumFacing = 1; | ||||
| 
 | ||||
|                     btVector3 p; | ||||
|                     if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|                     { | ||||
|                         float x, y; | ||||
|                         MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|                         p = mPhysics->getRayPoint(results.front().first, x, y); | ||||
|                     } | ||||
|                     else | ||||
|                         p = mPhysics->getRayPoint(results.front().first); | ||||
|                     Ogre::Vector3 pos(p.x(), p.z(), -p.y()); | ||||
|                     Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); | ||||
| 
 | ||||
|                     //std::cout << "Num facing 1 : " << mFaced1Name <<  std::endl;
 | ||||
|                     //std::cout << "Type 1 " << mFaced1.getTypeName() <<  std::endl;
 | ||||
| 
 | ||||
|                     query->occlusionTest(pos, node); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     mFaced1Name = results.front().second; | ||||
|                     mFaced2Name = results[1].second; | ||||
|                     mFaced1 = getPtrViaHandle(results.front().second); | ||||
|                     mFaced2 = getPtrViaHandle(results[1].second); | ||||
|                     mNumFacing = 2; | ||||
| 
 | ||||
|                     btVector3 p; | ||||
|                     if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|                     { | ||||
|                         float x, y; | ||||
|                         MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|                         p = mPhysics->getRayPoint(results[1].first, x, y); | ||||
|                     } | ||||
|                     else | ||||
|                         p = mPhysics->getRayPoint(results[1].first); | ||||
|                     Ogre::Vector3 pos(p.x(), p.z(), -p.y()); | ||||
|                     Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); | ||||
|                     Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); | ||||
| 
 | ||||
|                     // no need to test if the first node is not occluder
 | ||||
|                     if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) | ||||
|                     { | ||||
|                         mFacedHandle = mFaced1Name; | ||||
|                         //std::cout << "node1 Not an occluder" << std::endl;
 | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     // no need to test if the second object is static (thus cannot be activated)
 | ||||
|                     if (mFaced2.getTypeName().find("Static") != std::string::npos) | ||||
|                     { | ||||
|                         mFacedHandle = mFaced1Name; | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     // work around door problems
 | ||||
|                     if (mFaced1.getTypeName().find("Static") != std::string::npos | ||||
|                         && mFaced2.getTypeName().find("Door") != std::string::npos) | ||||
|                     { | ||||
|                         mFacedHandle = mFaced2Name; | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     query->occlusionTest(pos, node2); | ||||
|                 } | ||||
|                 processFacedQueryResults (query); | ||||
|                 beginFacedQueryProcess (query); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void World::processFacedQueryResults (MWRender::OcclusionQuery* query) | ||||
|     { | ||||
|         // get result of last query
 | ||||
|         if (mNumFacing == 0) | ||||
|         { | ||||
|             mFacedHandle = ""; | ||||
|             mFacedDistance = FLT_MAX; | ||||
|         } | ||||
|         else if (mNumFacing == 1) | ||||
|         { | ||||
|             bool result = query->getTestResult(); | ||||
|             mFacedHandle = result ? mFaced1Name : ""; | ||||
|             mFacedDistance = result ? mFaced1Distance : FLT_MAX; | ||||
|         } | ||||
|         else if (mNumFacing == 2) | ||||
|         { | ||||
|             bool result = query->getTestResult(); | ||||
|             mFacedHandle = result ? mFaced2Name : mFaced1Name; | ||||
|             mFacedDistance = result ? mFaced1Distance : mFaced1Distance; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void World::beginFacedQueryProcess (MWRender::OcclusionQuery* query) | ||||
|     { | ||||
|         // send new query
 | ||||
|         // figure out which object we want to test against
 | ||||
|         std::vector < std::pair < float, std::string > > results; | ||||
|         if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|         { | ||||
|             float x, y; | ||||
|             MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|             results = mPhysics->getFacedHandles(x, y, getMaxActivationDistance ()); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             results = mPhysics->getFacedHandles(getMaxActivationDistance ()); | ||||
|         } | ||||
| 
 | ||||
|         // ignore the player and other things we're not interested in
 | ||||
|         std::vector < std::pair < float, std::string > >::iterator it = results.begin(); | ||||
|         while (it != results.end()) | ||||
|         { | ||||
|             if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain
 | ||||
|             || getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself)
 | ||||
|             { | ||||
|                 it = results.erase(it); | ||||
|             } | ||||
|             else | ||||
|                 ++it; | ||||
|         } | ||||
| 
 | ||||
|         if (results.size() == 0) | ||||
|         { | ||||
|             mNumFacing = 0; | ||||
|         } | ||||
|         else if (results.size() == 1) | ||||
|         { | ||||
|             beginSingleFacedQueryProcess (query, results); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             beginDoubleFacedQueryProcess (query, results); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void World::beginSingleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results) | ||||
|     { | ||||
|         mFaced1 = getPtrViaHandle(results.front().second); | ||||
|         mFaced1Name = results.front().second; | ||||
|         mFaced1Distance = results.front().first; | ||||
|         mNumFacing = 1; | ||||
| 
 | ||||
|         btVector3 p; | ||||
|         if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|         { | ||||
|             float x, y; | ||||
|             MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|             p = mPhysics->getRayPoint(results.front().first, x, y); | ||||
|         } | ||||
|         else | ||||
|             p = mPhysics->getRayPoint(results.front().first); | ||||
|         Ogre::Vector3 pos(p.x(), p.z(), -p.y()); | ||||
|         Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); | ||||
| 
 | ||||
|         //std::cout << "Num facing 1 : " << mFaced1Name <<  std::endl;
 | ||||
|         //std::cout << "Type 1 " << mFaced1.getTypeName() <<  std::endl;
 | ||||
| 
 | ||||
|         query->occlusionTest(pos, node); | ||||
|     } | ||||
| 
 | ||||
|     void World::beginDoubleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results) | ||||
|     { | ||||
|         mFaced1Name = results.at (0).second; | ||||
|         mFaced2Name = results.at (1).second; | ||||
|         mFaced1Distance = results.at (0).first; | ||||
|         mFaced2Distance = results.at (1).first; | ||||
|         mFaced1 = getPtrViaHandle(results.at (0).second); | ||||
|         mFaced2 = getPtrViaHandle(results.at (1).second); | ||||
|         mNumFacing = 2; | ||||
| 
 | ||||
|         btVector3 p; | ||||
|         if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|         { | ||||
|             float x, y; | ||||
|             MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); | ||||
|             p = mPhysics->getRayPoint(results.at (1).first, x, y); | ||||
|         } | ||||
|         else | ||||
|             p = mPhysics->getRayPoint(results.at (1).first); | ||||
|         Ogre::Vector3 pos(p.x(), p.z(), -p.y()); | ||||
|         Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); | ||||
|         Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); | ||||
| 
 | ||||
|         // no need to test if the first node is not occluder
 | ||||
|         if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) | ||||
|         { | ||||
|             mFacedHandle = mFaced1Name; | ||||
|             mFacedDistance = mFaced1Distance; | ||||
|             //std::cout << "node1 Not an occluder" << std::endl;
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // no need to test if the second object is static (thus cannot be activated)
 | ||||
|         if (mFaced2.getTypeName().find("Static") != std::string::npos) | ||||
|         { | ||||
|             mFacedHandle = mFaced1Name; | ||||
|             mFacedDistance = mFaced1Distance; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // work around door problems
 | ||||
|         if (mFaced1.getTypeName().find("Static") != std::string::npos | ||||
|             && mFaced2.getTypeName().find("Door") != std::string::npos) | ||||
|         { | ||||
|             mFacedHandle = mFaced2Name; | ||||
|             mFacedDistance = mFaced2Distance; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         query->occlusionTest(pos, node2); | ||||
|     } | ||||
| 
 | ||||
|     bool World::isCellExterior() const | ||||
|     { | ||||
|         Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); | ||||
|  |  | |||
|  | @ -71,11 +71,15 @@ namespace MWWorld | |||
| 
 | ||||
|             Ptr getPtrViaHandle (const std::string& handle, Ptr::CellStore& cellStore); | ||||
| 
 | ||||
|             int mActivationDistanceOverride; | ||||
|             std::string mFacedHandle; | ||||
|             float mFacedDistance; | ||||
|             Ptr mFaced1; | ||||
|             Ptr mFaced2; | ||||
|             std::string mFaced1Name; | ||||
|             std::string mFaced2Name; | ||||
|             float mFaced1Distance; | ||||
|             float mFaced2Distance; | ||||
|             int mNumFacing; | ||||
|             std::map<std::string,std::string> mFallback; | ||||
| 
 | ||||
|  | @ -90,12 +94,23 @@ namespace MWWorld | |||
|             virtual void | ||||
|             copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); | ||||
| 
 | ||||
|             void updateWindowManager (); | ||||
|             void performUpdateSceneQueries (); | ||||
|             void processFacedQueryResults (MWRender::OcclusionQuery* query); | ||||
|             void beginFacedQueryProcess (MWRender::OcclusionQuery* query); | ||||
|             void beginSingleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results); | ||||
|             void beginDoubleFacedQueryProcess (MWRender::OcclusionQuery* query, std::vector < std::pair < float, std::string > > const & results); | ||||
| 
 | ||||
|             float getMaxActivationDistance (); | ||||
|             float getNpcActivationDistance (); | ||||
|             float getObjectActivationDistance (); | ||||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             World (OEngine::Render::OgreRenderer& renderer, | ||||
|                 const Files::Collections& fileCollections, | ||||
|                 const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, | ||||
|                 ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> fallbackMap); | ||||
|                 ToUTF8::Utf8Encoder* encoder, std::map<std::string,std::string> fallbackMap, int mActivationDistanceOverride); | ||||
| 
 | ||||
|             virtual ~World(); | ||||
| 
 | ||||
|  | @ -217,8 +232,8 @@ namespace MWWorld | |||
| 
 | ||||
|             virtual void markCellAsUnchanged(); | ||||
| 
 | ||||
|             virtual std::string getFacedHandle(); | ||||
|             ///< Return handle of the object the player is looking at
 | ||||
|             virtual MWWorld::Ptr getFacedObject(); | ||||
|             ///< Return pointer to the object the player is looking at, if it is within activation range
 | ||||
| 
 | ||||
|             virtual void deleteObject (const Ptr& ptr); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue