Merge pull request #244 from OpenMW/master

Add OpenMW commits up to 19 Jul 2017
0.6.1
David Cernat 8 years ago committed by GitHub
commit b8b3856c73

@ -852,6 +852,9 @@ void OMW::Engine::go()
{ {
mViewer->eventTraversal(); mViewer->eventTraversal();
mViewer->updateTraversal(); mViewer->updateTraversal();
mEnvironment.getWorld()->updateWindowManager();
mViewer->renderingTraversals(); mViewer->renderingTraversals();
} }

@ -363,6 +363,8 @@ namespace MWBase
virtual void update (float duration, bool paused) = 0; virtual void update (float duration, bool paused) = 0;
virtual void updateWindowManager () = 0;
virtual MWWorld::Ptr placeObject (const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) = 0; virtual MWWorld::Ptr placeObject (const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) = 0;
///< copy and place an object into the gameworld at the specified cursor position ///< copy and place an object into the gameworld at the specified cursor position
/// @param object /// @param object

@ -254,7 +254,10 @@ namespace MWRender
sizeX = std::max(sizeX, 0); sizeX = std::max(sizeX, 0);
sizeY = std::max(sizeY, 0); sizeY = std::max(sizeY, 0);
mCamera->setViewport(0, mSizeY-sizeY, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY)); // NB Camera::setViewport has threading issues
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setAttributeAndModes(new osg::Viewport(0, mSizeY-sizeY, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY)));
mCamera->setStateSet(stateset);
redraw(); redraw();
} }

@ -222,6 +222,7 @@ namespace MWRender
mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile)); mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
else else
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile)); mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
mTerrain->setDefaultViewer(mViewer->getCamera());
mCamera.reset(new Camera(mViewer->getCamera())); mCamera.reset(new Camera(mViewer->getCamera()));

@ -528,6 +528,7 @@ namespace MWWorld
, mPreloadExteriorGrid(Settings::Manager::getBool("preload exterior grid", "Cells")) , mPreloadExteriorGrid(Settings::Manager::getBool("preload exterior grid", "Cells"))
, mPreloadDoors(Settings::Manager::getBool("preload doors", "Cells")) , mPreloadDoors(Settings::Manager::getBool("preload doors", "Cells"))
, mPreloadFastTravel(Settings::Manager::getBool("preload fast travel", "Cells")) , mPreloadFastTravel(Settings::Manager::getBool("preload fast travel", "Cells"))
, mPredictionTime(Settings::Manager::getFloat("prediction time", "Cells"))
{ {
mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager(), rendering.getTerrain(), rendering.getLandManager())); mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager(), rendering.getTerrain(), rendering.getLandManager()));
mPreloader->setWorkQueue(mRendering.getWorkQueue()); mPreloader->setWorkQueue(mRendering.getWorkQueue());
@ -750,7 +751,7 @@ namespace MWWorld
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
osg::Vec3f moved = playerPos - mLastPlayerPos; osg::Vec3f moved = playerPos - mLastPlayerPos;
osg::Vec3f predictedPos = playerPos + moved / dt; osg::Vec3f predictedPos = playerPos + moved / dt * mPredictionTime;
if (mCurrentCell->isExterior()) if (mCurrentCell->isExterior())
exteriorPositions.push_back(predictedPos); exteriorPositions.push_back(predictedPos);

@ -67,6 +67,7 @@ namespace MWWorld
bool mPreloadExteriorGrid; bool mPreloadExteriorGrid;
bool mPreloadDoors; bool mPreloadDoors;
bool mPreloadFastTravel; bool mPreloadFastTravel;
float mPredictionTime;
osg::Vec3f mLastPlayerPos; osg::Vec3f mLastPlayerPos;

