From af27a10b0cc541cfc16d465ff12d0f164edfa04b Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Mar 2015 00:39:24 +0100 Subject: [PATCH] OpenCS: preliminary port of PreviewWidget to OSG --- apps/opencs/model/doc/document.cpp | 9 +++- apps/opencs/model/doc/document.hpp | 11 +++- apps/opencs/model/doc/documentmanager.cpp | 5 +- apps/opencs/model/doc/documentmanager.hpp | 2 +- apps/opencs/view/render/cell.cpp | 6 +-- apps/opencs/view/render/object.cpp | 65 +++++++++-------------- apps/opencs/view/render/object.hpp | 24 +++++---- apps/opencs/view/render/previewwidget.cpp | 12 +---- apps/opencs/view/render/previewwidget.hpp | 9 +++- apps/opencs/view/render/scenewidget.cpp | 15 ++++-- apps/opencs/view/render/scenewidget.hpp | 7 +++ apps/opencs/view/world/previewsubview.cpp | 4 +- components/nifosg/nifloader.hpp | 2 +- 13 files changed, 92 insertions(+), 79 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index e688a9474..2a5fa7746 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2245,12 +2245,12 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, +CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, const std::vector& blacklistedScripts) -: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager), +: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager), mTools (*this), mResDir(resDir), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), @@ -2311,6 +2311,11 @@ CSMDoc::Document::~Document() { } +const VFS::Manager *CSMDoc::Document::getVFS() const +{ + return mVFS; +} + QUndoStack& CSMDoc::Document::getUndoStack() { return mUndoStack; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index f3aef6db6..2d42e9903 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -23,6 +23,12 @@ class QAbstractItemModel; +namespace VFS +{ + + class Manager; +} + namespace ESM { struct GameSetting; @@ -53,6 +59,7 @@ namespace CSMDoc private: + const VFS::Manager* mVFS; boost::filesystem::path mSavePath; std::vector mContentFiles; bool mNew; @@ -91,7 +98,7 @@ namespace CSMDoc public: - Document (const Files::ConfigurationManager& configuration, + Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager, @@ -99,6 +106,8 @@ namespace CSMDoc ~Document(); + const VFS::Manager* getVFS() const; + QUndoStack& getUndoStack(); int getState() const; diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index ecff4bbed..edce6e613 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -13,7 +13,7 @@ #include "document.hpp" CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) -: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252) +: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mVFS(NULL) { boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; @@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager() void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts); + Document *document = new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts); mDocuments.push_back (document); @@ -107,4 +107,5 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std:: void CSMDoc::DocumentManager::setVFS(const VFS::Manager *vfs) { mResourcesManager.setVFS(vfs); + mVFS = vfs; } diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index a12d22c4e..8dc4f338a 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -40,7 +40,7 @@ namespace CSMDoc ToUTF8::FromType mEncoding; CSMWorld::ResourcesManager mResourcesManager; std::vector mBlacklistedScripts; - VFS::Manager* mVFS; + const VFS::Manager* mVFS; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index a0d0f6e71..72ceb654a 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -51,7 +51,7 @@ bool CSVRender::Cell::addObjects (int start, int end) std::string id = Misc::StringUtils::lowerCase (references.data ( references.index (i, idColumn)).toString().toUtf8().constData()); - mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); + //mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); modified = true; } } @@ -191,8 +191,8 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, // add new objects for (std::map::iterator iter (ids.begin()); iter!=ids.end(); ++iter) { - mObjects.insert (std::make_pair ( - iter->first, new Object (mData, mCellNode, iter->first, false, mPhysics))); + //mObjects.insert (std::make_pair ( + // iter->first, new Object (mData, mCellNode, iter->first, false, mPhysics))); modified = true; } diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index b54551c96..2434343c9 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -1,9 +1,6 @@ - #include "object.hpp" -#include -#include -#include +#include #include "../../model/world/data.hpp" #include "../../model/world/ref.hpp" @@ -11,43 +8,20 @@ #include "../world/physicssystem.hpp" -#include "elements.hpp" +#include -void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node) -{ - for (Ogre::SceneNode::ObjectIterator iter = node->getAttachedObjectIterator(); - iter.hasMoreElements(); ) - { - Ogre::MovableObject* object = dynamic_cast (iter.getNext()); - node->getCreator()->destroyMovableObject (object); - } - - for (Ogre::SceneNode::ChildNodeIterator iter = node->getChildIterator(); - iter.hasMoreElements(); ) - { - Ogre::SceneNode* childNode = dynamic_cast (iter.getNext()); - clearSceneNode (childNode); - node->getCreator()->destroySceneNode (childNode); - } -} +#include "elements.hpp" void CSVRender::Object::clear() { - mObject.setNull(); - - if (mBase) - clearSceneNode (mBase); } void CSVRender::Object::update() { - if(!mObject.isNull()) - mPhysics->removePhysicsObject(mBase->getName()); - clear(); std::string model; - int error = 0; // 1 referemceanöe does not exist, 2 referenceable does not specify a mesh + int error = 0; // 1 referenceable does not exist, 2 referenceable does not specify a mesh const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); @@ -69,17 +43,28 @@ void CSVRender::Object::update() if (error) { + /* Ogre::Entity* entity = mBase->getCreator()->createEntity (Ogre::SceneManager::PT_CUBE); entity->setMaterialName("BaseWhite"); /// \todo adjust material according to error entity->setVisibilityFlags (Element_Reference); mBase->attachObject (entity); + */ } else { - //mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model); + NifOsg::Loader loader; + loader.resourceManager = mVFS; + + std::string path = "meshes\\" + model; + + Nif::NIFFilePtr file(new Nif::NIFFile(mVFS->get(path), path)); + + loader.load(file, mBaseNode); + //mObject->setVisibilityFlags (Element_Reference); + /* if (mPhysics && !mReferenceId.empty()) { const CSMWorld::CellRef& reference = getReference(); @@ -96,11 +81,13 @@ void CSVRender::Object::update() mPhysics->addObject("meshes\\" + model, mBase->getName(), mReferenceId, reference.mScale, position, xr*yr*zr); } + */ } } void CSVRender::Object::adjust() { + /* if (mReferenceId.empty()) return; @@ -122,6 +109,7 @@ void CSVRender::Object::adjust() // scale mBase->setScale (reference.mScale, reference.mScale, reference.mScale); + */ } const CSMWorld::CellRef& CSVRender::Object::getReference() const @@ -132,12 +120,13 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const return mData.getReferences().getRecord (mReferenceId).get(); } -CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, +CSVRender::Object::Object (const VFS::Manager* vfs, const CSMWorld::Data& data, osg::Group* parentNode, const std::string& id, bool referenceable, boost::shared_ptr physics, bool forceBaseToZero) -: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics) +: mVFS(vfs), mData (data), mBaseNode(0), mParentNode(parentNode), mForceBaseToZero (forceBaseToZero), mPhysics(physics) { - mBase = cellNode->createChildSceneNode(); + mBaseNode = new osg::Group; + parentNode->addChild(mBaseNode); if (referenceable) { @@ -157,13 +146,7 @@ CSVRender::Object::~Object() { clear(); - if (mBase) - { - if(mPhysics) // preview may not have physics enabled - mPhysics->removeObject(mBase->getName()); - - mBase->getCreator()->destroySceneNode (mBase); - } + mParentNode->removeChild(mBaseNode); } bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 3ed4fa793..8e9598bbf 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -3,15 +3,19 @@ #include -#ifndef Q_MOC_RUN -#include -#endif +#include class QModelIndex; -namespace Ogre + +namespace osg +{ + class Group; +} + +namespace VFS { - class SceneNode; + class Manager; } namespace CSMWorld @@ -32,8 +36,9 @@ namespace CSVRender const CSMWorld::Data& mData; std::string mReferenceId; std::string mReferenceableId; - Ogre::SceneNode *mBase; - NifOgre::ObjectScenePtr mObject; + osg::ref_ptr mBaseNode; + osg::Group* mParentNode; + const VFS::Manager* mVFS; bool mForceBaseToZero; boost::shared_ptr mPhysics; @@ -43,9 +48,6 @@ namespace CSVRender /// Not implemented Object& operator= (const Object&); - /// Destroy all scene nodes and movable objects attached to node. - static void clearSceneNode (Ogre::SceneNode *node); - /// Remove object from node (includes deleting) void clear(); @@ -60,7 +62,7 @@ namespace CSVRender public: - Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, + Object (const VFS::Manager* vfs, const CSMWorld::Data& data, osg::Group *cellNode, const std::string& id, bool referenceable, boost::shared_ptr physics = boost::shared_ptr (), bool forceBaseToZero = false); diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 6982cad52..ee43ac13c 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -7,9 +7,9 @@ #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" -CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, +CSVRender::PreviewWidget::PreviewWidget (const VFS::Manager* vfs, CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent) -: SceneWidget (parent), mData (data) +: SceneWidget (parent), mData (data), mObject(vfs, data, mRootNode, id, referenceable) { //setNavigation (&mOrbit); @@ -36,7 +36,6 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { -#if 0 if (mObject.referenceableDataChanged (topLeft, bottomRight)) flagAsModified(); @@ -51,13 +50,11 @@ void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topL if (referenceables.data (index).toInt()==CSMWorld::RecordBase::State_Deleted) emit closeRequest(); } -#endif } void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) { -#if 0 if (mObject.referenceableAboutToBeRemoved (parent, start, end)) flagAsModified(); @@ -77,13 +74,11 @@ void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& emit closeRequest(); } } -#endif } void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { -#if 0 if (mObject.referenceDataChanged (topLeft, bottomRight)) flagAsModified(); @@ -112,13 +107,11 @@ void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft, if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) emit referenceableIdChanged (mObject.getReferenceableId()); -#endif } void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) { -#if 0 if (mObject.getReferenceId().empty()) return; @@ -129,5 +122,4 @@ void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& par if (index.row()>=start && index.row()<=end) emit closeRequest(); -#endif } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 7260ee242..dfe05b484 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -8,6 +8,11 @@ class QModelIndex; +namespace VFS +{ + class Manager; +} + namespace CSMWorld { class Data; @@ -21,11 +26,11 @@ namespace CSVRender CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; - //Object mObject; + CSVRender::Object mObject; public: - PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, + PreviewWidget (const VFS::Manager* vfs, CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent = 0); signals: diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 82dc4c211..2f28c06df 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -16,12 +16,14 @@ #include #include +#include namespace CSVRender { SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) + , mRootNode(0) { #if QT_VERSION >= 0x050000 @@ -37,6 +39,7 @@ SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f) setKeyEventSetsDone(0); osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); + //ds->setNumMultiSamples(8); osg::ref_ptr traits = new osg::GraphicsContext::Traits; traits->windowName = ""; traits->windowDecoration = true; @@ -49,6 +52,8 @@ SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f) traits->stencil = ds->getMinimumNumStencilBits(); traits->sampleBuffers = ds->getMultiSamples(); traits->samples = ds->getNumMultiSamples(); + // Doesn't make much sense as we're running on demand updates, and there seems to be a bug with the refresh rate when running multiple QGLWidgets + traits->vsync = false; osgQt::GraphicsWindowQt* window = new osgQt::GraphicsWindowQt(traits.get()); QLayout* layout = new QHBoxLayout(this); @@ -59,15 +64,19 @@ SceneWidget::SceneWidget(QWidget *parent, Qt::WindowFlags f) getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); - //getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast(traits->width)/static_cast(traits->height), 1.0f, 10000.0f ); + getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast(traits->width)/static_cast(traits->height), 1.0f, 10000.0f ); - osg::Node* root = new osg::Node; - setSceneData(root); + mRootNode = new osg::Group; + setSceneData(mRootNode); + + // Press S to reveal profiling stats + addEventHandler(new osgViewer::StatsHandler); setCameraManipulator(new osgGA::TrackballManipulator); // Only render when the camera position changed, or content flagged dirty //setRunFrameScheme(osgViewer::ViewerBase::ON_DEMAND); + setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS); connect( &mTimer, SIGNAL(timeout()), this, SLOT(update()) ); mTimer.start( 10 ); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 0cdf1ef99..3784a5c59 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -10,6 +10,11 @@ #include +namespace osg +{ + class Group; +} + namespace CSVWidget { class SceneToolMode; @@ -34,6 +39,8 @@ namespace CSVRender protected: + osg::Group* mRootNode; + QTimer mTimer; }; diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 0c9823c44..c82d1b82e 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -23,10 +23,10 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo referenceableIdChanged (referenceableId); mScene = - new CSVRender::PreviewWidget (document.getData(), id.getId(), false, this); + new CSVRender::PreviewWidget (document.getVFS(), document.getData(), id.getId(), false, this); } else - mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), true, this); + mScene = new CSVRender::PreviewWidget (document.getVFS(), document.getData(), id.getId(), true, this); CSVWidget::SceneToolbar *toolbar = new CSVWidget::SceneToolbar (48+6, this); diff --git a/components/nifosg/nifloader.hpp b/components/nifosg/nifloader.hpp index 5a0c901c1..7b38ce560 100644 --- a/components/nifosg/nifloader.hpp +++ b/components/nifosg/nifloader.hpp @@ -39,7 +39,7 @@ namespace NifOsg void loadAsSkeleton(Nif::NIFFilePtr file, osg::Group* parentNode); - VFS::Manager* resourceManager; + const VFS::Manager* resourceManager; // FIXME move std::vector mControllers;