forked from mirror/openmw-tes3mp
Merge pull request #244 from OpenMW/master
Add OpenMW commits up to 19 Jul 2017
This commit is contained in:
commit
b8b3856c73
16 changed files with 103 additions and 17 deletions
|
@ -852,6 +852,9 @@ void OMW::Engine::go()
|
|||
{
|
||||
mViewer->eventTraversal();
|
||||
mViewer->updateTraversal();
|
||||
|
||||
mEnvironment.getWorld()->updateWindowManager();
|
||||
|
||||
mViewer->renderingTraversals();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace MWWorld
|
|||
bool mPreloadExteriorGrid;
|
||||
bool mPreloadDoors;
|
||||
bool mPreloadFastTravel;
|
||||
float mPredictionTime;
|
||||
|
||||
osg::Vec3f mLastPlayerPos;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ namespace Terrain
|
|||
|
||||
void reportStats(unsigned int frameNumber, osg::Stats* stats);
|
||||
|
||||
virtual void setDefaultViewer(osg::Object* obj);
|
||||
|
||||
private:
|
||||
void ensureQuadTreeBuilt();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue