Merge pull request #244 from OpenMW/master

Add OpenMW commits up to 19 Jul 2017
This commit is contained in:
David Cernat 2017-07-19 20:49:56 +03:00 committed by GitHub
commit b8b3856c73
16 changed files with 103 additions and 17 deletions

View file

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

View file

@ -363,6 +363,8 @@ namespace MWBase
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;
///< copy and place an object into the gameworld at the specified cursor position
/// @param object

View file

@ -254,7 +254,10 @@ namespace MWRender
sizeX = std::max(sizeX, 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();
}

View file

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

View file

@ -528,6 +528,7 @@ namespace MWWorld
, mPreloadExteriorGrid(Settings::Manager::getBool("preload exterior grid", "Cells"))
, mPreloadDoors(Settings::Manager::getBool("preload doors", "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->setWorkQueue(mRendering.getWorkQueue());
@ -750,7 +751,7 @@ namespace MWWorld
const MWWorld::ConstPtr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
osg::Vec3f moved = playerPos - mLastPlayerPos;
osg::Vec3f predictedPos = playerPos + moved / dt;
osg::Vec3f predictedPos = playerPos + moved / dt * mPredictionTime;
if (mCurrentCell->isExterior())
exteriorPositions.push_back(predictedPos);

View file

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

View file

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

View file

@ -130,7 +130,6 @@ namespace MWWorld
Ptr copyObjectToCell(const ConstPtr &ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos);
void updateSoundListener();
void updateWindowManager ();
void updatePlayer(bool paused);
void preloadSpells();
@ -465,6 +464,8 @@ namespace MWWorld
virtual void update (float duration, bool paused);
virtual void updateWindowManager ();
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
/// @param object

View file

@ -99,8 +99,10 @@ void QuadTreeNode::traverse(osg::NodeVisitor &nv)
if (!hasValidBounds())
return;
if ((mLodCallback && mLodCallback->isSufficientDetail(this, nv.getEyePoint())) || !getNumChildren())
getView(nv)->add(this, true);
ViewData* vd = getView(nv);
if ((mLodCallback && mLodCallback->isSufficientDetail(this, vd->getEyePoint())) || !getNumChildren())
vd->add(this, true);
else
osg::Group::traverse(nv);
}
@ -130,11 +132,20 @@ ViewData* QuadTreeNode::getView(osg::NodeVisitor &nv)
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
{
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
{
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;
}
}

View file

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

View file

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

View file

@ -7,6 +7,7 @@ ViewData::ViewData()
: mNumEntries(0)
, mFrameLastUsed(0)
, mChanged(false)
, mHasEyePoint(false)
{
}
@ -43,6 +44,22 @@ bool ViewData::hasChanged() const
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)
{
// 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);
if (found == mViews.end())
{
ViewData* vd = createOrReuseView();
if (ref)
vd->setViewer(viewer);
vd->setViewer(viewer);
mViews[viewer] = vd;
return vd;
}
@ -130,8 +146,7 @@ void ViewDataMap::clearUnusedViews(unsigned int frame)
for (Map::iterator it = mViews.begin(); it != mViews.end(); )
{
ViewData* vd = it->second;
if ((!vd->getViewer() // if no ref was held, always need to clear to avoid holding a dangling ref.
|| vd->getFrameLastUsed() + 2 < frame))
if (vd->getFrameLastUsed() + 2 < frame)
{
vd->setViewer(NULL);
vd->clear();
@ -150,5 +165,15 @@ void ViewDataMap::clear()
mViewVector.clear();
}
void ViewDataMap::setDefaultViewer(osg::Object *viewer)
{
mDefaultViewer = viewer;
}
ViewData* ViewDataMap::getDefaultView()
{
return getViewData(mDefaultViewer);
}
}

View file

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

View file

@ -14,6 +14,7 @@ namespace osg
class Group;
class Stats;
class Node;
class Object;
}
namespace Resource
@ -87,6 +88,9 @@ namespace Terrain
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; }
protected:

View file

@ -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,
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
------------------

View file

@ -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)
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)
cache expiry delay = 5