From f962ce0bbe6848b572cd83582a36cae458b2b7d7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 29 Nov 2015 19:56:43 +0100 Subject: [PATCH 1/7] Don't link against unnecessary OSG libraries --- apps/opencs/CMakeLists.txt | 8 +++++++- apps/openmw/CMakeLists.txt | 8 +++++++- components/CMakeLists.txt | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 6af04e8fc..dc90072fa 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -205,7 +205,13 @@ if(APPLE) endif(APPLE) target_link_libraries(openmw-cs - ${OPENSCENEGRAPH_LIBRARIES} + ${OSG_LIBRARIES} + ${OPENTHREADS_LIBRARIES} + ${OSGUTIL_LIBRARIES} + ${OSGVIEWER_LIBRARIES} + ${OSGGA_LIBRARIES} + ${OSGFX_LIBRARIES} + ${OSGQT_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 48d10e202..e2d333e56 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -118,7 +118,13 @@ include_directories( ) target_link_libraries(openmw - ${OPENSCENEGRAPH_LIBRARIES} + ${OSG_LIBRARIES} + ${OPENTHREADS_LIBRARIES} + ${OSGPARTICLE_LIBRARIES} + ${OSGUTIL_LIBRARIES} + ${OSGDB_LIBRARIES} + ${OSGVIEWER_LIBRARIES} + ${OSGGA_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index c80e27e4d..0f2906ce5 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -177,7 +177,15 @@ target_link_libraries(components ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${OPENSCENEGRAPH_LIBRARIES} + ${OSG_LIBRARIES} + ${OPENTHREADS_LIBRARIES} + ${OSGPARTICLE_LIBRARIES} + ${OSGUTIL_LIBRARIES} + ${OSGDB_LIBRARIES} + ${OSGVIEWER_LIBRARIES} + ${OSGGA_LIBRARIES} + ${OSGFX_LIBRARIES} + ${OSGANIMATION_LIBRARIES} ${BULLET_LIBRARIES} ${SDL2_LIBRARY} # For MyGUI platform From d5a738bd392b0b28a3a65cb1128ce3fd35731046 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 00:38:52 +0100 Subject: [PATCH 2/7] Apply 27e669296e5 (locale-unaware tolower) to more code In particular, the one in VFS::normalizeFilename was affecting cell loading performance. --- apps/openmw/mwdialogue/keywordsearch.hpp | 15 +++++++-------- apps/openmw/mwgui/journalviewmodel.cpp | 6 ++---- components/files/multidircollection.cpp | 4 ++-- components/files/multidircollection.hpp | 6 ++---- components/vfs/manager.cpp | 4 ++-- 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwdialogue/keywordsearch.hpp b/apps/openmw/mwdialogue/keywordsearch.hpp index c4e1d7553..3b68d3d6b 100644 --- a/apps/openmw/mwdialogue/keywordsearch.hpp +++ b/apps/openmw/mwdialogue/keywordsearch.hpp @@ -2,7 +2,7 @@ #define GAME_MWDIALOGUE_KEYWORDSEARCH_H #include -#include +#include #include #include #include // std::reverse @@ -44,7 +44,7 @@ public: typename Entry::childen_t::iterator current; typename Entry::childen_t::iterator next; - current = mRoot.mChildren.find (std::tolower (*keyword.begin(), mLocale)); + current = mRoot.mChildren.find (tolower (*keyword.begin())); if (current == mRoot.mChildren.end()) return false; else if (current->second.mKeyword.size() && Misc::StringUtils::ciEqual(current->second.mKeyword, keyword)) @@ -55,7 +55,7 @@ public: for (Point i = ++keyword.begin(); i != keyword.end(); ++i) { - next = current->second.mChildren.find(std::tolower (*i, mLocale)); + next = current->second.mChildren.find(tolower (*i)); if (next == current->second.mChildren.end()) return false; if (Misc::StringUtils::ciEqual(next->second.mKeyword, keyword)) @@ -89,7 +89,7 @@ public: // check first character - typename Entry::childen_t::iterator candidate = mRoot.mChildren.find (std::tolower (*i, mLocale)); + typename Entry::childen_t::iterator candidate = mRoot.mChildren.find (tolower (*i)); // no match, on to next character if (candidate == mRoot.mChildren.end ()) @@ -104,7 +104,7 @@ public: while ((j + 1) != end) { - typename Entry::childen_t::iterator next = candidate->second.mChildren.find (std::tolower (*++j, mLocale)); + typename Entry::childen_t::iterator next = candidate->second.mChildren.find (tolower (*++j)); if (next == candidate->second.mChildren.end ()) { @@ -136,7 +136,7 @@ public: while (k != end && t != candidate->second.mKeyword.end ()) { - if (std::tolower (*k, mLocale) != std::tolower (*t, mLocale)) + if (tolower (*k) != tolower (*t)) break; ++k, ++t; @@ -212,7 +212,7 @@ private: void seed_impl (string_t keyword, value_t value, size_t depth, Entry & entry) { - int ch = tolower (keyword.at (depth), mLocale); + int ch = tolower (keyword.at (depth)); typename Entry::childen_t::iterator j = entry.mChildren.find (ch); @@ -249,7 +249,6 @@ private: } Entry mRoot; - std::locale mLocale; }; } diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index d05257e46..03e4813b3 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -29,8 +29,6 @@ struct JournalViewModelImpl : JournalViewModel mutable bool mKeywordSearchLoaded; mutable KeywordSearchT mKeywordSearch; - std::locale mLocale; - JournalViewModelImpl () { mKeywordSearchLoaded = false; @@ -74,7 +72,7 @@ struct JournalViewModelImpl : JournalViewModel } } - wchar_t tolower (wchar_t ch) const { return std::tolower (ch, mLocale); } + wchar_t tolower (wchar_t ch) const { return tolower (ch); } bool isEmpty () const { @@ -319,7 +317,7 @@ struct JournalViewModelImpl : JournalViewModel for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) { - if (i->first [0] != std::tolower (character, mLocale)) + if (i->first [0] != tolower (character)) continue; visitor (i->second.getName()); diff --git a/components/files/multidircollection.cpp b/components/files/multidircollection.cpp index 7b3b0c440..9b4a542f5 100644 --- a/components/files/multidircollection.cpp +++ b/components/files/multidircollection.cpp @@ -28,8 +28,8 @@ namespace Files for (std::size_t i=0; i #include #include -#include #include #include @@ -25,12 +24,11 @@ namespace Files return left #include -#include #include "archive.hpp" @@ -15,7 +15,7 @@ namespace char nonstrict_normalize_char(char ch) { - return ch == '\\' ? '/' : std::tolower(ch,std::locale::classic()); + return ch == '\\' ? '/' : tolower(ch); } void normalize_path(std::string& path, bool strict) From d2290a81837e404c4f1b22965c67e282f647bc44 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 00:41:26 +0100 Subject: [PATCH 3/7] Don't crash when Water_SurfaceFrameCount is 0 --- apps/openmw/mwrender/water.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index ca099991e..1afb74bd7 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -551,6 +551,8 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) stateset->setRenderBinDetails(MWRender::RenderBin_Water, "RenderBin"); + node->setStateSet(stateset); + std::vector > textures; int frameCount = mFallback->getFallbackInt("Water_SurfaceFrameCount"); std::string texture = mFallback->getFallbackString("Water_SurfaceTexture"); @@ -561,12 +563,15 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) textures.push_back(mResourceSystem->getTextureManager()->getTexture2D(texname.str(), osg::Texture::REPEAT, osg::Texture::REPEAT)); } + if (!textures.size()) + return; + float fps = mFallback->getFallbackFloat("Water_SurfaceFPS"); osg::ref_ptr controller (new NifOsg::FlipController(0, 1.f/fps, textures)); controller->setSource(boost::shared_ptr(new SceneUtil::FrameTimeSource)); node->setUpdateCallback(controller); - node->setStateSet(stateset); + stateset->setTextureAttributeAndModes(0, textures[0], osg::StateAttribute::ON); } From e49bce7b401c1a3fa31823dcc4e3688eaf365f68 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 01:39:41 +0100 Subject: [PATCH 4/7] Share the bvh of btBvhTriangleMeshShape's when possible Results in decent cell-loading speed up. (only affects bullet versions < 2.83, since we use btScaledBvhTriangleMeshShape for >=2.83) --- components/resource/bulletshape.cpp | 11 ++++++++++- components/resource/bulletshape.hpp | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/resource/bulletshape.cpp b/components/resource/bulletshape.cpp index 00bcb9e04..968dbe6c6 100644 --- a/components/resource/bulletshape.cpp +++ b/components/resource/bulletshape.cpp @@ -62,7 +62,16 @@ btCollisionShape* BulletShape::duplicateCollisionShape(btCollisionShape *shape) // work around btScaledBvhTriangleMeshShape bug ( https://code.google.com/p/bullet/issues/detail?id=371 ) in older bullet versions btTriangleMesh* oldMesh = static_cast(trishape->getMeshInterface()); btTriangleMesh* newMesh = new btTriangleMesh(*oldMesh); - TriangleMeshShape* newShape = new TriangleMeshShape(newMesh, true); + + // Do not build a new bvh (not needed, since it's the same as the original shape's bvh) + bool buildBvh = true; + if (trishape->getOptimizedBvh()) + buildBvh = false; + TriangleMeshShape* newShape = new TriangleMeshShape(newMesh, true, buildBvh); + // Set original shape's bvh via pointer + // The pointer is safe because the BulletShapeInstance keeps a ref_ptr to the original BulletShape + if (!buildBvh) + newShape->setOptimizedBvh(trishape->getOptimizedBvh()); #endif return newShape; } diff --git a/components/resource/bulletshape.hpp b/components/resource/bulletshape.hpp index 78e509db7..cfae27eac 100644 --- a/components/resource/bulletshape.hpp +++ b/components/resource/bulletshape.hpp @@ -60,8 +60,8 @@ namespace Resource // Subclass btBhvTriangleMeshShape to auto-delete the meshInterface struct TriangleMeshShape : public btBvhTriangleMeshShape { - TriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression) - : btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression) + TriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true) + : btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) { } From ac366f1603213f7ad12b25d35f9b4a97d5053057 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 04:28:20 +0100 Subject: [PATCH 5/7] Fix the rig bounds being updated twice per frame Unlike what I expected, the osgUtil::UpdateVisitor is set to traverse all children (not only active children). The FrameSwitch was thus traversing both RigGeometries part of the double-buffering scheme, rather than only the one active in the current frame. --- components/nifosg/nifloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 45e7c16df..18ece5101 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -100,7 +100,7 @@ namespace virtual void traverse(osg::NodeVisitor& nv) { - if (nv.getTraversalMode() != osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) + if (nv.getTraversalMode() != osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN && nv.getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR) osg::Group::traverse(nv); else { From 8fb328ef4f306cfe1048943aedb3186701b4eca6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 05:19:14 +0100 Subject: [PATCH 6/7] Fix updating of character preview size in InventoryWindow::setGuiMode --- apps/openmw/mwgui/inventorywindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index e5bf1f4b4..7678cb006 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -167,13 +167,15 @@ namespace MWGui MyGUI::IntSize size(static_cast(Settings::Manager::getFloat(setting + " w", "Windows") * viewSize.width), static_cast(Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height)); + bool needUpdate = (size.width != mMainWidget->getWidth() || size.height != mMainWidget->getHeight()); + mMainWidget->setPosition(pos); mMainWidget->setSize(size); - if (size.width != mMainWidget->getWidth() || size.height != mMainWidget->getHeight()) - updatePreviewSize(); - adjustPanes(); + + if (needUpdate) + updatePreviewSize(); } SortFilterItemModel* InventoryWindow::getSortFilterModel() From 0655abcd8b40e41f650def00f7151bba3186194d Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Nov 2015 05:39:51 +0100 Subject: [PATCH 7/7] Fix some character preview raycasting issues (Bug #2769) --- apps/openmw/mwrender/characterpreview.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index f7296b1bd..7ba8369df 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -30,6 +30,7 @@ namespace MWRender public: DrawOnceCallback () : mRendered(false) + , mLastRenderedFrame(0) { } @@ -38,13 +39,14 @@ namespace MWRender if (!mRendered) { mRendered = true; + + mLastRenderedFrame = nv->getTraversalNumber(); + traverse(node, nv); } else { node->setNodeMask(0); } - - traverse(node, nv); } void redrawNextFrame() @@ -52,8 +54,14 @@ namespace MWRender mRendered = false; } + unsigned int getLastRenderedFrame() const + { + return mLastRenderedFrame; + } + private: bool mRendered; + unsigned int mLastRenderedFrame; }; CharacterPreview::CharacterPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, @@ -262,8 +270,11 @@ namespace MWRender int InventoryPreview::getSlotSelected (int posX, int posY) { osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, posX, posY)); - intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_ONE); + intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); osgUtil::IntersectionVisitor visitor(intersector); + visitor.setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN); + // Set the traversal number from the last draw, so that the frame switch used for RigGeometry double buffering works correctly + visitor.setTraversalNumber(mDrawOnceCallback->getLastRenderedFrame()); osg::Node::NodeMask nodeMask = mCamera->getNodeMask(); mCamera->setNodeMask(~0);