From 2de862126a42edad6e6ed0adbb61c34a3b4ae23f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 9 Mar 2014 11:42:39 +0100 Subject: [PATCH 1/9] moved resources group creation from Engine to bsa component --- apps/openmw/engine.cpp | 49 ++------------------------------- apps/openmw/engine.hpp | 3 -- components/CMakeLists.txt | 2 +- components/bsa/resources.cpp | 53 ++++++++++++++++++++++++++++++++++++ components/bsa/resources.hpp | 16 +++++++++++ 5 files changed, 72 insertions(+), 51 deletions(-) create mode 100644 components/bsa/resources.cpp create mode 100644 components/bsa/resources.hpp diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4c3cadb3b6..37821b990f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -12,7 +12,7 @@ #include -#include +#include #include #include #include @@ -192,50 +192,6 @@ OMW::Engine::~Engine() SDL_Quit(); } -// Load BSA files - -void OMW::Engine::loadBSA() -{ - // We use separate resource groups to handle location priority. - const Files::PathContainer& dataDirs = mFileCollections.getPaths(); - - int i=0; - for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) - { - // Last data dir has the highest priority - std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0'); - Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); - - std::string dataDirectory = iter->string(); - std::cout << "Data dir " << dataDirectory << std::endl; - Bsa::addDir(dataDirectory, mFSStrict, groupName); - ++i; - } - - i=0; - for (std::vector::const_iterator archive = mArchives.begin(); archive != mArchives.end(); ++archive) - { - if (mFileCollections.doesExist(*archive)) - { - // Last BSA has the highest priority - std::string groupName = "DataBSA" + Ogre::StringConverter::toString(mArchives.size()-i, 8, '0'); - - Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); - - const std::string archivePath = mFileCollections.getPath(*archive).string(); - std::cout << "Adding BSA archive " << archivePath << std::endl; - Bsa::addBSA(archivePath, groupName); - ++i; - } - else - { - std::stringstream message; - message << "Archive '" << *archive << "' not found"; - throw std::runtime_error(message.str()); - } - } -} - // add resources directory // \note This function works recursively. @@ -385,8 +341,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mOgre->createWindow("OpenMW", windowSettings); - loadBSA(); - + Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict); // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 5c15ddf6fc..e0f51d0dcb 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -101,9 +101,6 @@ namespace OMW /// add a .zip resource void addZipResource (const boost::filesystem::path& path); - /// Load BSA files - void loadBSA(); - void executeLocalScripts(); virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index db4ecad0b1..f8a2969f9d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -15,7 +15,7 @@ add_component_dir (nifoverrides ) add_component_dir (bsa - bsa_archive bsa_file + bsa_archive bsa_file resources ) add_component_dir (nif diff --git a/components/bsa/resources.cpp b/components/bsa/resources.cpp new file mode 100644 index 0000000000..d06b3b4852 --- /dev/null +++ b/components/bsa/resources.cpp @@ -0,0 +1,53 @@ + +#include "resources.hpp" + +#include + +#include +#include + +#include "bsa_archive.hpp" + +void Bsa::registerResources (const Files::Collections& collections, + const std::vector& archives, bool useLooseFiles, bool fsStrict) +{ + const Files::PathContainer& dataDirs = collections.getPaths(); + + int i=0; + + if (useLooseFiles) + for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + { + // Last data dir has the highest priority + std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0'); + Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); + + std::string dataDirectory = iter->string(); + std::cout << "Data dir " << dataDirectory << std::endl; + Bsa::addDir(dataDirectory, fsStrict, groupName); + ++i; + } + + i=0; + for (std::vector::const_iterator archive = archives.begin(); archive != archives.end(); ++archive) + { + if (collections.doesExist(*archive)) + { + // Last BSA has the highest priority + std::string groupName = "DataBSA" + Ogre::StringConverter::toString(archives.size()-i, 8, '0'); + + Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); + + const std::string archivePath = collections.getPath(*archive).string(); + std::cout << "Adding BSA archive " << archivePath << std::endl; + Bsa::addBSA(archivePath, groupName); + ++i; + } + else + { + std::stringstream message; + message << "Archive '" << *archive << "' not found"; + throw std::runtime_error(message.str()); + } + } +} \ No newline at end of file diff --git a/components/bsa/resources.hpp b/components/bsa/resources.hpp new file mode 100644 index 0000000000..8c3fb7bef8 --- /dev/null +++ b/components/bsa/resources.hpp @@ -0,0 +1,16 @@ +#ifndef BSA_BSA_RESOURCES_H +#define BSA_BSA_RESOURCES_H + +#include +#include + +#include "../files/collections.hpp" + +namespace Bsa +{ + void registerResources (const Files::Collections& collections, + const std::vector& archives, bool useLooseFiles, bool fsStrict); + ///< Register resources directories and archives as OGRE resources groups +} + +#endif From 2b17f5dde95044c01e07c494417c93f75e87c0cc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 9 Mar 2014 12:32:21 +0100 Subject: [PATCH 2/9] register resources locations on editor startup --- apps/opencs/editor.cpp | 19 ++++++++++++++----- apps/opencs/editor.hpp | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 2b2f41754b..9eb95fafac 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -11,6 +11,8 @@ #include +#include + #include "model/doc/document.hpp" #include "model/world/data.hpp" @@ -18,14 +20,17 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), mIpcServerName ("org.openmw.OpenCS") { - Files::PathContainer dataDirs = readConfig(); + std::pair > config = readConfig(); - setupDataFiles (dataDirs); + setupDataFiles (config.first); CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg"); ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); + Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, + mFsStrict); + mNewGame.setLocalData (mLocal); mFileDialog.setLocalData (mLocal); @@ -58,7 +63,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) } } -Files::PathContainer CS::Editor::readConfig() +std::pair > CS::Editor::readConfig() { boost::program_options::variables_map variables; boost::program_options::options_description desc("Syntax: opencs \nAllowed options"); @@ -68,7 +73,9 @@ Files::PathContainer CS::Editor::readConfig() ("data-local", boost::program_options::value()->default_value("")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")) - ("resources", boost::program_options::value()->default_value("resources")); + ("resources", boost::program_options::value()->default_value("resources")) + ("fallback-archive", boost::program_options::value >()-> + default_value(std::vector(), "fallback-archive")->multitoken()); boost::program_options::notify(variables); @@ -76,6 +83,8 @@ Files::PathContainer CS::Editor::readConfig() mDocumentManager.setResourceDir (variables["resources"].as()); + mFsStrict = variables["fs-strict"].as(); + Files::PathContainer dataDirs, dataLocal; if (!variables["data"].empty()) { dataDirs = Files::PathContainer(variables["data"].as()); @@ -105,7 +114,7 @@ Files::PathContainer CS::Editor::readConfig() dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); - return dataDirs; + return std::make_pair (dataDirs, variables["fallback-archive"].as >()); } void CS::Editor::createGame() diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 0f1c7a682d..ec417ba8e0 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -41,12 +41,12 @@ namespace CS CSVDoc::NewGameDialogue mNewGame; CSVSettings::UserSettingsDialog mSettings; CSVDoc::FileDialog mFileDialog; - boost::filesystem::path mLocal; + bool mFsStrict; void setupDataFiles (const Files::PathContainer& dataDirs); - Files::PathContainer readConfig(); + std::pair > readConfig(); ///< \return data paths // not implemented From 7812427836200bfcb01ebd48477d319822125381 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 10 Mar 2014 12:44:34 +0100 Subject: [PATCH 3/9] added Preview submenu item; fixed View issues regarding exterior cells --- apps/opencs/model/world/data.cpp | 6 +-- apps/opencs/model/world/idtable.cpp | 9 ++++- apps/opencs/model/world/idtable.hpp | 5 ++- apps/opencs/model/world/universalid.cpp | 2 + apps/opencs/model/world/universalid.hpp | 3 +- apps/opencs/view/world/scenesubview.cpp | 2 +- apps/opencs/view/world/table.cpp | 51 ++++++++++++++++++------- apps/opencs/view/world/table.hpp | 3 ++ 8 files changed, 60 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d68b79ff0a..d60dcae117 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -250,9 +250,9 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo); addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell); - addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, - UniversalId::Type_Referenceable); - addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell), UniversalId::Type_References, UniversalId::Type_Reference, false); + addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true), + UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); + addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false); addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false); } diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 453a7da6a3..56b16f5a15 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -5,8 +5,8 @@ #include "columnbase.hpp" CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering, - Viewing viewing) -: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing) + Viewing viewing, bool preview) +: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview) {} CSMWorld::IdTable::~IdTable() @@ -196,6 +196,11 @@ CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const return mViewing; } +bool CSMWorld::IdTable::hasPreview() const +{ + return mPreview; +} + std::pair CSMWorld::IdTable::view (int row) const { std::string id; diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 5a271de443..7d812b083f 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -39,6 +39,7 @@ namespace CSMWorld CollectionBase *mIdCollection; Reordering mReordering; Viewing mViewing; + bool mPreview; // not implemented IdTable (const IdTable&); @@ -47,7 +48,7 @@ namespace CSMWorld public: IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None, - Viewing viewing = Viewing_None); + Viewing viewing = Viewing_None, bool preview = false); ///< The ownership of \a idCollection is not transferred. virtual ~IdTable(); @@ -100,6 +101,8 @@ namespace CSMWorld Viewing getViewing() const; + bool hasPreview() const; + std::pair view (int row) const; ///< Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 1d1b3c960f..a62acc02bb 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -92,6 +92,8 @@ namespace { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, + { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, + { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 0c17da03be..34167cd854 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -95,7 +95,8 @@ namespace CSMWorld Type_TopicInfo, Type_JournalInfos, Type_JournalInfo, - Type_Scene + Type_Scene, + Type_Preview }; enum { NumberOfTypes = Type_Scene+1 }; diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3601ae0942..66e0266046 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -34,7 +34,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolbar *toolbar = new SceneToolbar (48, this); - if (id.getId()[0]=='#') + if (id.getId()=="sys::default") mScene = new CSVRender::PagedWorldspaceWidget (this); else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 4bb9955e6e..29bca2f6b3 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -39,18 +39,6 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) if (mCreateAction) menu.addAction(mCloneAction); - - if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None) - { - int row = selectedRows.begin()->row(); - - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - - CSMWorld::UniversalId id = mModel->view (row).first; - - if (!mDocument.getData().getCells().getRecord (id.getId()).isDeleted()) - menu.addAction (mViewAction); - } } if (mCreateAction) @@ -95,6 +83,28 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) } } + if (selectedRows.size()==1) + { + if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None) + { + int row = selectedRows.begin()->row(); + + row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + + CSMWorld::UniversalId id = mModel->view (row).first; + + int index = mDocument.getData().getCells().searchId (id.getId()); + // index==-1: the ID references a worldspace instead of a cell (ignore for now and go + // ahead) + + if (index==-1 || !mDocument.getData().getCells().getRecord (index).isDeleted()) + menu.addAction (mViewAction); + } + + if (mModel->hasPreview()) + menu.addAction (mPreviewAction); + } + menu.exec (event->globalPos()); } @@ -249,6 +259,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord())); addAction (mViewAction); + mPreviewAction = new QAction (tr ("Preview"), this); + connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord())); + addAction (mPreviewAction); + connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (tableSizeUpdate())); @@ -406,7 +420,7 @@ void CSVWorld::Table::viewRecord() if (selectedRows.size()==1) { - int row =selectedRows.begin()->row(); + int row = selectedRows.begin()->row(); row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); @@ -417,6 +431,17 @@ void CSVWorld::Table::viewRecord() } } +void CSVWorld::Table::previewRecord() +{ + QModelIndexList selectedRows = selectionModel()->selectedRows(); + + if (selectedRows.size()==1) + { + std::string id = getUniversalId (selectedRows.begin()->row()).getId(); + + emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , ""); + } +} void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue) { int columns = mModel->columnCount(); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index e8d5648d16..4231a4a432 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -44,6 +44,7 @@ namespace CSVWorld QAction *mMoveUpAction; QAction *mMoveDownAction; QAction *mViewAction; + QAction *mPreviewAction; CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTable *mModel; bool mEditLock; @@ -111,6 +112,8 @@ namespace CSVWorld void viewRecord(); + void previewRecord(); + public slots: void tableSizeUpdate(); From ef1364878fc98876726759911a18b97ee5b6965e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 10 Mar 2014 18:35:49 +0100 Subject: [PATCH 4/9] moved test cube from SceneWidget to WorldspaceWidget --- apps/opencs/view/render/scenewidget.cpp | 10 +++++----- apps/opencs/view/render/scenewidget.hpp | 2 ++ apps/opencs/view/render/worldspacewidget.cpp | 11 ++++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 31d5d03187..7b790fd581 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -45,11 +45,6 @@ namespace CSVRender mCamera = mSceneMgr->createCamera("foo"); - Ogre::Entity* ent = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE); - ent->setMaterialName("BaseWhite"); - - mSceneMgr->getRootSceneNode()->attachObject(ent); - mCamera->setPosition(300,300,300); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); @@ -118,6 +113,11 @@ namespace CSVRender } } + Ogre::SceneManager *SceneWidget::getSceneManager() + { + return mSceneMgr; + } + void SceneWidget::paintEvent(QPaintEvent* e) { if (!mWindow) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index ad68897ac0..05b06b2873 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -34,6 +34,8 @@ namespace CSVRender void setNavigation (Navigation *navigation); ///< \attention The ownership of \a navigation is not transferred to *this. + Ogre::SceneManager *getSceneManager(); + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index dcd152bb33..9959c5a673 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -1,11 +1,20 @@ #include "worldspacewidget.hpp" +#include +#include +#include + #include "../world/scenetoolmode.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent) : SceneWidget (parent) -{} +{ + Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE); + ent->setMaterialName("BaseWhite"); + + getSceneManager()->getRootSceneNode()->attachObject(ent); +} void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) { From c36dfef972b858d0b640f0bb0f1f0604c685dce2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 12:44:01 +0100 Subject: [PATCH 5/9] prewview subview --- apps/opencs/CMakeLists.txt | 8 +++- apps/opencs/editor.cpp | 47 +++++++++++++++++++-- apps/opencs/editor.hpp | 8 ++++ apps/opencs/main.cpp | 6 +++ apps/opencs/view/render/previewwidget.cpp | 45 ++++++++++++++++++++ apps/opencs/view/render/previewwidget.hpp | 42 +++++++++++++++++++ apps/opencs/view/world/previewsubview.cpp | 50 +++++++++++++++++++++++ apps/opencs/view/world/previewsubview.hpp | 36 ++++++++++++++++ apps/opencs/view/world/subviews.cpp | 3 ++ 9 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 apps/opencs/view/render/previewwidget.cpp create mode 100644 apps/opencs/view/render/previewwidget.hpp create mode 100644 apps/opencs/view/world/previewsubview.cpp create mode 100644 apps/opencs/view/world/previewsubview.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 621b9bf869..7cdaad5bea 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,11 +60,12 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit + scenetoolmode infocreator scriptedit previewsubview ) opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget + previewwidget ) opencs_units_noqt (view/render @@ -147,6 +148,9 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) +set(BOOST_COMPONENTS system filesystem program_options thread wave) +find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) include(${QT_USE_FILE}) @@ -187,6 +191,8 @@ if(APPLE) endif(APPLE) target_link_libraries(opencs + ${OGRE_LIBRARIES} + ${SHINY_LIBRARIES} ${Boost_LIBRARIES} ${QT_LIBRARIES} components diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 9eb95fafac..942780c32b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include + #include #include @@ -81,7 +84,7 @@ std::pair > CS::Editor::readConfi mCfgMgr.readConfiguration(variables, desc); - mDocumentManager.setResourceDir (variables["resources"].as()); + mDocumentManager.setResourceDir (mResources = variables["resources"].as()); mFsStrict = variables["fs-strict"].as(); @@ -225,6 +228,15 @@ int CS::Editor::run() if (mLocal.empty()) return 1; + mStartup.show(); + + QApplication::setQuitOnLastWindowClosed (true); + + return QApplication::exec(); +} + +std::auto_ptr CS::Editor::setupGraphics() +{ // TODO: setting Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem")); @@ -242,9 +254,36 @@ int CS::Editor::run() Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms); hiddenWindow->setActive(false); - mStartup.show(); + sh::OgrePlatform* platform = + new sh::OgrePlatform ("General", (mResources / "materials").string()); - QApplication::setQuitOnLastWindowClosed (true); + if (!boost::filesystem::exists (mCfgMgr.getCachePath())) + boost::filesystem::create_directories (mCfgMgr.getCachePath()); - return QApplication::exec(); + platform->setCacheFolder (mCfgMgr.getCachePath().string()); + + std::auto_ptr factory (new sh::Factory (platform)); + + factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable + factory->setWriteSourceCache (true); + factory->setReadSourceCache (true); + factory->setReadMicrocodeCache (true); + factory->setWriteMicrocodeCache (true); + + factory->loadAllFiles(); + + sh::Factory::getInstance().setGlobalSetting ("fog", "true"); + + sh::Factory::getInstance().setGlobalSetting ("shadows", "false"); + sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8"); + + /// \todo add more configurable shiny settings + + return factory; } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index ec417ba8e0..164398fb73 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -1,11 +1,15 @@ #ifndef CS_EDITOR_H #define CS_EDITOR_H +#include + #include #include #include #include +#include + #ifndef Q_MOC_RUN #include #endif @@ -42,6 +46,7 @@ namespace CS CSVSettings::UserSettingsDialog mSettings; CSVDoc::FileDialog mFileDialog; boost::filesystem::path mLocal; + boost::filesystem::path mResources; bool mFsStrict; void setupDataFiles (const Files::PathContainer& dataDirs); @@ -63,6 +68,9 @@ namespace CS int run(); ///< \return error status + std::auto_ptr setupGraphics(); + ///< The returned factory must persist at least as long as *this. + private slots: void createGame(); diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index 212ed08367..eded36394a 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #ifdef Q_OS_MAC @@ -42,6 +44,8 @@ int main(int argc, char *argv[]) OgreInit::OgreInit ogreInit; + std::auto_ptr shinyFactory; + Application application (argc, argv); #ifdef Q_OS_MAC @@ -73,5 +77,7 @@ int main(int argc, char *argv[]) // return 0; } + shinyFactory = editor.setupGraphics(); + return editor.run(); } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp new file mode 100644 index 0000000000..160240b172 --- /dev/null +++ b/apps/opencs/view/render/previewwidget.cpp @@ -0,0 +1,45 @@ + +#include "previewwidget.hpp" + +#include + +#include "../../model/world/data.hpp" + +void CSVRender::PreviewWidget::setup (const std::string& id) +{ + setNavigation (&mOrbit); + + int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + + int row = mData.getReferenceables().getIndex (id); + + QVariant value = mData.getReferenceables().getData (row, column); + + if (!value.isValid()) + return; + + std::string model = value.toString().toUtf8().constData(); + + if (model.empty()) + return; + + Ogre::SceneNode* node = getSceneManager()->getRootSceneNode()->createChildSceneNode(); + node->setPosition (Ogre::Vector3 (0, 0, 0)); + + mObject = NifOgre::Loader::createObjects (node, "Meshes\\" + model); +} + +CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, + const std::string& referenceableId, QWidget *parent) +: SceneWidget (parent), mData (data) +{ + setup (referenceableId); +} + +CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, + const std::string& referenceableId, const std::string& referenceId, QWidget *parent) +: SceneWidget (parent), mData (data) +{ + setup (referenceableId); + /// \todo apply reference modifications (scale, rotation) +} diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp new file mode 100644 index 0000000000..01d40050fb --- /dev/null +++ b/apps/opencs/view/render/previewwidget.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCS_VIEW_PREVIEWWIDGET_H +#define OPENCS_VIEW_PREVIEWWIDGET_H + +#include + +#include "scenewidget.hpp" + +#include "navigationorbit.hpp" + +namespace CSMWorld +{ + class Data; +} + +namespace CSVRender +{ + class PreviewWidget : public SceneWidget + { + Q_OBJECT + + const CSMWorld::Data& mData; + CSVRender::NavigationOrbit mOrbit; + NifOgre::ObjectScenePtr mObject; + + void setup (const std::string& id); + ///< \param id ID of the referenceable to be viewed + + public: + + PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + QWidget *parent = 0); + + PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + const std::string& referenceId, QWidget *parent = 0); + + signals: + + void closeRequest(); + }; +} + +#endif diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp new file mode 100644 index 0000000000..0fa1d3b174 --- /dev/null +++ b/apps/opencs/view/world/previewsubview.cpp @@ -0,0 +1,50 @@ + +#include "previewsubview.hpp" + +#include + +#include "../render/scenewidget.hpp" + +#include "scenetoolbar.hpp" + +#include "../render/previewwidget.hpp" + +CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) +: SubView (id) +{ + QHBoxLayout *layout = new QHBoxLayout; + + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + if (document.getData().getReferenceables().searchId (id.getId())==-1) + { + std::string referenceableId = + document.getData().getReferences().getRecord (id.getId()).get().mRefID; + + mScene = + new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); + } + else + mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this); + + SceneToolbar *toolbar = new SceneToolbar (48, this); + + layout->addWidget (toolbar, 0); + + layout->addWidget (mScene, 1); + + QWidget *widget = new QWidget; + + widget->setLayout (layout); + + setWidget (widget); + + connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); +} + +void CSVWorld::PreviewSubView::setEditLock (bool locked) {} + +void CSVWorld::PreviewSubView::closeRequest() +{ + deleteLater(); +} \ No newline at end of file diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp new file mode 100644 index 0000000000..e7a2a261ed --- /dev/null +++ b/apps/opencs/view/world/previewsubview.hpp @@ -0,0 +1,36 @@ +#ifndef CSV_WORLD_PREVIEWSUBVIEW_H +#define CSV_WORLD_PREVIEWSUBVIEW_H + +#include "../doc/subview.hpp" + +namespace CSMDoc +{ + class Document; +} + +namespace CSVRender +{ + class PreviewWidget; +} + +namespace CSVWorld +{ + class PreviewSubView : public CSVDoc::SubView + { + Q_OBJECT + + CSVRender::PreviewWidget *mScene; + + public: + + PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + + virtual void setEditLock (bool locked); + + private slots: + + void closeRequest(); + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 74ce03cce6..33a91330df 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -16,6 +16,7 @@ #include "scenesubview.hpp" #include "dialoguecreator.hpp" #include "infocreator.hpp" +#include "previewsubview.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { @@ -78,4 +79,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CreatorFactory >); manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + + manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); } \ No newline at end of file From fa042a8aca3ca1ed8e11506763f8c6fd5987995f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 13:22:32 +0100 Subject: [PATCH 6/9] use proper title for reference prewview subviews (avoid internal ID) --- apps/opencs/view/render/previewwidget.hpp | 2 +- apps/opencs/view/world/previewsubview.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 01d40050fb..c8834775b5 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -20,7 +20,7 @@ namespace CSVRender const CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; - NifOgre::ObjectScenePtr mObject; + NifOgre::ObjectScenePtr mObject; void setup (const std::string& id); ///< \param id ID of the referenceable to be viewed diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 0fa1d3b174..587af561fb 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -21,6 +21,8 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo std::string referenceableId = document.getData().getReferences().getRecord (id.getId()).get().mRefID; + setWindowTitle (("Preview: Reference to " + referenceableId).c_str()); + mScene = new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); } From 48ea93d8907e2a7ba22cd555e6f35bfdf0ffef4d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:06:30 +0100 Subject: [PATCH 7/9] less random camera start position --- apps/opencs/view/render/scenewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 7b790fd581..5a2d93385c 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -45,7 +45,7 @@ namespace CSVRender mCamera = mSceneMgr->createCamera("foo"); - mCamera->setPosition(300,300,300); + mCamera->setPosition(300,0,000); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(3000); From 6b11265fbc0b4d78dcd89554a2af3472bb0fb9d4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:06:45 +0100 Subject: [PATCH 8/9] consider scale and orientation when previewing reference --- apps/opencs/view/render/previewwidget.cpp | 37 ++++++++++++++++++++--- apps/opencs/view/render/previewwidget.hpp | 4 +++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 160240b172..43d45f4cb9 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -23,15 +23,42 @@ void CSVRender::PreviewWidget::setup (const std::string& id) if (model.empty()) return; - Ogre::SceneNode* node = getSceneManager()->getRootSceneNode()->createChildSceneNode(); - node->setPosition (Ogre::Vector3 (0, 0, 0)); + mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); + mNode->setPosition (Ogre::Vector3 (0, 0, 0)); - mObject = NifOgre::Loader::createObjects (node, "Meshes\\" + model); + mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); +} + +void CSVRender::PreviewWidget::adjust (const std::string& id) +{ + if (mNode) + { + int row = mData.getReferences().getIndex (id); + + float scale = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); + float rotX = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat(); + float rotY = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat(); + float rotZ = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat(); + + mNode->setScale (scale, scale, scale); + + Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X); + + Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y); + + Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z); + + mNode->setOrientation (xr*yr*zr); + } } CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent) -: SceneWidget (parent), mData (data) +: SceneWidget (parent), mData (data), mNode (0) { setup (referenceableId); } @@ -41,5 +68,5 @@ CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, : SceneWidget (parent), mData (data) { setup (referenceableId); - /// \todo apply reference modifications (scale, rotation) + adjust (referenceId); } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index c8834775b5..b3abd55879 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -21,10 +21,14 @@ namespace CSVRender const CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; NifOgre::ObjectScenePtr mObject; + Ogre::SceneNode *mNode; void setup (const std::string& id); ///< \param id ID of the referenceable to be viewed + void adjust (const std::string& id); + ///< \param id ID of the reference to be viewed + public: PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, From 20ea859aac470906a1410fbf0602e9a52fc2c656 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:14:44 +0100 Subject: [PATCH 9/9] adjusted the far clip distance --- apps/opencs/view/render/scenewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5a2d93385c..5eec702d3d 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -48,7 +48,7 @@ namespace CSVRender mCamera->setPosition(300,0,000); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); - mCamera->setFarClipDistance(3000); + mCamera->setFarClipDistance(30000); QTimer *timer = new QTimer (this);