forked from teamnwah/openmw-tes3coop
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