@ -1711,16 +1711,14 @@ namespace MWWorld
if (!paused) if (!paused)
doPhysics (duration); doPhysics (duration);
updatePlayer(paused);
mPhysics->debugDraw(); mPhysics->debugDraw();
mWorldScene->update (duration, paused); mWorldScene->update (duration, paused);
updateWindowManager ();
updateSoundListener(); updateSoundListener();
updatePlayer(paused);
mSpellPreloadTimer -= duration; mSpellPreloadTimer -= duration;
if (mSpellPreloadTimer <= 0.f) if (mSpellPreloadTimer <= 0.f)
{ {

@ -130,7 +130,6 @@ namespace MWWorld
Ptr copyObjectToCell(const ConstPtr &ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos); Ptr copyObjectToCell(const ConstPtr &ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos);
void updateSoundListener(); void updateSoundListener();
void updateWindowManager ();
void updatePlayer(bool paused); void updatePlayer(bool paused);
void preloadSpells(); void preloadSpells();
@ -465,6 +464,8 @@ namespace MWWorld
virtual void update (float duration, bool paused); virtual void update (float duration, bool paused);
virtual void updateWindowManager ();
virtual MWWorld::Ptr placeObject (const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount); virtual MWWorld::Ptr placeObject (const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount);
///< copy and place an object into the gameworld at the specified cursor position ///< copy and place an object into the gameworld at the specified cursor position
/// @param object /// @param object

@ -99,8 +99,10 @@ void QuadTreeNode::traverse(osg::NodeVisitor &nv)
if (!hasValidBounds()) if (!hasValidBounds())
return; return;
if ((mLodCallback && mLodCallback->isSufficientDetail(this, nv.getEyePoint())) || !getNumChildren()) ViewData* vd = getView(nv);
getView(nv)->add(this, true);
if ((mLodCallback && mLodCallback->isSufficientDetail(this, vd->getEyePoint())) || !getNumChildren())
vd->add(this, true);
else else
osg::Group::traverse(nv); osg::Group::traverse(nv);
} }
@ -130,11 +132,20 @@ ViewData* QuadTreeNode::getView(osg::NodeVisitor &nv)
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR) if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);
return mViewDataMap->getViewData(cv->getCurrentCamera(), true); ViewData* vd = mViewDataMap->getViewData(cv->getCurrentCamera());
vd->setEyePoint(nv.getEyePoint());
return vd;
} }
else // INTERSECTION_VISITOR else // INTERSECTION_VISITOR
{ {
return mViewDataMap->getViewData(&nv, (nv.referenceCount() > 0)); // if no referenceCount, the visitor was allocated on the stack static osg::ref_ptr<osg::Object> dummyObj = new osg::DummyObject;
ViewData* vd = mViewDataMap->getViewData(dummyObj.get());
ViewData* defaultView = mViewDataMap->getDefaultView();
if (defaultView->hasEyePoint())
vd->setEyePoint(defaultView->getEyePoint());
else
vd->setEyePoint(nv.getEyePoint());
return vd;
} }
} }

@ -456,5 +456,10 @@ void QuadTreeWorld::reportStats(unsigned int frameNumber, osg::Stats *stats)
stats->setAttribute(frameNumber, "Composite", mCompositeMapRenderer->getCompileSetSize()); stats->setAttribute(frameNumber, "Composite", mCompositeMapRenderer->getCompileSetSize());
} }
void QuadTreeWorld::setDefaultViewer(osg::Object *obj)
{
mViewDataMap->setDefaultViewer(obj);
}
} }

@ -33,6 +33,8 @@ namespace Terrain
void reportStats(unsigned int frameNumber, osg::Stats* stats); void reportStats(unsigned int frameNumber, osg::Stats* stats);
virtual void setDefaultViewer(osg::Object* obj);
private: private:
void ensureQuadTreeBuilt(); void ensureQuadTreeBuilt();

