diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 6385eb2c6..35a825bcd 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -38,6 +38,7 @@ namespace MWGui , mLoadingOnTime(0.0) , mImportantLabel(false) , mProgress(0) + , mShowWallpaper(true) { mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize()); @@ -104,14 +105,16 @@ namespace MWGui class CopyFramebufferToTextureCallback : public osg::Camera::DrawCallback { public: - CopyFramebufferToTextureCallback(osg::Texture2D* texture, int w, int h) - : mTexture(texture), mWidth(w), mHeight(h) + CopyFramebufferToTextureCallback(osg::Texture2D* texture) + : mTexture(texture) { } virtual void operator () (osg::RenderInfo& renderInfo) const { - mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, mWidth, mHeight); + int w = renderInfo.getCurrentCamera()->getViewport()->width(); + int h = renderInfo.getCurrentCamera()->getViewport()->height(); + mTexture->copyTexImage2D(*renderInfo.getState(), 0, 0, w, h); // Callback removes itself when done if (renderInfo.getCurrentCamera()) @@ -120,7 +123,12 @@ namespace MWGui private: osg::ref_ptr mTexture; - int mWidth, mHeight; + }; + + class DontComputeBoundCallback : public osg::Node::ComputeBoundingSphereCallback + { + public: + virtual osg::BoundingSphere computeBound(const osg::Node&) const { return osg::BoundingSphere(); } }; void LoadingScreen::loadingOn() @@ -136,45 +144,21 @@ namespace MWGui mViewer->getIncrementalCompileOperation()->setTargetFrameRate(mTargetFrameRate); } - bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() - == MWBase::StateManager::State_NoGame); - - if (!showWallpaper) - { - // Copy the current framebuffer onto a texture and display that texture as the background image - // Note, we could also set the camera to disable clearing and have the background image transparent, - // but then we get shaking effects on buffer swaps. - - if (!mTexture) - { - mTexture = new osg::Texture2D; - mTexture->setInternalFormat(GL_RGB); - mTexture->setResizeNonPowerOfTwoHint(false); - } - - int width = mViewer->getCamera()->getViewport()->width(); - int height = mViewer->getCamera()->getViewport()->height(); - mViewer->getCamera()->setInitialDrawCallback(new CopyFramebufferToTextureCallback(mTexture, width, height)); - - if (!mGuiTexture.get()) - { - mGuiTexture.reset(new osgMyGUI::OSGTexture(mTexture)); - } + // Assign dummy bounding sphere callback to avoid the bounding sphere of the entire scene being recomputed after each frame of loading + // We are already using node masks to avoid the scene from being updated/rendered, but node masks don't work for computeBound() + mViewer->getSceneData()->setComputeBoundingSphereCallback(new DontComputeBoundCallback); - mBackgroundImage->setBackgroundImage(""); - - mBackgroundImage->setRenderItemTexture(mGuiTexture.get()); - mBackgroundImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); - } + mShowWallpaper = (MWBase::Environment::get().getStateManager()->getState() + == MWBase::StateManager::State_NoGame); setVisible(true); - if (showWallpaper) + if (mShowWallpaper) { changeWallpaper(); } - MWBase::Environment::get().getWindowManager()->pushGuiMode(showWallpaper ? GM_LoadingWallpaper : GM_Loading); + MWBase::Environment::get().getWindowManager()->pushGuiMode(mShowWallpaper ? GM_LoadingWallpaper : GM_Loading); } void LoadingScreen::loadingOff() @@ -192,6 +176,9 @@ namespace MWGui else mImportantLabel = false; // label was already shown on loading screen + mViewer->getSceneData()->setComputeBoundingSphereCallback(NULL); + mViewer->getSceneData()->dirtyBound(); + //std::cout << "loading took " << mTimer.time_m() - mLoadingOnTime << std::endl; setVisible(false); @@ -260,26 +247,53 @@ namespace MWGui diff -= mProgress / static_cast(mProgressBar->getScrollRange()) * 100.f; } - bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() - == MWBase::StateManager::State_NoGame); - if (!showWallpaper && diff < initialDelay*1000) + if (!mShowWallpaper && diff < initialDelay*1000) return false; return true; } + void LoadingScreen::setupCopyFramebufferToTextureCallback() + { + // Copy the current framebuffer onto a texture and display that texture as the background image + // Note, we could also set the camera to disable clearing and have the background image transparent, + // but then we get shaking effects on buffer swaps. + + if (!mTexture) + { + mTexture = new osg::Texture2D; + mTexture->setInternalFormat(GL_RGB); + mTexture->setResizeNonPowerOfTwoHint(false); + } + + if (!mGuiTexture.get()) + { + mGuiTexture.reset(new osgMyGUI::OSGTexture(mTexture)); + } + + mViewer->getCamera()->setInitialDrawCallback(new CopyFramebufferToTextureCallback(mTexture)); + + mBackgroundImage->setBackgroundImage(""); + + mBackgroundImage->setRenderItemTexture(mGuiTexture.get()); + mBackgroundImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); + } + void LoadingScreen::draw() { if (!needToDrawLoadingScreen()) return; - bool showWallpaper = (MWBase::Environment::get().getStateManager()->getState() - == MWBase::StateManager::State_NoGame); - if (showWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000*1) + if (mShowWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000*1) { mLastWallpaperChangeTime = mTimer.time_m(); changeWallpaper(); } + if (!mShowWallpaper && mLastRenderTime < mLoadingOnTime) + { + setupCopyFramebufferToTextureCallback(); + } + // Turn off rendering except the GUI int oldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask(); int oldCullMask = mViewer->getCamera()->getCullMask(); diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index a7f7d3619..0b7edbc9e 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -47,6 +47,8 @@ namespace MWGui void findSplashScreens(); bool needToDrawLoadingScreen(); + void setupCopyFramebufferToTextureCallback(); + const VFS::Manager* mVFS; osg::ref_ptr mViewer; @@ -61,6 +63,8 @@ namespace MWGui size_t mProgress; + bool mShowWallpaper; + MyGUI::Widget* mLoadingBox; MyGUI::TextBox* mLoadingText; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e7227178f..d0806b511 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -179,6 +179,15 @@ namespace { } + virtual void apply(osg::Group& node) + { + traverse(node); + } + virtual void apply(osg::MatrixTransform& node) + { + traverse(node); + } + void remove() { for (RemoveVec::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it) diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 36a0f4085..a90de2589 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -1,5 +1,9 @@ #include "creatureanimation.hpp" +#include + +#include + #include #include @@ -9,6 +13,8 @@ #include #include +#include + #include "../mwbase/world.hpp" #include "../mwworld/class.hpp" @@ -107,39 +113,51 @@ void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) else bonename = "Shield Bone"; - osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item)); - osg::ref_ptr attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename); - mResourceSystem->getSceneManager()->notifyAttached(attached); - - scene.reset(new PartHolder(attached)); - - if (!item.getClass().getEnchantment(item).empty()) - addGlow(attached, getEnchantmentColor(item)); - - // Crossbows start out with a bolt attached - // FIXME: code duplicated from NpcAnimation - if (slot == MWWorld::InventoryStore::Slot_CarriedRight && - item.getTypeName() == typeid(ESM::Weapon).name() && - item.get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) + try { - MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo != inv.end() && ammo->get()->mBase->mData.mType == ESM::Weapon::Bolt) - attachArrow(); + osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item)); + + const NodeMap& nodeMap = getNodeMap(); + NodeMap::const_iterator found = getNodeMap().find(Misc::StringUtils::lowerCase(bonename)); + if (found == nodeMap.end()) + throw std::runtime_error("Can't find attachment node " + bonename); + osg::ref_ptr attached = SceneUtil::attach(node, mObjectRoot, bonename, found->second.get()); + mResourceSystem->getSceneManager()->notifyAttached(attached); + + scene.reset(new PartHolder(attached)); + + if (!item.getClass().getEnchantment(item).empty()) + addGlow(attached, getEnchantmentColor(item)); + + // Crossbows start out with a bolt attached + // FIXME: code duplicated from NpcAnimation + if (slot == MWWorld::InventoryStore::Slot_CarriedRight && + item.getTypeName() == typeid(ESM::Weapon).name() && + item.get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) + { + MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo != inv.end() && ammo->get()->mBase->mData.mType == ESM::Weapon::Bolt) + attachArrow(); + else + mAmmunition.reset(); + } else mAmmunition.reset(); - } - else - mAmmunition.reset(); - boost::shared_ptr source; + boost::shared_ptr source; - if (slot == MWWorld::InventoryStore::Slot_CarriedRight) - source = mWeaponAnimationTime; - else - source.reset(new NullAnimationTime); + if (slot == MWWorld::InventoryStore::Slot_CarriedRight) + source = mWeaponAnimationTime; + else + source.reset(new NullAnimationTime); - SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); - attached->accept(assignVisitor); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); + attached->accept(assignVisitor); + } + catch (std::exception& e) + { + std::cerr << "Error adding creature part: " << e.what() << std::endl; + } } void CreatureWeaponAnimation::attachArrow() diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 53eaf0996..8f87c46fb 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -667,10 +667,18 @@ void NpcAnimation::updateParts() attachArrow(); } + + PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, const std::string& bonename, const std::string& bonefilter, bool enchantedGlow, osg::Vec4f* glowColor) { osg::ref_ptr instance = mResourceSystem->getSceneManager()->getInstance(model); - osg::ref_ptr attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, bonename); + + const NodeMap& nodeMap = getNodeMap(); + NodeMap::const_iterator found = nodeMap.find(Misc::StringUtils::lowerCase(bonename)); + if (found == nodeMap.end()) + throw std::runtime_error("Can't find attachment node " + bonename); + + osg::ref_ptr attached = SceneUtil::attach(instance, mObjectRoot, bonefilter, found->second); mResourceSystem->getSceneManager()->notifyAttached(attached); if (enchantedGlow) addGlow(attached, *glowColor); @@ -770,43 +778,46 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g } } - boost::shared_ptr src; - if (type == ESM::PRT_Head) + osg::Node* node = mObjectParts[type]->getNode(); + if (node->getNumChildrenRequiringUpdateTraversal() > 0) { - src = mHeadAnimationTime; - - osg::Node* node = mObjectParts[type]->getNode(); - if (node->getUserDataContainer()) + boost::shared_ptr src; + if (type == ESM::PRT_Head) { - for (unsigned int i=0; igetUserDataContainer()->getNumUserObjects(); ++i) + src = mHeadAnimationTime; + + if (node->getUserDataContainer()) { - osg::Object* obj = node->getUserDataContainer()->getUserObject(i); - if (NifOsg::TextKeyMapHolder* keys = dynamic_cast(obj)) + for (unsigned int i=0; igetUserDataContainer()->getNumUserObjects(); ++i) { - for (NifOsg::TextKeyMap::const_iterator it = keys->mTextKeys.begin(); it != keys->mTextKeys.end(); ++it) + osg::Object* obj = node->getUserDataContainer()->getUserObject(i); + if (NifOsg::TextKeyMapHolder* keys = dynamic_cast(obj)) { - if (Misc::StringUtils::ciEqual(it->second, "talk: start")) - mHeadAnimationTime->setTalkStart(it->first); - if (Misc::StringUtils::ciEqual(it->second, "talk: stop")) - mHeadAnimationTime->setTalkStop(it->first); - if (Misc::StringUtils::ciEqual(it->second, "blink: start")) - mHeadAnimationTime->setBlinkStart(it->first); - if (Misc::StringUtils::ciEqual(it->second, "blink: stop")) - mHeadAnimationTime->setBlinkStop(it->first); + for (NifOsg::TextKeyMap::const_iterator it = keys->mTextKeys.begin(); it != keys->mTextKeys.end(); ++it) + { + if (Misc::StringUtils::ciEqual(it->second, "talk: start")) + mHeadAnimationTime->setTalkStart(it->first); + if (Misc::StringUtils::ciEqual(it->second, "talk: stop")) + mHeadAnimationTime->setTalkStop(it->first); + if (Misc::StringUtils::ciEqual(it->second, "blink: start")) + mHeadAnimationTime->setBlinkStart(it->first); + if (Misc::StringUtils::ciEqual(it->second, "blink: stop")) + mHeadAnimationTime->setBlinkStop(it->first); + } + + break; } - - break; } } } - } - else if (type == ESM::PRT_Weapon) - src = mWeaponAnimationTime; - else - src.reset(new NullAnimationTime); + else if (type == ESM::PRT_Weapon) + src = mWeaponAnimationTime; + else + src.reset(new NullAnimationTime); - SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); - mObjectParts[type]->getNode()->accept(assignVisitor); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); + node->accept(assignVisitor); + } return true; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5b17bf3b7..7bb72ae5d 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -158,7 +158,6 @@ namespace MWRender : mViewer(viewer) , mRootNode(rootNode) , mResourceSystem(resourceSystem) - , mWorkQueue(new SceneUtil::WorkQueue) , mUnrefQueue(new SceneUtil::UnrefQueue) , mFogDepth(0.f) , mUnderwaterColor(fallback->getFallbackColour("Water_UnderwaterColor")) @@ -169,6 +168,11 @@ namespace MWRender , mFieldOfViewOverride(0.f) , mFieldOfViewOverridden(false) { + int numThreads = Settings::Manager::getInt("preload num threads", "Cells"); + if (numThreads <= 0) + throw std::runtime_error("Invalid setting: 'preload num threads' must be >0"); + mWorkQueue = new SceneUtil::WorkQueue(numThreads); + resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); resourceSystem->getSceneManager()->setForceShaders(Settings::Manager::getBool("force shaders", "Shaders")); diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 7524fefd8..f767c6254 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -240,7 +241,15 @@ namespace MWWorld void CellPreloader::notifyLoaded(CellStore *cell) { - mPreloadCells.erase(cell); + PreloadMap::iterator found = mPreloadCells.find(cell); + if (found != mPreloadCells.end()) + { + // do the deletion in the background thread + if (found->second.mWorkItem) + mUnrefQueue->push(mPreloadCells[cell].mWorkItem); + + mPreloadCells.erase(found); + } } void CellPreloader::updateCache(double timestamp) @@ -291,4 +300,9 @@ namespace MWWorld mWorkQueue = workQueue; } + void CellPreloader::setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue) + { + mUnrefQueue = unrefQueue; + } + } diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index e45f92735..3836b6869 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -16,6 +16,11 @@ namespace Terrain class World; } +namespace SceneUtil +{ + class UnrefQueue; +} + namespace MWWorld { class CellStore; @@ -51,11 +56,14 @@ namespace MWWorld void setWorkQueue(osg::ref_ptr workQueue); + void setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue); + private: Resource::ResourceSystem* mResourceSystem; Resource::BulletShapeManager* mBulletShapeManager; Terrain::World* mTerrain; osg::ref_ptr mWorkQueue; + osg::ref_ptr mUnrefQueue; double mExpiryDelay; unsigned int mMinCacheSize; unsigned int mMaxCacheSize; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 2932aac2c..8749607fa 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -491,6 +491,7 @@ namespace MWWorld mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager(), rendering.getTerrain())); mPreloader->setWorkQueue(mRendering.getWorkQueue()); + mPreloader->setUnrefQueue(rendering.getUnrefQueue()); mPhysics->setUnrefQueue(rendering.getUnrefQueue()); rendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells")); diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 0259b27e4..fa0fe0be3 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -315,7 +316,22 @@ FindGroupByRecIndex::FindGroupByRecIndex(int recIndex) { } -void FindGroupByRecIndex::apply(osg::Node &searchNode) +void FindGroupByRecIndex::apply(osg::Node &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::apply(osg::MatrixTransform &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::apply(osg::Geometry &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index f9c4abdac..7a2377f9d 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -196,7 +196,14 @@ namespace NifOsg public: FindGroupByRecIndex(int recIndex); - virtual void apply(osg::Node &searchNode); + virtual void apply(osg::Node &node); + + // Technically not required as the default implementation would trickle down to apply(Node&) anyway, + // but we'll shortcut instead to avoid the chain of virtual function calls + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + void applyNode(osg::Node& searchNode); osg::Group* mFound; osg::NodePath mFoundPath; diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index de4ce28a5..c975286ce 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -478,8 +478,12 @@ namespace Resource void SceneManager::notifyAttached(osg::Node *node) const { - InitWorldSpaceParticlesVisitor visitor (mParticleSystemMask); - node->accept(visitor); + // we can skip any scene graphs without update callbacks since we know that particle emitters will have an update callback set + if (node->getNumChildrenRequiringUpdateTraversal() > 0) + { + InitWorldSpaceParticlesVisitor visitor (mParticleSystemMask); + node->accept(visitor); + } } Resource::ImageManager* SceneManager::getImageManager() diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index c80b9be36..2a8f94c7c 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,24 @@ namespace SceneUtil mFilter2 = "tri " + mFilter; } + virtual void apply(osg::MatrixTransform& node) + { + applyNode(node); + } + virtual void apply(osg::Geometry& node) + { + applyNode(node); + } virtual void apply(osg::Node& node) + { + applyNode(node); + } + virtual void apply(osg::Group& node) + { + applyNode(node); + } + + void applyNode(osg::Node& node) { std::string lowerName = Misc::StringUtils::lowerCase(node.getName()); if ((lowerName.size() >= mFilter.size() && lowerName.compare(0, mFilter.size(), mFilter) == 0) @@ -63,7 +81,7 @@ namespace SceneUtil std::string mFilter2; }; - osg::ref_ptr attach(osg::ref_ptr toAttach, osg::Node *master, const std::string &filter, const std::string &attachNode) + osg::ref_ptr attach(osg::ref_ptr toAttach, osg::Node *master, const std::string &filter, osg::Group* attachNode) { if (dynamic_cast(toAttach.get())) { @@ -88,11 +106,6 @@ namespace SceneUtil } else { - FindByNameVisitor find(attachNode); - master->accept(find); - if (!find.mFoundNode) - throw std::runtime_error(std::string("Can't find attachment node ") + attachNode); - FindByNameVisitor findBoneOffset("BoneOffset"); toAttach->accept(findBoneOffset); @@ -110,7 +123,7 @@ namespace SceneUtil trans->setAttitude(osg::Quat(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0))); } - if (attachNode.find("Left") != std::string::npos) + if (attachNode->getName().find("Left") != std::string::npos) { if (!trans) trans = new osg::PositionAttitudeTransform; @@ -132,13 +145,13 @@ namespace SceneUtil if (trans) { - find.mFoundNode->addChild(trans); + attachNode->addChild(trans); trans->addChild(toAttach); return trans; } else { - find.mFoundNode->addChild(toAttach); + attachNode->addChild(toAttach); return toAttach; } } diff --git a/components/sceneutil/attach.hpp b/components/sceneutil/attach.hpp index 72f7809e9..a8a2239a8 100644 --- a/components/sceneutil/attach.hpp +++ b/components/sceneutil/attach.hpp @@ -8,6 +8,7 @@ namespace osg { class Node; + class Group; } namespace SceneUtil @@ -18,7 +19,7 @@ namespace SceneUtil /// Otherwise, just attach all of the toAttach scenegraph to the attachment node on the master scenegraph, with no filtering. /// @note The master scene graph is expected to include a skeleton. /// @return A newly created node that is directly attached to the master scene graph - osg::ref_ptr attach(osg::ref_ptr toAttach, osg::Node* master, const std::string& filter, const std::string& attachNode); + osg::ref_ptr attach(osg::ref_ptr toAttach, osg::Node* master, const std::string& filter, osg::Group* attachNode); } diff --git a/components/sceneutil/controller.cpp b/components/sceneutil/controller.cpp index 12c89c87d..6cd0cb036 100644 --- a/components/sceneutil/controller.cpp +++ b/components/sceneutil/controller.cpp @@ -3,6 +3,8 @@ #include "statesetupdater.hpp" #include +#include +#include #include namespace SceneUtil @@ -62,6 +64,21 @@ namespace SceneUtil } void ControllerVisitor::apply(osg::Node &node) + { + applyNode(node); + } + + void ControllerVisitor::apply(osg::MatrixTransform &node) + { + applyNode(node); + } + + void ControllerVisitor::apply(osg::Geometry &node) + { + applyNode(node); + } + + void ControllerVisitor::applyNode(osg::Node &node) { osg::Callback* callback = node.getUpdateCallback(); while (callback) @@ -81,7 +98,8 @@ namespace SceneUtil callback = callback->getNestedCallback(); } - traverse(node); + if (node.getNumChildrenRequiringUpdateTraversal() > 0) + traverse(node); } AssignControllerSourcesVisitor::AssignControllerSourcesVisitor() diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp index 3f1ec874e..fd8964ae1 100644 --- a/components/sceneutil/controller.hpp +++ b/components/sceneutil/controller.hpp @@ -64,6 +64,13 @@ namespace SceneUtil virtual void apply(osg::Node& node); + // Technically not required as the default implementation would trickle down to apply(Node&) anyway, + // but we'll shortcut instead to avoid the chain of virtual function calls + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + void applyNode(osg::Node& node); + virtual void visit(osg::Node& node, Controller& ctrl) = 0; }; diff --git a/components/sceneutil/unrefqueue.cpp b/components/sceneutil/unrefqueue.cpp index 10d568298..238da0971 100644 --- a/components/sceneutil/unrefqueue.cpp +++ b/components/sceneutil/unrefqueue.cpp @@ -2,7 +2,6 @@ #include -#include //#include //#include @@ -14,7 +13,7 @@ namespace SceneUtil class UnrefWorkItem : public SceneUtil::WorkItem { public: - std::deque > mObjects; + std::deque > mObjects; virtual void doWork() { @@ -30,7 +29,7 @@ namespace SceneUtil mWorkItem = new UnrefWorkItem; } - void UnrefQueue::push(const osg::Object *obj) + void UnrefQueue::push(const osg::Referenced *obj) { mWorkItem->mObjects.push_back(obj); } diff --git a/components/sceneutil/unrefqueue.hpp b/components/sceneutil/unrefqueue.hpp index 85b1d31e1..4e5293956 100644 --- a/components/sceneutil/unrefqueue.hpp +++ b/components/sceneutil/unrefqueue.hpp @@ -4,11 +4,6 @@ #include #include -namespace osg -{ - class Object; -} - namespace SceneUtil { class WorkQueue; @@ -22,7 +17,7 @@ namespace SceneUtil UnrefQueue(); /// Adds an object to the list of objects to be unreferenced. Call from the main thread. - void push(const osg::Object* obj); + void push(const osg::Referenced* obj); /// Adds a WorkItem to the given WorkQueue that will clear the list of objects in a worker thread, thus unreferencing them. /// Call from the main thread. diff --git a/components/sceneutil/visitor.cpp b/components/sceneutil/visitor.cpp index d147ced7f..74b9be63d 100644 --- a/components/sceneutil/visitor.cpp +++ b/components/sceneutil/visitor.cpp @@ -1,5 +1,7 @@ #include "visitor.hpp" +#include + #include #include @@ -7,14 +9,35 @@ namespace SceneUtil { - void FindByNameVisitor::apply(osg::Group &group) + bool FindByNameVisitor::checkGroup(osg::Group &group) { if (Misc::StringUtils::ciEqual(group.getName(), mNameToFind)) { mFoundNode = &group; - return; + return true; } - traverse(group); + return false; + } + + void FindByNameVisitor::apply(osg::Group &group) + { + if (!checkGroup(group)) + traverse(group); + } + + void FindByNameVisitor::apply(osg::MatrixTransform &node) + { + if (!checkGroup(node)) + traverse(node); + } + + void FindByNameVisitor::apply(osg::Geometry&) + { + } + + void DisableFreezeOnCullVisitor::apply(osg::MatrixTransform &node) + { + traverse(node); } void DisableFreezeOnCullVisitor::apply(osg::Drawable& drw) diff --git a/components/sceneutil/visitor.hpp b/components/sceneutil/visitor.hpp index 751339d02..209f2d9bd 100644 --- a/components/sceneutil/visitor.hpp +++ b/components/sceneutil/visitor.hpp @@ -21,6 +21,11 @@ namespace SceneUtil virtual void apply(osg::Group& group); + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + bool checkGroup(osg::Group& group); + std::string mNameToFind; osg::Group* mFoundNode; }; @@ -34,6 +39,8 @@ namespace SceneUtil { } + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Drawable& drw); }; diff --git a/docs/source/openmw-mods/settings/GUI.rst b/docs/source/openmw-mods/settings/GUI.rst index 945d660c7..0c39cf172 100644 --- a/docs/source/openmw-mods/settings/GUI.rst +++ b/docs/source/openmw-mods/settings/GUI.rst @@ -8,7 +8,7 @@ scaling factor :Range: > 0.0 :Default: 1.0 -This floating point setting scales the GUI interface windows. The value must be greater than 0.0. A value of 1.0 results in the normal scale. Values much larger than 2.0 may result in user interface components being inaccessible. Until a gamepad interface is created, increasing this setting is helpful for simulating the larger interface used in console games. +This setting scales the GUI interface windows. The value must be greater than 0.0. A value of 1.0 results in the normal scale. Values much larger than 2.0 may result in user interface components being inaccessible. Until a gamepad interface is created, increasing this setting is helpful for simulating the larger interface used in console games. The default value is 1.0. This setting can only be configured by editing the settings configuration file. @@ -19,7 +19,7 @@ menu transparency :Range: 0.0 (transparent) to 1.0 (opaque) :Default: 0.84 -This floating point setting controls the transparency of the GUI windows. The value should be between 0.0 (transparent) and 1.0 (opaque). +This setting controls the transparency of the GUI windows. The value should be between 0.0 (transparent) and 1.0 (opaque). The default value is 0.84. This setting can be adjusted in game with the Menu Transparency slider in the Prefs panel of the Options menu. tooltip delay @@ -29,7 +29,7 @@ tooltip delay :Range: > 0.0 :Default: 0.0 -This floating point value determines the number of seconds between when you begin hovering over an item and when its tooltip appears. This setting only affects the tooltip delay for objects under the crosshair in GUI mode windows. There does not appear to be a setting to control the tool tip delay in outside of GUI mode. +This value determines the number of seconds between when you begin hovering over an item and when its tooltip appears. This setting only affects the tooltip delay for objects under the crosshair in GUI mode windows. There does not appear to be a setting to control the tool tip delay in outside of GUI mode. The tooltip displays context sensitive information on the selected GUI element, such as weight, value, damage, armor rating, magical effects, and detailed description. @@ -64,7 +64,7 @@ hit fader :Range: True/False :Default: True -This boolean setting enables or disables the "red flash" overlay that provides a visual clue when the character has taken damage. +This setting enables or disables the "red flash" overlay that provides a visual clue when the character has taken damage. If this setting is disabled, the player will "bleed" like NPCs do. @@ -101,4 +101,4 @@ color crosshair owned This setting sets the color of the crosshair when hovering over an item owned by an NPC. The value is composed of four floating point values representing the red, green, blue and alpha channels. The alpha value is currently ignored. -The default value is "1.0 0.15 0.15 1.0" which is a bright red color. This setting can only be configured by editing the settings configuration file. This setting has no effect if the crosshair setting in the HUD Settings Section is false. This setting has no effect if the show owned setting in the Game Settings Section is false. \ No newline at end of file +The default value is "1.0 0.15 0.15 1.0" which is a bright red color. This setting can only be configured by editing the settings configuration file. This setting has no effect if the crosshair setting in the HUD Settings Section is false. This setting has no effect if the show owned setting in the Game Settings Section is false. diff --git a/docs/source/openmw-mods/settings/HUD.rst b/docs/source/openmw-mods/settings/HUD.rst index 9a15e3aba..8ee5267dd 100644 --- a/docs/source/openmw-mods/settings/HUD.rst +++ b/docs/source/openmw-mods/settings/HUD.rst @@ -8,6 +8,6 @@ crosshair :Range: True/False :Default: True -This boolean setting determines whether the crosshair or reticle is displayed. Some players perceive that disabling the crosshair provides a more immersive experience. Another common use is to disable the crosshair for screen shots. Enabling the crosshair provides more immediate feedback about which object that is currently the focus of actions. +This setting determines whether the crosshair or reticle is displayed. Some players perceive that disabling the crosshair provides a more immersive experience. Another common use is to disable the crosshair for screen shots. Enabling the crosshair provides more immediate feedback about which object is currently the focus of actions. -The default value is true. This setting can be toggled with the Crosshair button in the Prefs panel of the Options menu. \ No newline at end of file +The default value is true. This setting can be toggled with the Crosshair button in the Prefs panel of the Options menu. diff --git a/docs/source/openmw-mods/settings/camera.rst b/docs/source/openmw-mods/settings/camera.rst index 41dabee40..4fe3aa977 100644 --- a/docs/source/openmw-mods/settings/camera.rst +++ b/docs/source/openmw-mods/settings/camera.rst @@ -8,7 +8,7 @@ near clip :Range: > 0 :Default: 1.0 -This floating point setting controls the distance to the near clipping plane. The value must be greater than zero. Values greater than approximately 18.0 will occasionally clip objects in the world in front of the character. Values greater than approximately 8.0 will clip the character's hands in first person view and/or the back of their head in third person view. +This setting controls the distance to the near clipping plane. The value must be greater than zero. Values greater than approximately 18.0 will occasionally clip objects in the world in front of the character. Values greater than approximately 8.0 will clip the character's hands in first person view and/or the back of their head in third person view. The default value is 1.0. This setting can only be configured by editing the settings configuration file. The value must be greater than 0.0, but it's unclear if the engine enforces this limitation. @@ -19,7 +19,7 @@ small feature culling :Range: True/False :Default: True -This boolean setting determines whether objects that render to a few pixels or smaller will be culled (not drawn). It generally improves performance to enable this feature, and by definition the culled objects will be very small on screen. The size in pixels for an object to be considered 'small' is controlled by a separate setting. +This setting determines whether objects that render to a few pixels or smaller will be culled (not drawn). It generally improves performance to enable this feature, and by definition the culled objects will be very small on screen. The size in pixels for an object to be considered 'small' is controlled by a separate setting. The default value is true. This setting can only be configured by editing the settings configuration file. @@ -41,7 +41,7 @@ viewing distance :Range: > 0 :Default: 6666.0 -This floating point values controls the maximum visible distance (also called the far clipping plane). Larger values significantly improve rendering in exterior spaces, but also increase the amount of rendered geometry and significantly reduce the frame rate. This value interacts with the exterior cell load distance setting in that it's probably undesired for this value to provide visibility into cells that have not yet been loaded. When cells are visible before loading, the geometry will "pop-in" suddenly, creating a jarring visual effect. To prevent this effect, this value must be less than:: +This value controls the maximum visible distance (also called the far clipping plane). Larger values significantly improve rendering in exterior spaces, but also increase the amount of rendered geometry and significantly reduce the frame rate. This value interacts with the exterior cell load distance setting in that it's probably undesired for this value to provide visibility into cells that have not yet been loaded. When cells are visible before loading, the geometry will "pop-in" suddenly, creating a jarring visual effect. To prevent this effect, this value must be less than:: (8192 * exterior cell load distance - 1024) * 0.93 @@ -81,6 +81,6 @@ first person field of view :Range: 0-360 :Default: 55.0 -The floating point setting controls the field of view for first person meshes such as the player's hands and held objects. It is not recommended to change this value from its default value because the Bethesda provided Morrowind assets do not adapt well to large values, while small values can result in the hands not being visible. +This setting controls the field of view for first person meshes such as the player's hands and held objects. It is not recommended to change this value from its default value because the Bethesda provided Morrowind assets do not adapt well to large values, while small values can result in the hands not being visible. The default value is 55.0. This setting can only be configured by editing the settings configuration file. diff --git a/docs/source/openmw-mods/settings/cells.rst b/docs/source/openmw-mods/settings/cells.rst index 3a5947ff1..6892bbff2 100644 --- a/docs/source/openmw-mods/settings/cells.rst +++ b/docs/source/openmw-mods/settings/cells.rst @@ -8,10 +8,119 @@ exterior cell load distance :Range: >= 1 :Default: 1 -This integer setting determines the number of exterior cells adjacent to the character that will be loaded for rendering. Values greater than one may significantly affect loading times when exiting interior spaces or loading additional exterior cells. Caution is advised when increasing this setting. +This setting determines the number of exterior cells adjacent to the character that will be loaded for rendering. Values greater than one may significantly affect loading times when exiting interior spaces or loading additional exterior cells. Caution is advised when increasing this setting. This setting interacts with viewing distance and field of view settings. It is generally very wasteful for this value to load geometry than will almost never be visible due to viewing distance and fog. For low frame rate screen shots of scenic vistas, this setting should be set high, and viewing distances adjusted accordingly. -The default value is 1. This value must be greater than or equal to 1. This setting can only be configured by editing the settings configuration file. \ No newline at end of file +The default value is 1. This value must be greater than or equal to 1. This setting can only be configured by editing the settings configuration file. + + +preload enabled +--------------- + +:Type: boolean +:Range: True/False +:Default: True + +Controls whether textures and objects will be pre-loaded in background threads. This setting being enabled should result in a reduced amount of loading screens, no impact on frame rate and a varying amount of additional RAM usage, depending on how the preloader was configured (see the below settings). The default preloading settings with vanilla game files should only use negligible amounts of RAM, however, when using high-res texture and model replacers it may be necessary to tweak these settings to prevent the game from running out of memory. + +All settings starting with 'preload' in this section will have no effect if preloading is disabled, and can only be configured by editing the settings configuration file. + + +preload num threads +------------------- + +:Type: integer +:Range: >=1 +:Default: 1 + +Controls the number of worker threads used for preloading operations. In addition to the preloading threads, OpenMW uses a main thread, a sound streaming thread, and a graphics thread. Therefore, the default setting of one preloading thread will result in a total of 4 threads used which should work well with quad-core CPUs. If you have additional cores to spare, consider increasing the number of preloading threads to 2 or 3 for a boost in preloading performance. Faster preloading will reduce the chance that a cell could not be completely loaded before the player moves into it, and hence reduce the chance of seeing loading screens or frame drops. This may be especially relevant when the player moves at high speed and/or a large number of cells are loaded in via 'exterior cell load distance'. + +A value of 4 or higher is not recommended. With 4 or more threads, improvements will start to diminish due to file reading and synchronization bottlenecks. + +preload exterior grid +--------------------- + +:Type: boolean +:Range: True/False +:Default: True + +Controls whether adjacent cells are preloaded when the player moves close to an exterior cell border. + +preload fast travel +------------------- + +:Type: boolean +:Range: True/False +:Default: False + +Controls whether fast travel destinations are preloaded when the player moves close to a travel service. Because the game can not predict the destination that the player will choose, all possible destinations will be preloaded. This setting is disabled by default due to the adverse effect on memory usage caused by the preloading of all possible destinations. + +preload doors +------------- + +:Type: boolean +:Range: True/False +:Default: True + +Controls whether locations behind a door are preloaded when the player moves close to the door. + +preload distance +---------------- + +:Type: floating point +:Range: >0 +:Default: 1000 + +Controls the distance in in-game units that is considered the player being 'close' to a preloading trigger. Used by all the preloading mechanisms i.e. 'preload exterior grid', 'preload fast travel' and 'preload doors'. + +For measurement purposes, the distance to an object in-game can be observed by opening the console, clicking on the object and typing 'getdistance player'. + +preload instances +----------------- + +:Type: boolean +:Range: True/False +:Default: True + +Controls whether or not objects are also pre-instanced on top of being pre-loaded. Instancing happens when the same object is placed more than once in the cell, and to be sure that any modifications to one instance do not affect the other, the game will create independent copies (instances) of the object. If this setting is enabled, the creation of instances will be done in the preloading thread; otherwise, instancing will only happen in the main thread once the cell is actually loaded. + +Enabling this setting should reduce the chance of frame drops when transitioning into a preloaded cell, but will also result in some additional memory usage. + +preload cell cache min +---------------------- + +:Type: integer +:Range: >0 +:Default: 12 + +The minimum number of preloaded cells that will be kept in the cache. Once the number of preloaded cells in the cache exceeds this setting, the game may start to expire preloaded cells, based on the 'preload cell expiry delay' setting, starting with the oldest cell. When a preloaded cell expires, all the assets that were loaded for it will also expire and will have to be loaded again the next time the cell is requested for preloading. + +preload cell cache max +---------------------- + +:Type: integer +:Range: >0 +:Default: 20 + +The maximum number of cells that will ever be in pre-loaded state simultaneously. This setting is intended to put a cap on the amount of memory that could potentially be used by preload state. + +preload cell expiry delay +------------------------- + +:Type: floating point +:Range: >=0 +:Default: 5 + +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. + +cache expiry delay +------------------ + +:Type: floating point +:Range: >=0 +:Default: 5 + +The amount of time (in seconds) that a preloaded texture or object will stay in cache after it is no longer referenced or required, for example, when all cells containing this texture have been unloaded. diff --git a/docs/source/openmw-mods/settings/game.rst b/docs/source/openmw-mods/settings/game.rst index 40fd2e292..1eaa22db4 100644 --- a/docs/source/openmw-mods/settings/game.rst +++ b/docs/source/openmw-mods/settings/game.rst @@ -19,7 +19,7 @@ best attack :Range: True/False :Default: False -If this boolean setting is true, the player character will always use the most powerful attack when striking with a weapon (chop, slash or thrust). If this setting is false, the type of attack is determined by the direction that the character is moving at the time the attack begins. +If this setting is true, the player character will always use the most powerful attack when striking with a weapon (chop, slash or thrust). If this setting is false, the type of attack is determined by the direction that the character is moving at the time the attack begins. The default value is false. This setting can be toggled with the Always Use Best Attack button in the Prefs panel of the Options menu. @@ -30,7 +30,7 @@ difficulty :Range: -500 to 500 :Default: 0 -This integer setting adjusts the difficulty of the game and is intended to be in the range -100 to 100 inclusive. Given the default game setting for fDifficultyMult of 5.0, a value of -100 results in the player taking 80% of the usual damage, doing 6 times the normal damage. A value of 100 results in the player taking 6 times as much damage, but inflicting only 80% of the usual damage. Values less than -500 will result in the player receiving no damage, and values greater than 500 will result in the player inflicting no damage. +This setting adjusts the difficulty of the game and is intended to be in the range -100 to 100 inclusive. Given the default game setting for fDifficultyMult of 5.0, a value of -100 results in the player taking 80% of the usual damage, doing 6 times the normal damage. A value of 100 results in the player taking 6 times as much damage, but inflicting only 80% of the usual damage. Values less than -500 will result in the player receiving no damage, and values greater than 500 will result in the player inflicting no damage. The default value is 0. This setting can be controlled in game with the Difficulty slider in the Prefs panel of the Options menu. @@ -41,6 +41,6 @@ show effect duration :Range: True/False :Default: False -Show the remaining duration of magic effects and lights if this boolean setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. +Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. -The default value is false. This setting can only be configured by editing the settings configuration file. \ No newline at end of file +The default value is false. This setting can only be configured by editing the settings configuration file. diff --git a/docs/source/openmw-mods/settings/index.rst b/docs/source/openmw-mods/settings/index.rst index fa79c5efc..345c29dda 100644 --- a/docs/source/openmw-mods/settings/index.rst +++ b/docs/source/openmw-mods/settings/index.rst @@ -4,7 +4,7 @@ Advanced Settings Configuration This part of the guide will cover how to make modifications to the more arcane settings in OpenMW, most of which are not available from in-game menus, to optimize or customize your OpenMW experience. If you are familiar with ``.ini`` tweaks in Morrowind or the other games, this will be quite similar. All settings described in this section are changed in ``settings.cfg``, located in your OpenMW user directory. See :doc:`paths` for this location. -Although this guide attempts to be comprehensive and up to date. You will always be able to find the full list of settings available and their default values in ``settings-default.cfg`` in your main OpenMW installation directory. The ranges I have included with each setting are the physically possible ranges, not recommendations. +Although this guide attempts to be comprehensive and up to date, you will always be able to find the full list of settings available and their default values in ``settings-default.cfg`` in your main OpenMW installation directory. The ranges I have included with each setting are the physically possible ranges, not recommendations. .. warning:: As the title suggests, these are advanced settings. If digging around plain text files and manually editing settings sounds scary to you, you may want to stear clear of altering these files. That being said, this guide should be plenty clear enough that you can find the setting you want to change and safely edit it. @@ -25,4 +25,4 @@ Although this guide attempts to be comprehensive and up to date. You will always sound video water - windows \ No newline at end of file + windows diff --git a/docs/source/openmw-mods/settings/input.rst b/docs/source/openmw-mods/settings/input.rst index 8c7b2a42b..5d0f8f662 100644 --- a/docs/source/openmw-mods/settings/input.rst +++ b/docs/source/openmw-mods/settings/input.rst @@ -8,7 +8,7 @@ grab cursor :Range: True/False :Default: True -OpenMW will capture control of the cursor if this boolean setting is true. +OpenMW will capture control of the cursor if this setting is true. In "look mode", OpenMW will center the cursor regardless of the value of this setting (since the cursor/crosshair is always centered in the OpenMW window). However, in GUI mode, this setting determines the behavior when the cursor is moved outside the OpenMW window. If true, the cursor movement stops at the edge of the window preventing access to other applications. If false, the cursor is allowed to move freely on the desktop. @@ -25,7 +25,7 @@ toggle sneak :Range: True/False :Default: False -This boolean setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. +This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. The default value is false. This setting can only be configured by editing the settings configuration file. @@ -36,7 +36,7 @@ always run :Range: True/False :Default: False -If this boolean setting is true, the character is running by default, otherwise the character is walking by default. The shift key will temporarily invert this setting, and the caps lock key will invert this setting while it's "locked". This setting is updated every time you exit the game, based on whether the caps lock key was on or off at the time you exited. +If this setting is true, the character is running by default, otherwise the character is walking by default. The shift key will temporarily invert this setting, and the caps lock key will invert this setting while it's "locked". This setting is updated every time you exit the game, based on whether the caps lock key was on or off at the time you exited. The default value is false. This settings can be toggled in game by pressing the CapsLock key and exiting. @@ -56,7 +56,7 @@ camera sensitivity :Range: > 0 :Default: 1.0 -This floating point setting controls the overall camera/mouse sensitivity when not in GUI mode. The default sensitivity is 1.0, with smaller values requiring more mouse movement, and larger values requiring less. This setting is multiplicative in magnitude. This setting does not affect mouse speed in GUI mode, which is instead controlled by your operating system mouse speed setting. +This setting controls the overall camera/mouse sensitivity when not in GUI mode. The default sensitivity is 1.0, with smaller values requiring more mouse movement, and larger values requiring less. This setting is multiplicative in magnitude. This setting does not affect mouse speed in GUI mode, which is instead controlled by your operating system mouse speed setting. The default value is 1.0. This setting can be changed with the Camera Sensitivity slider in the Controls panel of the Options menu. @@ -67,7 +67,7 @@ camera y multiplier :Range: > 0 :Default: 1.0 -This floating point setting controls the vertical camera/mouse sensitivity relative to the horizontal sensitivity (see camera sensitivity above). It is multiplicative with the previous setting, meaning that it should remain set at 1.0 unless the player desires to have different sensitivities in the two axes. +This setting controls the vertical camera/mouse sensitivity relative to the horizontal sensitivity (see camera sensitivity above). It is multiplicative with the previous setting, meaning that it should remain set at 1.0 unless the player desires to have different sensitivities in the two axes. The default value is 1.0. This setting can only be configured by editing the settings configuration file. @@ -80,4 +80,4 @@ invert y axis Invert the vertical axis while not in GUI mode. If this setting is true, moving the mouse away from the player will look down, while moving it towards the player will look up. This setting does not affect cursor movement in GUI mode. -The default value is false. This setting can be toggled in game with the Invert Y Axis button in the Controls panel of the Options menu. \ No newline at end of file +The default value is false. This setting can be toggled in game with the Invert Y Axis button in the Controls panel of the Options menu. diff --git a/docs/source/openmw-mods/settings/map.rst b/docs/source/openmw-mods/settings/map.rst index e03bfd615..f3e0a1c53 100644 --- a/docs/source/openmw-mods/settings/map.rst +++ b/docs/source/openmw-mods/settings/map.rst @@ -8,7 +8,7 @@ global map size :Range: >= 1 :Default: 18 -This integer setting adjusts the scale of the world map in the GUI mode map window. The value is the width in pixels of each cell in the map, so larger values result in larger more detailed world maps, while smaller values result in smaller less detailed world maps. However, the native resolution of the map source material appears to be 9 pixels per unexplored cell and approximately 18 pixels per explored cell, so values larger than 36 don't produce much additional detail. Similarly, the size of place markers is currently fixed at 12 pixels, so values smaller than this result in overlapping place markers. Values from 12 to 36 are recommended. For reference, Vvardenfell is approximately 41x36 cells. +This setting adjusts the scale of the world map in the GUI mode map window. The value is the width in pixels of each cell in the map, so larger values result in larger more detailed world maps, while smaller values result in smaller less detailed world maps. However, the native resolution of the map source material appears to be 9 pixels per unexplored cell and approximately 18 pixels per explored cell, so values larger than 36 don't produce much additional detail. Similarly, the size of place markers is currently fixed at 12 pixels, so values smaller than this result in overlapping place markers. Values from 12 to 36 are recommended. For reference, Vvardenfell is approximately 41x36 cells. Warning: Changing this setting affects saved games. The currently explored area is stored as an image in the save file that's overlayed on the default world map in game. When you increase the resolution of the map, the overlay of earlier saved games will be scaled up on load, and appear blurry. When you visit the cell again, the overlay for that cell is regenerated at the new resolution, so the blurry areas can be corrected by revisiting all the cells you've already visited. @@ -21,7 +21,7 @@ local map hud widget size :Range: >= 1 :Default: 256 -This integer setting controls the zoom level for the HUD map widget (the map in the lower right corner of the window). A value of 64 results in the HUD map widget displaying one entire exterior cell. Since the GUI mode map displays 3x3 cells, a value of approximately 21 displays the same area as the GUI mode map. Larger values increase the level of zoom, while smaller values are wasteful since there's no map data to display beyond the 3x3 cell grid. +This setting controls the zoom level for the HUD map widget (the map in the lower right corner of the window). A value of 64 results in the HUD map widget displaying one entire exterior cell. Since the GUI mode map displays 3x3 cells, a value of approximately 21 displays the same area as the GUI mode map. Larger values increase the level of zoom, while smaller values are wasteful since there's no map data to display beyond the 3x3 cell grid. Note that the actual size of the widget is always the same on the screen unless the scaling factor setting in the "GUI" section is changed. Increasing both the scaling factor of the GUI and this setting does result in a higher resolution HUD map, but unfortunately with a scaled direction pointer on top of it. @@ -34,7 +34,7 @@ local map resolution :Range: >= 1 :Default: 256 -This integer setting controls the resolution of the GUI mode local map window. Larger values generally increase the visible detail in map. If this setting is half the local map widget size or smaller, the map will generally be be fairly blurry. Setting both options to the same value results in a map with good detail. Values that exceed the local map widget size setting by more than a factor of two are unlikely to provide much of an improvement in detail since they're subsequently scaled back to the approximately the map widget size before display. The video resolution settings interacts with this setting in that regard. +This setting controls the resolution of the GUI mode local map window. Larger values generally increase the visible detail in map. If this setting is half the local map widget size or smaller, the map will generally be be fairly blurry. Setting both options to the same value results in a map with good detail. Values that exceed the local map widget size setting by more than a factor of two are unlikely to provide much of an improvement in detail since they're subsequently scaled back to the approximately the map widget size before display. The video resolution settings interacts with this setting in that regard. .. warning:: Increasing this setting can increase cell load times, because the map is rendered on demand each time you enter a new cell. Large values may exceed video card limits or exhaust VRAM. @@ -48,6 +48,6 @@ local map widget size :Range: >= 1 :Default: 512 -This integer setting controls the canvas size of the GUI mode local map window. Larger values result in a larger physical map size on screen, and typically require more panning to see all available portions of the map. This larger size also enables an overall greater level of detail if the local map resolution setting is also increased. +This setting controls the canvas size of the GUI mode local map window. Larger values result in a larger physical map size on screen, and typically require more panning to see all available portions of the map. This larger size also enables an overall greater level of detail if the local map resolution setting is also increased. -The default value for this setting is 512. This setting can not be configured except by editing the settings configuration file. \ No newline at end of file +The default value for this setting is 512. This setting can not be configured except by editing the settings configuration file. diff --git a/docs/source/openmw-mods/settings/saves.rst b/docs/source/openmw-mods/settings/saves.rst index 39354a4c7..de0c06558 100644 --- a/docs/source/openmw-mods/settings/saves.rst +++ b/docs/source/openmw-mods/settings/saves.rst @@ -8,7 +8,7 @@ character :Range: :Default: "" -This string setting contains the default character name for loading saved games. +This setting contains the default character name for loading saved games. The default value is the empty string, which results in no character being selected by default. This setting is automatically updated from the Load menu when a different character is selected. @@ -19,7 +19,7 @@ autosave :Range: True/False :Default: True -This boolean setting determines whether the game will be automatically saved when the character rests. +This setting determines whether the game will be automatically saved when the character rests. The default value is true. This setting can be toggled in game with the Auto-Save when Rest button in the Prefs panel of the Options menu. @@ -30,6 +30,6 @@ timeplayed :Range: True/False :Default: False -This boolean setting determines whether the amount of the time the player has spent playing will be displayed for each saved game in the Load menu. +This setting determines whether the amount of the time the player has spent playing will be displayed for each saved game in the Load menu. -The default value is false. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW 0.37. \ No newline at end of file +The default value is false. This setting can only be configured by editing the settings configuration file. diff --git a/docs/source/openmw-mods/settings/sound.rst b/docs/source/openmw-mods/settings/sound.rst index 6537ee950..dec4bb3a2 100644 --- a/docs/source/openmw-mods/settings/sound.rst +++ b/docs/source/openmw-mods/settings/sound.rst @@ -8,7 +8,7 @@ device :Range: :Default: "" -This string setting determines which audio device to use. A blank or missing setting means to use the default device, which should usually be sufficient, but if you need to explicitly specify a device use this setting. +This setting determines which audio device to use. A blank or missing setting means to use the default device, which should usually be sufficient, but if you need to explicitly specify a device use this setting. The names of detected devices can be found in the openmw.log file in your configuration directory. @@ -21,7 +21,7 @@ master volume :Range: 0.0 to 1.0 :Default: 1.0 -This floating point setting controls the overall volume. The master volume is multiplied with all other volume settings to determine the final volume. +This setting controls the overall volume. The master volume is multiplied with all other volume settings to determine the final volume. The default value is 1.0. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Master slider from the Audio panel of the Options menu. @@ -32,7 +32,7 @@ footsteps volume :Range: 0.0 to 1.0 :Default: 0.2 -This floating point setting controls the volume of footsteps from the character and other actors. +This setting controls the volume of footsteps from the character and other actors. The default value is 0.2. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Footsteps slider from the Audio panel of the Options menu. @@ -43,7 +43,7 @@ music volume :Range: 0.0 to 1.0 :Default: 0.5 -This floating point setting controls the volume for music tracks. +This setting controls the volume for music tracks. The default value is 0.5. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Music slider from the Audio panel of the Options menu. @@ -54,7 +54,7 @@ sfx volume :Range: 0.0 to 1.0 :Default: 1.0 -This floating point setting controls the volume for special sound effects such as combat noises. +This setting controls the volume for special sound effects such as combat noises. The default value is 1.0. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Effects slider from the Audio panel of the Options menu. @@ -65,7 +65,7 @@ voice volume :Range: 0.0 to 1.0 :Default: 0.8 -This floating point setting controls the volume for spoken dialog from NPCs. +This setting controls the volume for spoken dialog from NPCs. The default value is 0.8. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Voice slider from the Audio panel of the Options menu. @@ -76,9 +76,9 @@ buffer cache min :Range: > 0 :Default: 14 -This integer setting determines the minimum size of the sound buffer cache in megabytes. When the cache reaches the size specified by the buffer cache max setting, old buffers will be unloaded until it's using no more memory than specified by this setting. This setting must be less than or equal to the buffer cache max setting. +This setting determines the minimum size of the sound buffer cache in megabytes. When the cache reaches the size specified by the buffer cache max setting, old buffers will be unloaded until it's using no more memory than specified by this setting. This setting must be less than or equal to the buffer cache max setting. -The default value is 14. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38. +The default value is 14. This setting can only be configured by editing the settings configuration file. buffer cache max ---------------- @@ -87,9 +87,9 @@ buffer cache max :Range: > 0 :Default: 16 -This integer setting determines the maximum size of the sound buffer cache in megabytes. When the cache reaches this size, old buffers will be unloaded until it reaches the size specified by the buffer cache min setting. This setting must be greater than or equal to the buffer cache min setting. +This setting determines the maximum size of the sound buffer cache in megabytes. When the cache reaches this size, old buffers will be unloaded until it reaches the size specified by the buffer cache min setting. This setting must be greater than or equal to the buffer cache min setting. -The default value is 16. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38. +The default value is 16. This setting can only be configured by editing the settings configuration file. hrtf enable ----------- @@ -98,8 +98,8 @@ hrtf enable :Range: -1, 0, 1 :Default: -1 -This integer setting determines whether to enable head-related transfer function (HRTF) audio processing. HRTF audio processing creates the perception of sounds occurring in a three dimensional space when wearing headphones. Enabling HRTF may also require an OpenAL Soft version greater than 1.17.0, and possibly some operating system configuration. A value of 0 disables HRTF processing, while a value of 1 explicitly enables HRTF processing. -The default value is -1, which should enable the feature automatically for most users when possible. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38. +This setting determines whether to enable head-related transfer function (HRTF) audio processing. HRTF audio processing creates the perception of sounds occurring in a three dimensional space when wearing headphones. Enabling HRTF may also require an OpenAL Soft version greater than 1.17.0, and possibly some operating system configuration. A value of 0 disables HRTF processing, while a value of 1 explicitly enables HRTF processing. +The default value is -1, which should enable the feature automatically for most users when possible. This setting can only be configured by editing the settings configuration file. hrtf ---- @@ -108,6 +108,6 @@ hrtf :Range: :Default: "" -This string setting specifies which HRTF profile to use when HRTF is enabled. Blank means use the default. This setting has no effect if HRTF is not enabled based on the hrtf enable setting. Allowed values for this field are enumerated in openmw.log file is an HRTF enabled ausio system is installed. +This setting specifies which HRTF profile to use when HRTF is enabled. Blank means use the default. This setting has no effect if HRTF is not enabled based on the hrtf enable setting. Allowed values for this field are enumerated in openmw.log file is an HRTF enabled ausio system is installed. -The default value is the empty string, which uses the default profile. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38. \ No newline at end of file +The default value is the empty string, which uses the default profile. This setting can only be configured by editing the settings configuration file. diff --git a/docs/source/openmw-mods/settings/video.rst b/docs/source/openmw-mods/settings/video.rst index a31af5103..b724611ad 100644 --- a/docs/source/openmw-mods/settings/video.rst +++ b/docs/source/openmw-mods/settings/video.rst @@ -30,7 +30,7 @@ fullscreen :Range: True/False :Default: False -This boolean setting determines whether the entire screen is used for the specified resolution. +This setting determines whether the entire screen is used for the specified resolution. The default value is false. This setting can be toggled in game using the Fullscreen button in the Video tab of the Video panel in the Options menu. It can also be toggled with the Full Screen check box in the Graphics tab of the OpenMW Launcher. @@ -41,7 +41,7 @@ screen :Range: >= 0 :Default: 0 -This integer setting determines which screen the game will open on in multi-monitor configurations. This setting is particularly important when the fullscreen setting is true, since this is the only way to control which screen is used, but it can also be used to control which screen a normal window or a borderless window opens on as well. The screens are numbered in increasing order, beginning with 0. +This setting determines which screen the game will open on in multi-monitor configurations. This setting is particularly important when the fullscreen setting is true, since this is the only way to control which screen is used, but it can also be used to control which screen a normal window or a borderless window opens on as well. The screens are numbered in increasing order, beginning with 0. The default value is 0. This setting can be selected from a pull down menu in the Graphics tab of the OpenMW Launcher, but cannot be changed during game play. @@ -69,7 +69,7 @@ window border :Range: True/False :Default: True -This boolean setting determines whether there's an operating system border drawn around the OpenMW window. If this setting is true, the window can be moved and resized with the operating system window controls. If this setting is false, the window has no operating system border. +This setting determines whether there's an operating system border drawn around the OpenMW window. If this setting is true, the window can be moved and resized with the operating system window controls. If this setting is false, the window has no operating system border. This setting has no effect if the fullscreen setting is true. @@ -82,7 +82,7 @@ antialiasing :Range: 0, 2, 4, 8, 16 :Default: 0 -This integer setting controls anti-aliasing. Anti-aliasing is a technique designed to improve the appearance of polygon edges, so they do not appear to be "jagged". Anti-aliasing can smooth these edges at the cost of a minor reduction in the frame rate. A value of 0 disables anti-aliasing. Other powers of two (e.g. 2, 4, 8, 16) are supported according to the capabilities of your graphics hardware. Higher values do a better job of smoothing out the image but have a greater impact on frame rate. +This setting controls anti-aliasing. Anti-aliasing is a technique designed to improve the appearance of polygon edges, so they do not appear to be "jagged". Anti-aliasing can smooth these edges at the cost of a minor reduction in the frame rate. A value of 0 disables anti-aliasing. Other powers of two (e.g. 2, 4, 8, 16) are supported according to the capabilities of your graphics hardware. Higher values do a better job of smoothing out the image but have a greater impact on frame rate. This setting can be configured from a list of valid choices in the Graphics panel of the OpenMW Launcher, but cannot be changed during game play - due to a technical limitation that may be addressed in a future version of OpenMW. @@ -93,7 +93,7 @@ vsync :Range: True/False :Default: False -This boolean setting determines whether frame draws are synchronized with the vertical refresh rate of your monitor. Enabling this setting can reduce screen tearing, a visual defect caused by updating the image buffer in the middle of a screen draw. Enabling this option typically implies limiting the framerate to 60 frames per second, but may also introduce additional delays caused by having to wait until the appropriate time (the vertical blanking interval) to draw a frame. +This setting determines whether frame draws are synchronized with the vertical refresh rate of your monitor. Enabling this setting can reduce screen tearing, a visual defect caused by updating the image buffer in the middle of a screen draw. Enabling this option typically implies limiting the framerate to 60 frames per second, but may also introduce additional delays caused by having to wait until the appropriate time (the vertical blanking interval) to draw a frame. The default value is false. This setting can be adjusted in game using the VSync button in the Video tab of the Video panel in the Options menu. It can also be changed by toggling the Vertical Sync check box in the Graphics tab of the OpenMW Launcher. @@ -104,13 +104,13 @@ framerate limit :Range: >= 0.0 :Default: 0.0 -This floating point setting determines the maximum frame rate in frames per second. If this setting is 0.0, the frame rate is unlimited. +This setting determines the maximum frame rate in frames per second. If this setting is 0.0, the frame rate is unlimited. There are several reasons to consider capping your frame rate, especially if you're already experiencing a relatively high frame rate (greater than 60 frames per second). Lower frame rates will consume less power and generate less heat and noise. Frame rates above 60 frames per second rarely produce perceptible improvements in visual quality, but may improve input responsiveness. Capping the frame rate may in some situations reduce the perception of choppiness (highly variable frame rates during game play) by lowering the peak frame rates. This setting interacts with the vsync setting in the Video section in the sense that enabling vertical sync limits the frame rate to the refresh rate of your monitor (often 60 frames per second). Choosing to limit the frame rate using this setting instead of vsync may reduce input lag due to the game not having to wait for the vertical blanking interval. -The default value is 0.0. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW 0.37. +The default value is 0.0. This setting can only be configured by editing the settings configuration file. contrast -------- @@ -119,7 +119,7 @@ contrast :Range: > 0.0 :Default: 1.0 -This floating point setting controls the contrast correction for all video in the game. +This setting controls the contrast correction for all video in the game. The default value is 1.0. This setting can only be configured by editing the settings configuration file. This setting does not currently work under Linux. @@ -130,6 +130,6 @@ gamma :Range: > 0.0 :Default: 1.0 -This floating point setting controls the gamma correction for all video in the game. Gamma is an exponent that makes colors brighter if greater than 1.0 and darker if less than 1.0. +This setting controls the gamma correction for all video in the game. Gamma is an exponent that makes colors brighter if greater than 1.0 and darker if less than 1.0. -The default value is 1.0. This setting can be changed in the Detail tab of the Video panel of the Options menu. This setting does not currently work under Linux, and the in-game setting in the Options menu has been disabled. \ No newline at end of file +The default value is 1.0. This setting can be changed in the Detail tab of the Video panel of the Options menu. This setting does not currently work under Linux, and the in-game setting in the Options menu has been disabled. diff --git a/docs/source/openmw-mods/settings/water.rst b/docs/source/openmw-mods/settings/water.rst index 379da1de2..a5fa27972 100644 --- a/docs/source/openmw-mods/settings/water.rst +++ b/docs/source/openmw-mods/settings/water.rst @@ -11,7 +11,7 @@ shader :Range: True/False :Default: False -This boolean setting enables or disables the water shader, which results in much more realistic looking water surfaces, including reflected objects and a more detailed wavy surface. +This setting enables or disables the water shader, which results in much more realistic looking water surfaces, including reflected objects and a more detailed wavy surface. The default value is false. This setting can be toggled with the Shader button in the Water tab of the Video panel of the Options menu. @@ -22,7 +22,7 @@ rtt size :Range: > 0 :Default: 512 -The integer setting determines the size of the texture used for reflection and refraction (if enabled). For reflection, the texture size determines the detail of reflected images on the surface of the water. For refraction, the texture size determines the detail of the objects on the other side of the plane of water (which have a wavy appearance caused by the refraction). RTT is an acronym for Render to Texture which allows rendering of the scene to be saved as a texture. +The setting determines the size of the texture used for reflection and refraction (if enabled). For reflection, the texture size determines the detail of reflected images on the surface of the water. For refraction, the texture size determines the detail of the objects on the other side of the plane of water (which have a wavy appearance caused by the refraction). RTT is an acronym for Render to Texture which allows rendering of the scene to be saved as a texture. Higher values produces better visuals and result in a marginally lower frame rate depending on your graphics hardware. In the Water tab of the Video panel of the Options menu, the choices are Low (512), Medium (1024) and High (2048). This setting has no effect if the shader setting is false. It is recommended to use values that are a power of two because this results in more efficient use of video hardware. @@ -36,7 +36,7 @@ refraction :Range: True/False :Default: False -This boolean setting enables the refraction rendering feature of the water shader. Refraction causes deep water to be more opaque and objects seen through the plane of the water to have a wavy appearance. Enabling this feature results in better visuals, and a marginally lower frame rate depending on your graphics hardware. +This setting enables the refraction rendering feature of the water shader. Refraction causes deep water to be more opaque and objects seen through the plane of the water to have a wavy appearance. Enabling this feature results in better visuals, and a marginally lower frame rate depending on your graphics hardware. This setting has no effect if the shader setting is false. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d9d40bb0b..770a9674d 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -42,6 +42,9 @@ exterior cell load distance = 1 # Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled. preload enabled = true +# The number of threads to be used for preloading operations. +preload num threads = 1 + # Preload adjacent cells when moving close to an exterior cell border. preload exterior grid = true