@ -7,6 +7,7 @@ ViewData::ViewData()
: mNumEntries(0) : mNumEntries(0)
, mFrameLastUsed(0) , mFrameLastUsed(0)
, mChanged(false) , mChanged(false)
, mHasEyePoint(false)
{ {
} }
@ -43,6 +44,22 @@ bool ViewData::hasChanged() const
return mChanged; return mChanged;
} }
bool ViewData::hasEyePoint() const
{
return mHasEyePoint;
}
void ViewData::setEyePoint(const osg::Vec3f &eye)
{
mEyePoint = eye;
mHasEyePoint = true;
}
const osg::Vec3f& ViewData::getEyePoint() const
{
return mEyePoint;
}
void ViewData::reset(unsigned int frame) void ViewData::reset(unsigned int frame)
{ {
// clear any unused entries // clear any unused entries
@ -95,14 +112,13 @@ bool ViewData::Entry::set(QuadTreeNode *node, bool visible)
} }
} }
ViewData *ViewDataMap::getViewData(osg::Object *viewer, bool ref) ViewData *ViewDataMap::getViewData(osg::Object *viewer)
{ {
Map::const_iterator found = mViews.find(viewer); Map::const_iterator found = mViews.find(viewer);
if (found == mViews.end()) if (found == mViews.end())
{ {
ViewData* vd = createOrReuseView(); ViewData* vd = createOrReuseView();
if (ref) vd->setViewer(viewer);
vd->setViewer(viewer);
mViews[viewer] = vd; mViews[viewer] = vd;
return vd; return vd;
} }
@ -130,8 +146,7 @@ void ViewDataMap::clearUnusedViews(unsigned int frame)
for (Map::iterator it = mViews.begin(); it != mViews.end(); ) for (Map::iterator it = mViews.begin(); it != mViews.end(); )
{ {
ViewData* vd = it->second; ViewData* vd = it->second;
if ((!vd->getViewer() // if no ref was held, always need to clear to avoid holding a dangling ref. if (vd->getFrameLastUsed() + 2 < frame)
|| vd->getFrameLastUsed() + 2 < frame))
{ {
vd->setViewer(NULL); vd->setViewer(NULL);
vd->clear(); vd->clear();
@ -150,5 +165,15 @@ void ViewDataMap::clear()
mViewVector.clear(); mViewVector.clear();
} }
void ViewDataMap::setDefaultViewer(osg::Object *viewer)
{
mDefaultViewer = viewer;
}
ViewData* ViewDataMap::getDefaultView()
{
return getViewData(mDefaultViewer);
}
} }

@ -52,18 +52,25 @@ namespace Terrain
/// @return Have any nodes changed since the last frame /// @return Have any nodes changed since the last frame
bool hasChanged() const; bool hasChanged() const;
bool hasEyePoint() const;
void setEyePoint(const osg::Vec3f& eye);
const osg::Vec3f& getEyePoint() const;
private: private:
std::vector<Entry> mEntries; std::vector<Entry> mEntries;
unsigned int mNumEntries; unsigned int mNumEntries;
unsigned int mFrameLastUsed; unsigned int mFrameLastUsed;
bool mChanged; bool mChanged;
osg::ref_ptr<osg::Object> mViewer; osg::ref_ptr<osg::Object> mViewer;
osg::Vec3f mEyePoint;
bool mHasEyePoint;
}; };
class ViewDataMap : public osg::Referenced class ViewDataMap : public osg::Referenced
{ {
public: public:
ViewData* getViewData(osg::Object* viewer, bool ref); ViewData* getViewData(osg::Object* viewer);
ViewData* createOrReuseView(); ViewData* createOrReuseView();
@ -71,6 +78,10 @@ namespace Terrain
void clear(); void clear();
void setDefaultViewer(osg::Object* viewer);
ViewData* getDefaultView();
private: private:
std::list<ViewData> mViewVector; std::list<ViewData> mViewVector;
@ -78,6 +89,8 @@ namespace Terrain
Map mViews; Map mViews;
std::deque<ViewData*> mUnusedViews; std::deque<ViewData*> mUnusedViews;
osg::ref_ptr<osg::Object> mDefaultViewer;
}; };
} }

@ -14,6 +14,7 @@ namespace osg
class Group; class Group;
class Stats; class Stats;
class Node; class Node;
class Object;
} }
namespace Resource namespace Resource
@ -87,6 +88,9 @@ namespace Terrain
virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) {} virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) {}
/// Set the default viewer (usually a Camera), used as viewpoint for any viewers that don't use their own viewpoint.
virtual void setDefaultViewer(osg::Object* obj) {}
Storage* getStorage() { return mStorage; } Storage* getStorage() { return mStorage; }
protected: protected:

@ -155,6 +155,19 @@ preload cell expiry delay
The amount of time (in seconds) that a preloaded cell will stay in cache after it is no longer referenced or required, The amount of time (in seconds) that a preloaded cell will stay in cache after it is no longer referenced or required,
for example, after the player has moved away from a door without entering it. for example, after the player has moved away from a door without entering it.
prediction time
---------------
:Type: floating point
:Range: >=0
:Default: 1
The amount of time (in seconds) in the future to predict the player position for. This predicted position is used to preload any cells and/or distant terrain required at that position.
This setting will only have an effect if 'preload enabled' is set or the 'distant terrain' in the Terrain section is set.
Increasing this setting from its default may help if your computer/hard disk is too slow to preload in time and you see loading screens and/or lag spikes.
cache expiry delay cache expiry delay
------------------ ------------------

@ -73,6 +73,9 @@ preload cell cache max = 20
# How long to keep preloaded cells in cache after they're no longer referenced/required (in seconds) # How long to keep preloaded cells in cache after they're no longer referenced/required (in seconds)
preload cell expiry delay = 5 preload cell expiry delay = 5
# The predicted position of the player N seconds in the future will be used for preloading cells and distant terrain
prediction time = 1
# How long to keep models/textures/collision shapes in cache after they're no longer referenced/required (in seconds) # How long to keep models/textures/collision shapes in cache after they're no longer referenced/required (in seconds)
cache expiry delay = 5 cache expiry delay = 5

Loading…
Cancel
Save