mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw into dialogoue3
This commit is contained in:
commit
020e3f8fc5
@ -7,7 +7,6 @@ branches:
|
||||
- /openmw-.*$/
|
||||
before_install:
|
||||
- pwd
|
||||
- git fetch --tags
|
||||
- echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
|
||||
- echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
||||
- sudo apt-get update -qq
|
||||
|
@ -6,34 +6,63 @@ if (APPLE)
|
||||
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
|
||||
endif (APPLE)
|
||||
|
||||
# Macros
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||
|
||||
include(OpenMWMacros)
|
||||
|
||||
# Version
|
||||
message(STATUS "Configuring OpenMW...")
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
set(OPENMW_VERSION_MAJOR 0)
|
||||
set(OPENMW_VERSION_MINOR 29)
|
||||
set(OPENMW_VERSION_RELEASE 0)
|
||||
|
||||
get_git_tag_revision(TAGHASH --tags --max-count=1 "HEAD...")
|
||||
get_git_head_revision(REFSPEC COMMITHASH)
|
||||
git_describe(VERSION --tags ${TAGHASH})
|
||||
set(OPENMW_VERSION_COMMITHASH "")
|
||||
set(OPENMW_VERSION_TAGHASH "")
|
||||
|
||||
string(REGEX MATCH "^openmw-[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" MATCH "${VERSION}")
|
||||
if (MATCH)
|
||||
string(REGEX REPLACE "^openmw-([0-9]+)\\..*" "\\1" OPENMW_VERSION_MAJOR "${VERSION}")
|
||||
string(REGEX REPLACE "^openmw-[0-9]+\\.([0-9]+).*" "\\1" OPENMW_VERSION_MINOR "${VERSION}")
|
||||
string(REGEX REPLACE "^openmw-[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" OPENMW_VERSION_RELEASE "${VERSION}")
|
||||
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
|
||||
set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}")
|
||||
set(OPENMW_VERSION_TAGHASH "${TAGHASH}")
|
||||
if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow)
|
||||
find_package(Git)
|
||||
|
||||
message(STATUS "Configuring OpenMW ${OPENMW_VERSION}...")
|
||||
else (MATCH)
|
||||
message(FATAL_ERROR "Failed to get valid version information from Git")
|
||||
endif (MATCH)
|
||||
if(GIT_FOUND)
|
||||
include(GetGitRevisionDescription)
|
||||
get_git_tag_revision(TAGHASH --tags --max-count=1)
|
||||
get_git_head_revision(REFSPEC COMMITHASH)
|
||||
git_describe(VERSION --tags ${TAGHASH})
|
||||
|
||||
string(REGEX MATCH "^openmw-[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" MATCH "${VERSION}")
|
||||
if(MATCH)
|
||||
string(REGEX REPLACE "^openmw-([0-9]+)\\..*" "\\1" GIT_VERSION_MAJOR "${VERSION}")
|
||||
string(REGEX REPLACE "^openmw-[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_MINOR "${VERSION}")
|
||||
string(REGEX REPLACE "^openmw-[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_RELEASE "${VERSION}")
|
||||
|
||||
set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}")
|
||||
|
||||
if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION})
|
||||
message(FATAL_ERROR "Silly Zini forgot to update the version again...")
|
||||
else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION})
|
||||
set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR})
|
||||
set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR})
|
||||
set(OPENMW_VERSION_RELEASE ${GIT_VERSION_RELEASE})
|
||||
|
||||
set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}")
|
||||
set(OPENMW_VERSION_TAGHASH "${TAGHASH}")
|
||||
endif(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION})
|
||||
|
||||
message(STATUS "OpenMW version ${OPENMW_VERSION}")
|
||||
else(MATCH)
|
||||
message(WARNING "Failed to get valid version information from Git")
|
||||
endif(MATCH)
|
||||
else(GIT_FOUND)
|
||||
message(WARNING "Git executable not found")
|
||||
endif(GIT_FOUND)
|
||||
else(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow)
|
||||
message(STATUS "Shallow Git clone detected, not attempting to retrieve version info")
|
||||
endif(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/shallow)
|
||||
endif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||
|
||||
# Macros
|
||||
include(OpenMWMacros)
|
||||
|
||||
# doxygen main page
|
||||
|
||||
@ -209,6 +238,14 @@ if (UNIX AND NOT APPLE)
|
||||
find_package (Threads)
|
||||
endif()
|
||||
|
||||
# Look for stdint.h
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(stdint.h HAVE_STDINT_H)
|
||||
if(NOT HAVE_STDINT_H)
|
||||
unset(HAVE_STDINT_H CACHE)
|
||||
message(FATAL_ERROR "stdint.h was not found" )
|
||||
endif()
|
||||
|
||||
include (CheckIncludeFileCXX)
|
||||
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
|
||||
if (HAVE_UNORDERED_MAP)
|
||||
|
@ -76,17 +76,20 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||
QString revision(OPENMW_VERSION_COMMITHASH);
|
||||
QString tag(OPENMW_VERSION_TAGHASH);
|
||||
|
||||
if (revision == tag) {
|
||||
versionLabel->setText(tr("OpenMW %0 release").arg(OPENMW_VERSION));
|
||||
} else {
|
||||
versionLabel->setText(tr("OpenMW development (%0)").arg(revision.left(10)));
|
||||
}
|
||||
if (!revision.isEmpty() && !tag.isEmpty())
|
||||
{
|
||||
if (revision == tag) {
|
||||
versionLabel->setText(tr("OpenMW %0 release").arg(OPENMW_VERSION));
|
||||
} else {
|
||||
versionLabel->setText(tr("OpenMW development (%0)").arg(revision.left(10)));
|
||||
}
|
||||
|
||||
// Add the compile date and time
|
||||
versionLabel->setToolTip(tr("Compiled on %0 %1").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(),
|
||||
QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate),
|
||||
QLocale(QLocale::C).toTime(QString(__TIME__).simplified(),
|
||||
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
|
||||
// Add the compile date and time
|
||||
versionLabel->setToolTip(tr("Compiled on %0 %1").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(),
|
||||
QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate),
|
||||
QLocale(QLocale::C).toTime(QString(__TIME__).simplified(),
|
||||
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
|
||||
}
|
||||
|
||||
createIcons();
|
||||
}
|
||||
|
@ -64,8 +64,12 @@ opencs_units (view/world
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
scenewidget
|
||||
)
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
navigation navigation1st navigationfree navigationorbit
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
|
@ -9,15 +9,22 @@
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
#include "model/doc/document.hpp"
|
||||
#include "model/world/data.hpp"
|
||||
|
||||
CS::Editor::Editor()
|
||||
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager)
|
||||
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
||||
mIpcServerName ("org.openmw.OpenCS")
|
||||
{
|
||||
mIpcServerName = "org.openmw.OpenCS";
|
||||
Files::PathContainer dataDirs = readConfig();
|
||||
|
||||
setupDataFiles();
|
||||
setupDataFiles (dataDirs);
|
||||
|
||||
CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg");
|
||||
|
||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||
|
||||
mNewGame.setLocalData (mLocal);
|
||||
mFileDialog.setLocalData (mLocal);
|
||||
@ -42,7 +49,16 @@ CS::Editor::Editor()
|
||||
this, SLOT (createNewGame (const boost::filesystem::path&)));
|
||||
}
|
||||
|
||||
void CS::Editor::setupDataFiles()
|
||||
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||
{
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
{
|
||||
QString path = QString::fromStdString(iter->string());
|
||||
mFileDialog.addFiles(path);
|
||||
}
|
||||
}
|
||||
|
||||
Files::PathContainer CS::Editor::readConfig()
|
||||
{
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
||||
@ -58,6 +74,8 @@ void CS::Editor::setupDataFiles()
|
||||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
mDocumentManager.setResourceDir (variables["resources"].as<std::string>());
|
||||
|
||||
Files::PathContainer dataDirs, dataLocal;
|
||||
if (!variables["data"].empty()) {
|
||||
dataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
@ -83,23 +101,11 @@ void CS::Editor::setupDataFiles()
|
||||
messageBox.exec();
|
||||
|
||||
QApplication::exit (1);
|
||||
return;
|
||||
}
|
||||
|
||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||
|
||||
mDocumentManager.setResourceDir (variables["resources"].as<std::string>());
|
||||
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
{
|
||||
|
||||
QString path = QString::fromStdString(iter->string());
|
||||
mFileDialog.addFiles(path);
|
||||
}
|
||||
|
||||
//load the settings into the userSettings instance.
|
||||
const QString settingFileName = "opencs.cfg";
|
||||
CSMSettings::UserSettings::instance().loadSettings(settingFileName);
|
||||
return dataDirs;
|
||||
}
|
||||
|
||||
void CS::Editor::createGame()
|
||||
@ -210,8 +216,6 @@ int CS::Editor::run()
|
||||
if (mLocal.empty())
|
||||
return 1;
|
||||
|
||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
||||
#if 0
|
||||
// TODO: setting
|
||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
|
||||
|
||||
@ -228,7 +232,6 @@ int CS::Editor::run()
|
||||
#endif
|
||||
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
||||
hiddenWindow->setActive(false);
|
||||
#endif
|
||||
|
||||
mStartup.show();
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
#include <components/files/multidircollection.hpp>
|
||||
|
||||
#include "model/settings/usersettings.hpp"
|
||||
#include "model/doc/documentmanager.hpp"
|
||||
|
||||
@ -20,6 +22,11 @@
|
||||
|
||||
#include "view/settings/usersettingsdialog.hpp"
|
||||
|
||||
namespace OgreInit
|
||||
{
|
||||
class OgreInit;
|
||||
}
|
||||
|
||||
namespace CS
|
||||
{
|
||||
class Editor : public QObject
|
||||
@ -37,7 +44,10 @@ namespace CS
|
||||
|
||||
boost::filesystem::path mLocal;
|
||||
|
||||
void setupDataFiles();
|
||||
void setupDataFiles (const Files::PathContainer& dataDirs);
|
||||
|
||||
Files::PathContainer readConfig();
|
||||
///< \return data paths
|
||||
|
||||
// not implemented
|
||||
Editor (const Editor&);
|
||||
@ -45,7 +55,7 @@ namespace CS
|
||||
|
||||
public:
|
||||
|
||||
Editor();
|
||||
Editor (OgreInit::OgreInit& ogreInit);
|
||||
|
||||
bool makeIPCServer();
|
||||
void connectToIPCServer();
|
||||
|
@ -40,15 +40,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Q_INIT_RESOURCE (resources);
|
||||
|
||||
// TODO: Ogre startup shouldn't be here, but it currently has to:
|
||||
// SceneWidget destructor will delete the created render window, which would be called _after_ Root has shut down :(
|
||||
|
||||
Application mApplication (argc, argv);
|
||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
||||
#if 0
|
||||
OgreInit::OgreInit ogreInit;
|
||||
ogreInit.init("./opencsOgre.log"); // TODO log path?
|
||||
#endif
|
||||
|
||||
Application application (argc, argv);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QDir dir(QCoreApplication::applicationDirPath());
|
||||
@ -66,12 +60,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
QStringList libraryPaths;
|
||||
libraryPaths << pluginsPath.path() << QCoreApplication::applicationDirPath();
|
||||
mApplication.setLibraryPaths(libraryPaths);
|
||||
application.setLibraryPaths(libraryPaths);
|
||||
#endif
|
||||
|
||||
mApplication.setWindowIcon (QIcon (":./opencs.png"));
|
||||
application.setWindowIcon (QIcon (":./opencs.png"));
|
||||
|
||||
CS::Editor editor;
|
||||
CS::Editor editor (ogreInit);
|
||||
|
||||
if(!editor.makeIPCServer())
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ namespace CSMWorld
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
virtual void cloneRecord(const std::string& origin,
|
||||
virtual void cloneRecord(const std::string& origin,
|
||||
const std::string& destination,
|
||||
const UniversalId::Type type);
|
||||
|
||||
@ -198,7 +198,7 @@ namespace CSMWorld
|
||||
}
|
||||
|
||||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void Collection<ESXRecordT, IdAccessorT>::cloneRecord(const std::string& origin,
|
||||
void Collection<ESXRecordT, IdAccessorT>::cloneRecord(const std::string& origin,
|
||||
const std::string& destination,
|
||||
const UniversalId::Type type)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ namespace CSMWorld
|
||||
UniversalId::Type type = UniversalId::Type_None) = 0;
|
||||
///< If the record type does not match, an exception is thrown.
|
||||
|
||||
virtual void cloneRecord(const std::string& origin,
|
||||
virtual void cloneRecord(const std::string& origin,
|
||||
const std::string& destination,
|
||||
const UniversalId::Type type) = 0;
|
||||
|
||||
|
@ -247,12 +247,12 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
||||
addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell);
|
||||
addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic);
|
||||
addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal);
|
||||
addModel (new IdTable (&mTopicInfos), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
||||
addModel (new IdTable (&mJournalInfos), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
||||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
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), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,9 @@
|
||||
#include "collectionbase.hpp"
|
||||
#include "columnbase.hpp"
|
||||
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering)
|
||||
: mIdCollection (idCollection), mReordering (reordering)
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
||||
Viewing viewing)
|
||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing)
|
||||
{}
|
||||
|
||||
CSMWorld::IdTable::~IdTable()
|
||||
@ -188,4 +189,45 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
|
||||
CSMWorld::IdTable::Reordering CSMWorld::IdTable::getReordering() const
|
||||
{
|
||||
return mReordering;
|
||||
}
|
||||
|
||||
CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
||||
{
|
||||
return mViewing;
|
||||
}
|
||||
|
||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||
{
|
||||
std::string id;
|
||||
std::string hint;
|
||||
|
||||
if (mViewing==Viewing_Cell)
|
||||
{
|
||||
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
|
||||
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (cellColumn!=-1 && idColumn!=-1)
|
||||
{
|
||||
id = mIdCollection->getData (row, cellColumn).toString().toUtf8().constData();
|
||||
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
else if (mViewing==Viewing_Id)
|
||||
{
|
||||
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
|
||||
|
||||
if (column!=-1)
|
||||
{
|
||||
id = mIdCollection->getData (row, column).toString().toUtf8().constData();
|
||||
hint = "c:" + id;
|
||||
}
|
||||
}
|
||||
|
||||
if (id.empty())
|
||||
return std::make_pair (UniversalId::Type_None, "");
|
||||
|
||||
if (id[0]=='#')
|
||||
id = "sys::default";
|
||||
|
||||
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
||||
}
|
@ -25,10 +25,20 @@ namespace CSMWorld
|
||||
Reordering_WithinTopic
|
||||
};
|
||||
|
||||
enum Viewing
|
||||
{
|
||||
Viewing_None,
|
||||
Viewing_Id, // use ID column to generate view request (ID is transformed into
|
||||
// worldspace and original ID is passed as hint with c: prefix)
|
||||
Viewing_Cell // use cell column to generate view request (cell ID is transformed
|
||||
// into worldspace and record ID is passed as hint with r: prefix)
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CollectionBase *mIdCollection;
|
||||
Reordering mReordering;
|
||||
Viewing mViewing;
|
||||
|
||||
// not implemented
|
||||
IdTable (const IdTable&);
|
||||
@ -36,7 +46,8 @@ namespace CSMWorld
|
||||
|
||||
public:
|
||||
|
||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_WithinTopic);
|
||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
||||
Viewing viewing = Viewing_None);
|
||||
///< The ownership of \a idCollection is not transferred.
|
||||
|
||||
virtual ~IdTable();
|
||||
@ -63,8 +74,8 @@ namespace CSMWorld
|
||||
void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None);
|
||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||
|
||||
void cloneRecord(const std::string& origin,
|
||||
const std::string& destination,
|
||||
void cloneRecord(const std::string& origin,
|
||||
const std::string& destination,
|
||||
UniversalId::Type type = UniversalId::Type_None);
|
||||
|
||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
@ -86,6 +97,12 @@ namespace CSMWorld
|
||||
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
|
||||
|
||||
Reordering getReordering() const;
|
||||
|
||||
Viewing getViewing() const;
|
||||
|
||||
std::pair<UniversalId, std::string> 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, "").
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -90,14 +90,14 @@ namespace
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
||||
static const TypeData sIndexArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
}
|
||||
|
@ -16,4 +16,6 @@ void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QSt
|
||||
{
|
||||
}
|
||||
|
||||
void CSVDoc::SubView::setStatusBar (bool show) {}
|
||||
void CSVDoc::SubView::setStatusBar (bool show) {}
|
||||
|
||||
void CSVDoc::SubView::useHint (const std::string& hint) {}
|
@ -40,9 +40,12 @@ namespace CSVDoc
|
||||
virtual void setStatusBar (bool show);
|
||||
///< Default implementation: ignored
|
||||
|
||||
virtual void useHint (const std::string& hint);
|
||||
///< Default implementation: ignored
|
||||
|
||||
signals:
|
||||
|
||||
void focusId (const CSMWorld::UniversalId& universalId);
|
||||
void focusId (const CSMWorld::UniversalId& universalId, const std::string& hint);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -115,10 +115,6 @@ void CSVDoc::View::setupWorldMenu()
|
||||
|
||||
world->addSeparator(); // items that don't represent single record lists follow here
|
||||
|
||||
QAction *scene = new QAction (tr ("Scene"), this);
|
||||
connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView()));
|
||||
world->addAction (scene);
|
||||
|
||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||
world->addAction (regionMap);
|
||||
@ -310,7 +306,7 @@ void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
|
||||
mOperations->setProgress (current, max, type, threads);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
||||
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint)
|
||||
{
|
||||
/// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
|
||||
/// number is exceeded
|
||||
@ -322,12 +318,15 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
||||
|
||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||
|
||||
if (!hint.empty())
|
||||
view->useHint (hint);
|
||||
|
||||
view->setStatusBar (mShowStatusBar->isChecked());
|
||||
|
||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||
|
||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
||||
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
|
||||
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
|
||||
|
||||
CSMSettings::UserSettings::instance().updateSettings("Display Format");
|
||||
|
||||
@ -429,11 +428,6 @@ void CSVDoc::View::addFiltersSubView()
|
||||
addSubView (CSMWorld::UniversalId::Type_Filters);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSceneSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Scene);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addTopicsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Topics);
|
||||
|
@ -120,7 +120,9 @@ namespace CSVDoc
|
||||
|
||||
public slots:
|
||||
|
||||
void addSubView (const CSMWorld::UniversalId& id);
|
||||
void addSubView (const CSMWorld::UniversalId& id, const std::string& hint = "");
|
||||
///< \param hint Suggested view point (e.g. coordinates in a 3D scene or a line number
|
||||
/// in a script).
|
||||
|
||||
void abortOperation (int type);
|
||||
|
||||
@ -166,8 +168,6 @@ namespace CSVDoc
|
||||
|
||||
void addFiltersSubView();
|
||||
|
||||
void addSceneSubView();
|
||||
|
||||
void addTopicsSubView();
|
||||
|
||||
void addJournalsSubView();
|
||||
|
19
apps/opencs/view/render/navigation.cpp
Normal file
19
apps/opencs/view/render/navigation.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
float CSVRender::Navigation::getFactor (bool mouse) const
|
||||
{
|
||||
float factor = mFastModeFactor;
|
||||
|
||||
if (mouse)
|
||||
factor /= 2; /// \todo make this configurable
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
CSVRender::Navigation::~Navigation() {}
|
||||
|
||||
void CSVRender::Navigation::setFastModeFactor (float factor)
|
||||
{
|
||||
mFastModeFactor = factor;
|
||||
}
|
46
apps/opencs/view/render/navigation.hpp
Normal file
46
apps/opencs/view/render/navigation.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATION_H
|
||||
#define OPENCS_VIEW_NAVIGATION_H
|
||||
|
||||
class QPoint;
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Camera;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Navigation
|
||||
{
|
||||
float mFastModeFactor;
|
||||
|
||||
protected:
|
||||
|
||||
float getFactor (bool mouse) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Navigation();
|
||||
|
||||
void setFastModeFactor (float factor);
|
||||
///< Set currently applying fast mode factor.
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode) = 0;
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta) = 0;
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
85
apps/opencs/view/render/navigation1st.cpp
Normal file
85
apps/opencs/view/render/navigation1st.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
#include "navigation1st.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
CSVRender::Navigation1st::Navigation1st() : mCamera (0) {}
|
||||
|
||||
bool CSVRender::Navigation1st::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (true);
|
||||
|
||||
Ogre::Radian pitch = mCamera->getOrientation().getPitch();
|
||||
|
||||
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||
|
||||
if (pitch>limit)
|
||||
mCamera->pitch (-(pitch-limit));
|
||||
else if (pitch<-limit)
|
||||
mCamera->pitch (pitch-limit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::wheelMoved (int delta)
|
||||
{
|
||||
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
if (mode==0)
|
||||
{
|
||||
// turn camera
|
||||
if (delta.x())
|
||||
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||
|
||||
if (delta.y())
|
||||
{
|
||||
Ogre::Radian oldPitch = mCamera->getOrientation().getPitch();
|
||||
float deltaPitch = getFactor (true) * delta.y();
|
||||
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
||||
|
||||
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||
|
||||
if ((deltaPitch>0 && newPitch<limit) || (deltaPitch<0 && newPitch>-limit))
|
||||
mCamera->pitch (Ogre::Degree (deltaPitch));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
// pan camera
|
||||
if (delta.x())
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||
|
||||
if (delta.y())
|
||||
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
if (vertical)
|
||||
mCamera->move (getFactor (false) * mCamera->getDirection() * vertical);
|
||||
|
||||
if (horizontal)
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::handleRollKeys (int delta)
|
||||
{
|
||||
// we don't roll this way in 1st person mode
|
||||
return false;
|
||||
}
|
35
apps/opencs/view/render/navigation1st.hpp
Normal file
35
apps/opencs/view/render/navigation1st.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATION1ST_H
|
||||
#define OPENCS_VIEW_NAVIGATION1ST_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief First person-like camera controls
|
||||
class Navigation1st : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
|
||||
public:
|
||||
|
||||
Navigation1st();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
66
apps/opencs/view/render/navigationfree.cpp
Normal file
66
apps/opencs/view/render/navigationfree.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
#include "navigationfree.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
CSVRender::NavigationFree::NavigationFree() : mCamera (0) {}
|
||||
|
||||
bool CSVRender::NavigationFree::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::wheelMoved (int delta)
|
||||
{
|
||||
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
if (mode==0)
|
||||
{
|
||||
// turn camera
|
||||
if (delta.x())
|
||||
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||
|
||||
if (delta.y())
|
||||
mCamera->pitch (Ogre::Degree (getFactor (true) * delta.y()));
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
// pan camera
|
||||
if (delta.x())
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||
|
||||
if (delta.y())
|
||||
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
if (vertical)
|
||||
mCamera->move (getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||
|
||||
if (horizontal)
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::handleRollKeys (int delta)
|
||||
{
|
||||
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||
return true;
|
||||
}
|
35
apps/opencs/view/render/navigationfree.hpp
Normal file
35
apps/opencs/view/render/navigationfree.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATIONFREE_H
|
||||
#define OPENCS_VIEW_NAVIGATIONFREE_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief Free camera controls
|
||||
class NavigationFree : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
|
||||
public:
|
||||
|
||||
NavigationFree();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
100
apps/opencs/view/render/navigationorbit.cpp
Normal file
100
apps/opencs/view/render/navigationorbit.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
#include "navigationorbit.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
void CSVRender::NavigationOrbit::rotateCamera (const Ogre::Vector3& diff)
|
||||
{
|
||||
Ogre::Vector3 pos = mCamera->getPosition();
|
||||
|
||||
float distance = (pos-mCentre).length();
|
||||
|
||||
Ogre::Vector3 direction = (pos+diff)-mCentre;
|
||||
direction.normalise();
|
||||
|
||||
mCamera->setPosition (mCentre + direction*distance);
|
||||
mCamera->lookAt (mCentre);
|
||||
}
|
||||
|
||||
CSVRender::NavigationOrbit::NavigationOrbit() : mCamera (0), mCentre (0, 0, 0), mDistance (100)
|
||||
{}
|
||||
|
||||
bool CSVRender::NavigationOrbit::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (false);
|
||||
|
||||
if ((mCamera->getPosition()-mCentre).length()<mDistance)
|
||||
{
|
||||
// move camera out of the centre area
|
||||
Ogre::Vector3 direction = mCentre-mCamera->getPosition();
|
||||
direction.normalise();
|
||||
|
||||
if (direction.length()==0)
|
||||
direction = Ogre::Vector3 (1, 0, 0);
|
||||
|
||||
mCamera->setPosition (mCentre - direction * mDistance);
|
||||
}
|
||||
|
||||
mCamera->lookAt (mCentre);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::wheelMoved (int delta)
|
||||
{
|
||||
Ogre::Vector3 diff = getFactor (true) * mCamera->getDirection() * delta;
|
||||
|
||||
Ogre::Vector3 pos = mCamera->getPosition();
|
||||
|
||||
if (delta>0 && diff.length()>=(pos-mCentre).length()-mDistance)
|
||||
{
|
||||
pos = mCentre-(mCamera->getDirection() * mDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += diff;
|
||||
}
|
||||
|
||||
mCamera->setPosition (pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
Ogre::Vector3 diff =
|
||||
getFactor (true) * -mCamera->getDerivedRight() * delta.x()
|
||||
+ getFactor (true) * mCamera->getDerivedUp() * delta.y();
|
||||
|
||||
if (mode==0)
|
||||
{
|
||||
rotateCamera (diff);
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
mCamera->move (diff);
|
||||
mCentre += diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
rotateCamera (
|
||||
- getFactor (false) * -mCamera->getDerivedRight() * horizontal
|
||||
+ getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::handleRollKeys (int delta)
|
||||
{
|
||||
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||
return true;
|
||||
}
|
42
apps/opencs/view/render/navigationorbit.hpp
Normal file
42
apps/opencs/view/render/navigationorbit.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||
#define OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief Orbiting camera controls
|
||||
class NavigationOrbit : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::Vector3 mCentre;
|
||||
int mDistance;
|
||||
|
||||
void rotateCamera (const Ogre::Vector3& diff);
|
||||
///< Rotate camera around centre.
|
||||
|
||||
public:
|
||||
|
||||
NavigationOrbit();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
6
apps/opencs/view/render/pagedworldspacewidget.cpp
Normal file
6
apps/opencs/view/render/pagedworldspacewidget.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
#include "pagedworldspacewidget.hpp"
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent)
|
||||
: WorldspaceWidget (parent)
|
||||
{}
|
18
apps/opencs/view/render/pagedworldspacewidget.hpp
Normal file
18
apps/opencs/view/render/pagedworldspacewidget.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class PagedWorldspaceWidget : public WorldspaceWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
PagedWorldspaceWidget (QWidget *parent);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -2,24 +2,34 @@
|
||||
|
||||
#include <QEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QTimer>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
SceneWidget::SceneWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mWindow(NULL)
|
||||
, mCamera(NULL)
|
||||
, mSceneMgr(NULL)
|
||||
, mSceneMgr(NULL), mNavigation (0), mUpdate (false)
|
||||
, mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false)
|
||||
, mKeyRollLeft (false), mKeyRollRight (false)
|
||||
, mFast (false), mDragging (false), mMod1 (false)
|
||||
, mFastFactor (4) /// \todo make this configurable
|
||||
{
|
||||
setAttribute(Qt::WA_PaintOnScreen);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
|
||||
setFocusPolicy (Qt::StrongFocus);
|
||||
|
||||
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
||||
|
||||
// Throw in a random color just to make sure multiple scenes work
|
||||
@ -44,6 +54,16 @@ namespace CSVRender
|
||||
mCamera->lookAt(0,0,0);
|
||||
mCamera->setNearClipDistance(0.1);
|
||||
mCamera->setFarClipDistance(3000);
|
||||
|
||||
QTimer *timer = new QTimer (this);
|
||||
|
||||
connect (timer, SIGNAL (timeout()), this, SLOT (update()));
|
||||
timer->start (20); /// \todo make this configurable
|
||||
}
|
||||
|
||||
void SceneWidget::setAmbient (const Ogre::ColourValue& colour)
|
||||
{
|
||||
mSceneMgr->setAmbientLight (colour);
|
||||
}
|
||||
|
||||
void SceneWidget::updateOgreWindow()
|
||||
@ -81,7 +101,21 @@ namespace CSVRender
|
||||
|
||||
SceneWidget::~SceneWidget()
|
||||
{
|
||||
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
|
||||
if (mWindow)
|
||||
Ogre::Root::getSingleton().destroyRenderTarget (mWindow);
|
||||
|
||||
if (mSceneMgr)
|
||||
Ogre::Root::getSingleton().destroySceneManager (mSceneMgr);
|
||||
}
|
||||
|
||||
void SceneWidget::setNavigation (Navigation *navigation)
|
||||
{
|
||||
if ((mNavigation = navigation))
|
||||
{
|
||||
mNavigation->setFastModeFactor (mFast ? mFastFactor : 1);
|
||||
if (mNavigation->activate (mCamera))
|
||||
mUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::paintEvent(QPaintEvent* e)
|
||||
@ -93,7 +127,6 @@ namespace CSVRender
|
||||
e->accept();
|
||||
}
|
||||
|
||||
|
||||
QPaintEngine* SceneWidget::paintEngine() const
|
||||
{
|
||||
// We don't want another paint engine to get in the way.
|
||||
@ -130,4 +163,151 @@ namespace CSVRender
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_W: mKeyForward = true; break;
|
||||
case Qt::Key_S: mKeyBackward = true; break;
|
||||
case Qt::Key_A: mKeyLeft = true; break;
|
||||
case Qt::Key_D: mKeyRight = true; break;
|
||||
case Qt::Key_Q: mKeyRollLeft = true; break;
|
||||
case Qt::Key_E: mKeyRollRight = true; break;
|
||||
case Qt::Key_Control: mMod1 = true; break;
|
||||
|
||||
case Qt::Key_Shift:
|
||||
|
||||
mFast = true;
|
||||
|
||||
if (mNavigation)
|
||||
mNavigation->setFastModeFactor (mFastFactor);
|
||||
|
||||
break;
|
||||
|
||||
default: QWidget::keyPressEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
||||
{
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_W: mKeyForward = false; break;
|
||||
case Qt::Key_S: mKeyBackward = false; break;
|
||||
case Qt::Key_A: mKeyLeft = false; break;
|
||||
case Qt::Key_D: mKeyRight = false; break;
|
||||
case Qt::Key_Q: mKeyRollLeft = false; break;
|
||||
case Qt::Key_E: mKeyRollRight = false; break;
|
||||
case Qt::Key_Control: mMod1 = false; break;
|
||||
|
||||
case Qt::Key_Shift:
|
||||
|
||||
mFast = false;
|
||||
|
||||
if (mNavigation)
|
||||
mNavigation->setFastModeFactor (1);
|
||||
|
||||
break;
|
||||
|
||||
default: QWidget::keyReleaseEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
if (mNavigation)
|
||||
if (event->delta())
|
||||
if (mNavigation->wheelMoved (event->delta()))
|
||||
mUpdate = true;
|
||||
}
|
||||
|
||||
void SceneWidget::leaveEvent (QEvent *event)
|
||||
{
|
||||
mDragging = false;
|
||||
}
|
||||
|
||||
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
if (mDragging)
|
||||
{
|
||||
QPoint diff = mOldPos-event->pos();
|
||||
mOldPos = event->pos();
|
||||
|
||||
if (mNavigation)
|
||||
if (mNavigation->mouseMoved (diff, mMod1 ? 1 : 0))
|
||||
mUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDragging = true;
|
||||
mOldPos = event->pos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
mDragging = false;
|
||||
}
|
||||
|
||||
void SceneWidget::focusOutEvent (QFocusEvent *event)
|
||||
{
|
||||
mKeyForward = false;
|
||||
mKeyBackward = false;
|
||||
mKeyLeft = false;
|
||||
mKeyRight = false;
|
||||
mFast = false;
|
||||
mMod1 = false;
|
||||
|
||||
QWidget::focusOutEvent (event);
|
||||
}
|
||||
|
||||
void SceneWidget::update()
|
||||
{
|
||||
if (mNavigation)
|
||||
{
|
||||
int horizontal = 0;
|
||||
int vertical = 0;
|
||||
|
||||
if (mKeyForward && !mKeyBackward)
|
||||
vertical = 1;
|
||||
else if (!mKeyForward && mKeyBackward)
|
||||
vertical = -1;
|
||||
|
||||
if (mKeyLeft && !mKeyRight)
|
||||
horizontal = -1;
|
||||
else if (!mKeyLeft && mKeyRight)
|
||||
horizontal = 1;
|
||||
|
||||
if (horizontal || vertical)
|
||||
if (mNavigation->handleMovementKeys (vertical, horizontal))
|
||||
mUpdate = true;
|
||||
|
||||
int roll = 0;
|
||||
|
||||
if (mKeyRollLeft && !mKeyRollRight)
|
||||
roll = 1;
|
||||
else if (!mKeyRollLeft && mKeyRollRight)
|
||||
roll = -1;
|
||||
|
||||
if (roll)
|
||||
if (mNavigation->handleRollKeys (roll))
|
||||
mUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
if (mUpdate)
|
||||
{
|
||||
mUpdate = false;
|
||||
mWindow->update();
|
||||
}
|
||||
}
|
||||
|
||||
int SceneWidget::getFastFactor() const
|
||||
{
|
||||
return mFast ? mFastFactor : 1;
|
||||
}
|
||||
}
|
||||
|
@ -8,33 +8,77 @@ namespace Ogre
|
||||
class Camera;
|
||||
class SceneManager;
|
||||
class RenderWindow;
|
||||
class ColourValue;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Navigation;
|
||||
|
||||
class SceneWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SceneWidget(QWidget *parent);
|
||||
virtual ~SceneWidget(void);
|
||||
public:
|
||||
|
||||
QPaintEngine* paintEngine() const;
|
||||
SceneWidget(QWidget *parent);
|
||||
virtual ~SceneWidget();
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* e);
|
||||
void resizeEvent(QResizeEvent* e);
|
||||
bool event(QEvent* e);
|
||||
QPaintEngine* paintEngine() const;
|
||||
|
||||
void updateOgreWindow();
|
||||
void setAmbient (const Ogre::ColourValue& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
|
||||
Ogre::Camera* mCamera;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::RenderWindow* mWindow;
|
||||
protected:
|
||||
|
||||
void setNavigation (Navigation *navigation);
|
||||
///< \attention The ownership of \a navigation is not transferred to *this.
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* e);
|
||||
void resizeEvent(QResizeEvent* e);
|
||||
bool event(QEvent* e);
|
||||
|
||||
void keyPressEvent (QKeyEvent *event);
|
||||
|
||||
void keyReleaseEvent (QKeyEvent *event);
|
||||
|
||||
void focusOutEvent (QFocusEvent *event);
|
||||
|
||||
void wheelEvent (QWheelEvent *event);
|
||||
|
||||
void leaveEvent (QEvent *event);
|
||||
|
||||
void mouseMoveEvent (QMouseEvent *event);
|
||||
|
||||
void mouseReleaseEvent (QMouseEvent *event);
|
||||
|
||||
void updateOgreWindow();
|
||||
|
||||
int getFastFactor() const;
|
||||
|
||||
Ogre::Camera* mCamera;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::RenderWindow* mWindow;
|
||||
|
||||
Navigation *mNavigation;
|
||||
bool mUpdate;
|
||||
bool mKeyForward;
|
||||
bool mKeyBackward;
|
||||
bool mKeyLeft;
|
||||
bool mKeyRight;
|
||||
bool mKeyRollLeft;
|
||||
bool mKeyRollRight;
|
||||
bool mFast;
|
||||
bool mDragging;
|
||||
bool mMod1;
|
||||
QPoint mOldPos;
|
||||
int mFastFactor;
|
||||
|
||||
private slots:
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
66
apps/opencs/view/render/unpagedworldspacewidget.cpp
Normal file
66
apps/opencs/view/render/unpagedworldspacewidget.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
#include "unpagedworldspacewidget.hpp"
|
||||
|
||||
#include <OgreColourValue.h>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::update()
|
||||
{
|
||||
const CSMWorld::Record<CSMWorld::Cell>& record =
|
||||
dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&> (mCellsModel->getRecord (mCellId));
|
||||
|
||||
Ogre::ColourValue colour;
|
||||
colour.setAsABGR (record.get().mAmbi.mAmbient);
|
||||
setAmbient (colour);
|
||||
|
||||
/// \todo deal with mSunlight and mFog/mForDensity
|
||||
}
|
||||
|
||||
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId,
|
||||
CSMDoc::Document& document, QWidget *parent)
|
||||
: WorldspaceWidget (parent), mCellId (cellId)
|
||||
{
|
||||
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||
|
||||
connect (mCellsModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
int index = mCellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, index);
|
||||
|
||||
if (cellIndex.row()>=topLeft.row() && cellIndex.row()<=bottomRight.row())
|
||||
{
|
||||
if (mCellsModel->data (cellIndex).toInt()==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
emit closeRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
/// \todo possible optimisation: check columns and update only if relevant columns have
|
||||
/// changed
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelIndex& parent,
|
||||
int start, int end)
|
||||
{
|
||||
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, 0);
|
||||
|
||||
if (cellIndex.row()>=start && cellIndex.row()<=end)
|
||||
emit closeRequest();
|
||||
}
|
44
apps/opencs/view/render/unpagedworldspacewidget.hpp
Normal file
44
apps/opencs/view/render/unpagedworldspacewidget.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||
#define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class UnpagedWorldspaceWidget : public WorldspaceWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
std::string mCellId;
|
||||
CSMWorld::IdTable *mCellsModel;
|
||||
|
||||
void update();
|
||||
|
||||
public:
|
||||
|
||||
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
|
||||
QWidget *parent);
|
||||
|
||||
private slots:
|
||||
|
||||
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
38
apps/opencs/view/render/worldspacewidget.cpp
Normal file
38
apps/opencs/view/render/worldspacewidget.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
#include "../world/scenetoolmode.hpp"
|
||||
|
||||
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
||||
: SceneWidget (parent)
|
||||
{}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="1st")
|
||||
setNavigation (&m1st);
|
||||
else if (mode=="free")
|
||||
setNavigation (&mFree);
|
||||
else if (mode=="orbit")
|
||||
setNavigation (&mOrbit);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||
{
|
||||
setNavigation (&m1st);
|
||||
}
|
||||
|
||||
CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||
CSVWorld::SceneToolbar *parent)
|
||||
{
|
||||
CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent);
|
||||
|
||||
tool->addButton (":door.png", "1st"); /// \todo replace icons
|
||||
tool->addButton (":GMST.png", "free");
|
||||
tool->addButton (":Info.png", "orbit");
|
||||
|
||||
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (selectNavigationMode (const std::string&)));
|
||||
|
||||
return tool;
|
||||
}
|
46
apps/opencs/view/render/worldspacewidget.hpp
Normal file
46
apps/opencs/view/render/worldspacewidget.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
|
||||
#include "navigation1st.hpp"
|
||||
#include "navigationfree.hpp"
|
||||
#include "navigationorbit.hpp"
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolMode;
|
||||
class SceneToolbar;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget : public SceneWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSVRender::Navigation1st m1st;
|
||||
CSVRender::NavigationFree mFree;
|
||||
CSVRender::NavigationOrbit mOrbit;
|
||||
|
||||
public:
|
||||
|
||||
WorldspaceWidget (QWidget *parent = 0);
|
||||
|
||||
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
||||
///< \important The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
|
||||
void selectDefaultNavigationMode();
|
||||
|
||||
private slots:
|
||||
|
||||
void selectNavigationMode (const std::string& mode);
|
||||
|
||||
signals:
|
||||
|
||||
void closeRequest();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -40,5 +40,5 @@ void CSVTools::ReportSubView::updateEditorSetting (const QString& key, const QSt
|
||||
|
||||
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
||||
{
|
||||
focusId (mModel->getUniversalId (index.row()));
|
||||
focusId (mModel->getUniversalId (index.row()), "");
|
||||
}
|
@ -9,7 +9,8 @@
|
||||
|
||||
#include "../filter/filterbox.hpp"
|
||||
|
||||
#include "../render/scenewidget.hpp"
|
||||
#include "../render/pagedworldspacewidget.hpp"
|
||||
#include "../render/unpagedworldspacewidget.hpp"
|
||||
|
||||
#include "tablebottombox.hpp"
|
||||
#include "creator.hpp"
|
||||
@ -32,37 +33,20 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
// test
|
||||
SceneToolMode *tool = new SceneToolMode (toolbar);
|
||||
tool->addButton (":door.png", "a");
|
||||
tool->addButton (":GMST.png", "b");
|
||||
tool->addButton (":Info.png", "c");
|
||||
toolbar->addTool (tool);
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
toolbar->addTool (new SceneToolMode (toolbar));
|
||||
|
||||
if (id.getId()[0]=='#')
|
||||
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
||||
else
|
||||
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
||||
|
||||
SceneToolMode *tool = mScene->makeNavigationSelector (toolbar);
|
||||
toolbar->addTool (tool);
|
||||
|
||||
layout2->addWidget (toolbar, 0);
|
||||
|
||||
// temporarily disable OGRE-integration (need to fix path problem first)
|
||||
#if 0
|
||||
CSVRender::SceneWidget* sceneWidget = new CSVRender::SceneWidget(this);
|
||||
|
||||
layout2->addWidget (sceneWidget, 1);
|
||||
layout2->addWidget (mScene, 1);
|
||||
|
||||
layout->insertLayout (0, layout2, 1);
|
||||
#endif
|
||||
/// \todo replace with rendering widget
|
||||
QPalette palette2 (palette());
|
||||
palette2.setColor (QPalette::Background, Qt::white);
|
||||
QLabel *placeholder = new QLabel ("Here goes the 3D scene", this);
|
||||
placeholder->setAutoFillBackground (true);
|
||||
placeholder->setPalette (palette2);
|
||||
placeholder->setAlignment (Qt::AlignHCenter);
|
||||
|
||||
layout2->addWidget (placeholder, 1);
|
||||
|
||||
layout->insertLayout (0, layout2, 1);
|
||||
|
||||
|
||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||
|
||||
@ -73,6 +57,10 @@ toolbar->addTool (new SceneToolMode (toolbar));
|
||||
widget->setLayout (layout);
|
||||
|
||||
setWidget (widget);
|
||||
|
||||
mScene->selectDefaultNavigationMode();
|
||||
|
||||
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::setEditLock (bool locked)
|
||||
@ -91,3 +79,8 @@ void CSVWorld::SceneSubView::setStatusBar (bool show)
|
||||
{
|
||||
mBottom->setStatusBar (show);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::closeRequest()
|
||||
{
|
||||
deleteLater();
|
||||
}
|
@ -10,6 +10,11 @@ namespace CSMDoc
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class Table;
|
||||
@ -21,6 +26,7 @@ namespace CSVWorld
|
||||
Q_OBJECT
|
||||
|
||||
TableBottomBox *mBottom;
|
||||
CSVRender::WorldspaceWidget *mScene;
|
||||
|
||||
public:
|
||||
|
||||
@ -31,6 +37,10 @@ namespace CSVWorld
|
||||
virtual void updateEditorSetting (const QString& key, const QString& value);
|
||||
|
||||
virtual void setStatusBar (bool show);
|
||||
|
||||
private slots:
|
||||
|
||||
void closeRequest();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "table.hpp"
|
||||
|
||||
#include <QHeaderView>
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
@ -10,6 +9,8 @@
|
||||
#include <QString>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtableproxymodel.hpp"
|
||||
@ -35,8 +36,21 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
||||
if (selectedRows.size()==1)
|
||||
{
|
||||
menu.addAction (mEditAction);
|
||||
|
||||
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)
|
||||
@ -162,11 +176,12 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
||||
return deletableIds;
|
||||
}
|
||||
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
bool createAndDelete, bool sorting, const CSMDoc::Document& document)
|
||||
: mUndoStack (undoStack), mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), mDocument(document)
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||
bool createAndDelete, bool sorting, CSMDoc::Document& document)
|
||||
: mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0),
|
||||
mDocument (document)
|
||||
{
|
||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
|
||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id));
|
||||
|
||||
mProxyModel = new CSMWorld::IdTableProxyModel (this);
|
||||
mProxyModel->setSourceModel (mModel);
|
||||
@ -190,7 +205,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||
mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display,
|
||||
undoStack, this);
|
||||
mDocument.getUndoStack(), this);
|
||||
|
||||
mDelegates.push_back (delegate);
|
||||
setItemDelegateForColumn (i, delegate);
|
||||
@ -230,6 +245,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, Q
|
||||
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
||||
addAction (mMoveDownAction);
|
||||
|
||||
mViewAction = new QAction (tr ("View"), this);
|
||||
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||
addAction (mViewAction);
|
||||
|
||||
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (tableSizeUpdate()));
|
||||
|
||||
@ -268,13 +287,13 @@ void CSVWorld::Table::revertRecord()
|
||||
if (revertableIds.size()>0)
|
||||
{
|
||||
if (revertableIds.size()>1)
|
||||
mUndoStack.beginMacro (tr ("Revert multiple records"));
|
||||
mDocument.getUndoStack().beginMacro (tr ("Revert multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
|
||||
mUndoStack.push (new CSMWorld::RevertCommand (*mModel, *iter));
|
||||
mDocument.getUndoStack().push (new CSMWorld::RevertCommand (*mModel, *iter));
|
||||
|
||||
if (revertableIds.size()>1)
|
||||
mUndoStack.endMacro();
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,13 +307,13 @@ void CSVWorld::Table::deleteRecord()
|
||||
if (deletableIds.size()>0)
|
||||
{
|
||||
if (deletableIds.size()>1)
|
||||
mUndoStack.beginMacro (tr ("Delete multiple records"));
|
||||
mDocument.getUndoStack().beginMacro (tr ("Delete multiple records"));
|
||||
|
||||
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
|
||||
mUndoStack.push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
||||
mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (*mModel, *iter));
|
||||
|
||||
if (deletableIds.size()>1)
|
||||
mUndoStack.endMacro();
|
||||
mDocument.getUndoStack().endMacro();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,7 +325,7 @@ void CSVWorld::Table::editRecord()
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
if (selectedRows.size()==1)
|
||||
emit editRequest (selectedRows.begin()->row());
|
||||
emit editRequest (getUniversalId (selectedRows.begin()->row()), "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,7 +366,7 @@ void CSVWorld::Table::moveUpRecord()
|
||||
for (int i=1; i<row2-row; ++i)
|
||||
newOrder[i] = i;
|
||||
|
||||
mUndoStack.push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,11 +395,28 @@ void CSVWorld::Table::moveDownRecord()
|
||||
for (int i=1; i<row2-row; ++i)
|
||||
newOrder[i] = i;
|
||||
|
||||
mUndoStack.push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::viewRecord()
|
||||
{
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
if (selectedRows.size()==1)
|
||||
{
|
||||
int row =selectedRows.begin()->row();
|
||||
|
||||
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||
|
||||
std::pair<CSMWorld::UniversalId, std::string> params = mModel->view (row);
|
||||
|
||||
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||
emit editRequest (params.first, params.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
int columns = mModel->columnCount();
|
||||
@ -517,7 +553,7 @@ void CSVWorld::Table::dropEvent(QDropEvent *event)
|
||||
std::auto_ptr<CSMWorld::ModifyCommand> command (new CSMWorld::ModifyCommand
|
||||
(*mProxyModel, index, QVariant (QString::fromUtf8 (record.getId().c_str()))));
|
||||
|
||||
mUndoStack.push (command.release());
|
||||
mDocument.getUndoStack().push (command.release());
|
||||
}
|
||||
} //TODO handle drops from different document
|
||||
}
|
||||
|
@ -10,13 +10,14 @@
|
||||
#include "../../model/filter/node.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
|
||||
namespace CSMDoc {
|
||||
class Document;
|
||||
}
|
||||
|
||||
class QUndoStack;
|
||||
class QAction;
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
@ -35,7 +36,6 @@ namespace CSVWorld
|
||||
Q_OBJECT
|
||||
|
||||
std::vector<CommandDelegate *> mDelegates;
|
||||
QUndoStack& mUndoStack;
|
||||
QAction *mEditAction;
|
||||
QAction *mCreateAction;
|
||||
QAction *mCloneAction;
|
||||
@ -43,14 +43,12 @@ namespace CSVWorld
|
||||
QAction *mDeleteAction;
|
||||
QAction *mMoveUpAction;
|
||||
QAction *mMoveDownAction;
|
||||
QAction *mViewAction;
|
||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||
CSMWorld::IdTable *mModel;
|
||||
bool mEditLock;
|
||||
int mRecordStatusDisplay;
|
||||
|
||||
/// \brief This variable is used exclusivly for checking if dropEvents came from the same document. Most likely you
|
||||
/// should NOT use it for anything else.
|
||||
const CSMDoc::Document& mDocument;
|
||||
CSMDoc::Document& mDocument;
|
||||
|
||||
private:
|
||||
|
||||
@ -70,9 +68,8 @@ namespace CSVWorld
|
||||
|
||||
public:
|
||||
|
||||
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete,
|
||||
bool sorting, const CSMDoc::Document& document);
|
||||
|
||||
Table (const CSMWorld::UniversalId& id, bool createAndDelete,
|
||||
bool sorting, CSMDoc::Document& document);
|
||||
///< \param createAndDelete Allow creation and deletion of records.
|
||||
/// \param sorting Allow changing order of rows in the view via column headers.
|
||||
|
||||
@ -86,7 +83,7 @@ namespace CSVWorld
|
||||
|
||||
signals:
|
||||
|
||||
void editRequest (int row);
|
||||
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||
|
||||
void selectionSizeChanged (int size);
|
||||
|
||||
@ -112,6 +109,8 @@ namespace CSVWorld
|
||||
|
||||
void moveDownRecord();
|
||||
|
||||
void viewRecord();
|
||||
|
||||
public slots:
|
||||
|
||||
void tableSizeUpdate();
|
||||
|
@ -24,7 +24,7 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this), 0);
|
||||
|
||||
layout->insertWidget (0, mTable =
|
||||
new Table (id, document.getData(), document.getUndoStack(), mBottom->canCreateAndDelete(), sorting, document), 2);
|
||||
new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2);
|
||||
|
||||
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
|
||||
|
||||
@ -36,7 +36,8 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
||||
|
||||
setWidget (widget);
|
||||
|
||||
connect (mTable, SIGNAL (editRequest (int)), this, SLOT (editRequest (int)));
|
||||
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||
this, SLOT (editRequest (const CSMWorld::UniversalId&, const std::string&)));
|
||||
|
||||
connect (mTable, SIGNAL (selectionSizeChanged (int)),
|
||||
mBottom, SLOT (selectionSizeChanged (int)));
|
||||
@ -81,9 +82,9 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||
mBottom->setEditLock (locked);
|
||||
}
|
||||
|
||||
void CSVWorld::TableSubView::editRequest (int row)
|
||||
void CSVWorld::TableSubView::editRequest (const CSMWorld::UniversalId& id, const std::string& hint)
|
||||
{
|
||||
focusId (mTable->getUniversalId (row));
|
||||
focusId (id, hint);
|
||||
}
|
||||
|
||||
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||
|
@ -53,7 +53,7 @@ namespace CSVWorld
|
||||
|
||||
private slots:
|
||||
|
||||
void editRequest (int row);
|
||||
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||
void cloneRequest (const CSMWorld::UniversalId& toClone);
|
||||
void createFilterRequest(std::vector< CSMWorld::UniversalId >& types,
|
||||
Qt::DropAction action);
|
||||
|
@ -159,3 +159,10 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(openmw gcov)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# Debug version needs increased number of sections beyond 2^16
|
||||
if (CMAKE_CL_64)
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
|
||||
endif (CMAKE_CL_64)
|
||||
endif (MSVC)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "engine.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
@ -456,7 +457,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
else
|
||||
{
|
||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
||||
pos.rot[0] = pos.rot[1] = pos.pos[2] = 0;
|
||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||
world->changeToExteriorCell (pos);
|
||||
}
|
||||
|
||||
@ -621,4 +622,4 @@ void OMW::Engine::setActivationDistanceOverride (int distance)
|
||||
void OMW::Engine::setWarningsMode (int mode)
|
||||
{
|
||||
mWarningsMode = mode;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../mwdialogue/journalentry.hpp"
|
||||
#include "../mwdialogue/topic.hpp"
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "MyGUI_TextureUtility.h"
|
||||
#include "MyGUI_FactoryManager.h"
|
||||
|
||||
#include <platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "MyGUI_Widget.h"
|
||||
|
||||
#include <functional>
|
||||
#include <platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "enchantingdialog.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -206,9 +206,9 @@ struct JournalViewModelImpl : JournalViewModel
|
||||
|
||||
const MWDialogue::Quest& quest = i->second;
|
||||
// Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal.
|
||||
if (quest.getName().empty())
|
||||
visitor (reinterpret_cast <QuestId> (&i->second), toUtf8Span (i->first));
|
||||
else
|
||||
// Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not supposed
|
||||
// to appear in the quest book.
|
||||
if (!quest.getName().empty())
|
||||
visitor (reinterpret_cast <QuestId> (&i->second), toUtf8Span (quest.getName()));
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
#include "loadingscreen.hpp"
|
||||
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreTechnique.h>
|
||||
#include <OgreRectangle2D.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
|
||||
#include <openengine/ogre/fader.hpp>
|
||||
|
||||
@ -66,6 +73,10 @@ namespace MWGui
|
||||
|
||||
void LoadingScreen::loadingOn()
|
||||
{
|
||||
// Early-out if already on
|
||||
if (mRectangle->getVisible())
|
||||
return;
|
||||
|
||||
// Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync.
|
||||
// Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it.
|
||||
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
|
||||
@ -74,16 +85,36 @@ namespace MWGui
|
||||
mWindow->setVSyncEnabled(false);
|
||||
#endif
|
||||
|
||||
if (!mFirstLoad)
|
||||
{
|
||||
mBackgroundImage->setImageTexture("");
|
||||
int width = mWindow->getWidth();
|
||||
int height = mWindow->getHeight();
|
||||
const std::string textureName = "@loading_background";
|
||||
Ogre::TexturePtr texture;
|
||||
texture = Ogre::TextureManager::getSingleton().getByName(textureName);
|
||||
if (texture.isNull())
|
||||
{
|
||||
texture = Ogre::TextureManager::getSingleton().createManual(textureName,
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D,
|
||||
width, height, 0, mWindow->suggestPixelFormat(), Ogre::TU_DYNAMIC_WRITE_ONLY);
|
||||
}
|
||||
texture->unload();
|
||||
texture->setWidth(width);
|
||||
texture->setHeight(height);
|
||||
texture->createInternalResources();
|
||||
mWindow->copyContentsToMemory(texture->getBuffer()->lock(Ogre::Image::Box(0,0,width,height), Ogre::HardwareBuffer::HBL_DISCARD));
|
||||
texture->getBuffer()->unlock();
|
||||
mBackgroundImage->setImageTexture(texture->getName());
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
|
||||
if (mFirstLoad)
|
||||
{
|
||||
changeWallpaper();
|
||||
}
|
||||
else
|
||||
{
|
||||
mBackgroundImage->setImageTexture("");
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(mFirstLoad ? GM_LoadingWallpaper : GM_Loading);
|
||||
}
|
||||
@ -197,8 +228,6 @@ namespace MWGui
|
||||
|
||||
MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
|
||||
mWindow->getViewport(0)->setClearEveryFrame(false);
|
||||
|
||||
// First, swap buffers from last draw, then, queue an update of the
|
||||
// window contents, but don't swap buffers (which would have
|
||||
// caused a sync / flush and would be expensive).
|
||||
@ -208,9 +237,6 @@ namespace MWGui
|
||||
|
||||
mWindow->update(false);
|
||||
|
||||
mWindow->getViewport(0)->setClearEveryFrame(true);
|
||||
|
||||
|
||||
mRectangle->setVisible(false);
|
||||
|
||||
// resume 3d rendering
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define MWGUI_LOADINGSCREEN_H
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreTimer.h>
|
||||
|
||||
#include "windowbase.hpp"
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreVector2.h>
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef MWGUI_MAPWINDOW_H
|
||||
#define MWGUI_MAPWINDOW_H
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "windowpinnablebase.hpp"
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "repair.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "tooltips.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
|
||||
#include <OgreTextureManager.h>
|
||||
|
||||
#include "MyGUI_UString.h"
|
||||
#include "MyGUI_IPointer.h"
|
||||
#include "MyGUI_ResourceImageSetPointer.h"
|
||||
|
@ -455,7 +455,7 @@ namespace MWInput
|
||||
mInputBinder->adjustMouseRegion(width, height);
|
||||
}
|
||||
|
||||
bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
|
||||
void InputManager::keyPressed( const SDL_KeyboardEvent &arg )
|
||||
{
|
||||
// Cut, copy & paste
|
||||
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||
@ -501,7 +501,6 @@ namespace MWInput
|
||||
|
||||
if (kc != OIS::KC_UNASSIGNED)
|
||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
||||
@ -512,23 +511,21 @@ namespace MWInput
|
||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
|
||||
}
|
||||
|
||||
bool InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
||||
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
||||
{
|
||||
mInputBinder->keyReleased (arg);
|
||||
|
||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||
|
||||
MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||
void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||
{
|
||||
mInputBinder->mousePressed (arg, id);
|
||||
|
||||
if (id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT)
|
||||
return true; // MyGUI has no use for these events
|
||||
return; // MyGUI has no use for these events
|
||||
|
||||
MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id));
|
||||
if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0)
|
||||
@ -539,20 +536,16 @@ namespace MWInput
|
||||
MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||
void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
|
||||
{
|
||||
mInputBinder->mouseReleased (arg, id);
|
||||
|
||||
MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
|
||||
void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
|
||||
{
|
||||
mInputBinder->mouseMoved (arg);
|
||||
|
||||
@ -600,8 +593,6 @@ namespace MWInput
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputManager::windowFocusChange(bool have_focus)
|
||||
|
@ -86,13 +86,13 @@ namespace MWInput
|
||||
virtual void resetToDefaultBindings();
|
||||
|
||||
public:
|
||||
virtual bool keyPressed(const SDL_KeyboardEvent &arg );
|
||||
virtual bool keyReleased( const SDL_KeyboardEvent &arg );
|
||||
virtual void keyPressed(const SDL_KeyboardEvent &arg );
|
||||
virtual void keyReleased( const SDL_KeyboardEvent &arg );
|
||||
virtual void textInput (const SDL_TextInputEvent &arg);
|
||||
|
||||
virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual bool mouseMoved( const SFO::MouseMotionEvent &arg );
|
||||
virtual void mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual void mouseMoved( const SFO::MouseMotionEvent &arg );
|
||||
|
||||
virtual void windowVisibilityChange( bool visible );
|
||||
virtual void windowFocusChange( bool have_focus );
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
|
||||
|
||||
#include "npcstats.hpp"
|
||||
#include "creaturestats.hpp"
|
||||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
#include "character.hpp" // fixme: for getActiveWeapon
|
||||
@ -140,11 +140,12 @@ namespace MWMechanics
|
||||
{
|
||||
MWMechanics::DrawState_ state = actor.getClass().getCreatureStats(actor).getDrawState();
|
||||
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
|
||||
actor.getClass().getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon);
|
||||
actor.getClass().getCreatureStats(actor).setDrawState(MWMechanics::DrawState_Weapon);
|
||||
|
||||
//Get weapon speed and range
|
||||
MWWorld::ContainerStoreIterator weaponSlot =
|
||||
MWMechanics::getActiveWeapon(cls.getNpcStats(actor), cls.getInventoryStore(actor), &weaptype);
|
||||
MWMechanics::getActiveWeapon(cls.getCreatureStats(actor), cls.getInventoryStore(actor), &weaptype);
|
||||
|
||||
if (weaptype == WeapType_HandToHand)
|
||||
{
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||
@ -242,17 +243,21 @@ namespace MWMechanics
|
||||
//target is at far distance: build path to target OR follow target (if previously actor had reached it once)
|
||||
mFollowTarget = false;
|
||||
|
||||
buildNewPath(actor);
|
||||
buildNewPath(actor); //may fail to build a path, check before use
|
||||
|
||||
//delete visited path node
|
||||
mPathFinder.checkPathCompleted(pos.pos[0],pos.pos[1],pos.pos[2]);
|
||||
|
||||
//try shortcut
|
||||
if(vDir.length() < mPathFinder.getDistToNext(pos.pos[0],pos.pos[1],pos.pos[2]) && MWBase::Environment::get().getWorld()->getLOS(actor, mTarget))
|
||||
mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / vDir.length()) * sgn(Ogre::Math::ASin(vDir.x / vDir.length())) ).valueDegrees();
|
||||
else
|
||||
mTargetAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
|
||||
mRotate = true;
|
||||
//if no new path leave mTargetAngle unchanged
|
||||
if(!mPathFinder.getPath().empty())
|
||||
{
|
||||
//try shortcut
|
||||
if(vDir.length() < mPathFinder.getDistToNext(pos.pos[0],pos.pos[1],pos.pos[2]) && MWBase::Environment::get().getWorld()->getLOS(actor, mTarget))
|
||||
mTargetAngle = Ogre::Radian( Ogre::Math::ACos(vDir.y / vDir.length()) * sgn(Ogre::Math::ASin(vDir.x / vDir.length())) ).valueDegrees();
|
||||
else
|
||||
mTargetAngle = mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1]);
|
||||
mRotate = true;
|
||||
}
|
||||
|
||||
mMovement.mPosition[1] = 1;
|
||||
mReadyToAttack = false;
|
||||
@ -302,9 +307,13 @@ namespace MWMechanics
|
||||
dest.mZ = mTarget.getRefData().getPosition().pos[2];
|
||||
Ogre::Vector3 newPathTarget = Ogre::Vector3(dest.mX, dest.mY, dest.mZ);
|
||||
|
||||
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
||||
Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ);
|
||||
float dist = Ogre::Math::Abs((newPathTarget - currPathTarget).length());
|
||||
float dist = -1; //hack to indicate first time, to construct a new path
|
||||
if(!mPathFinder.getPath().empty())
|
||||
{
|
||||
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
||||
Ogre::Vector3 currPathTarget(lastPt.mX, lastPt.mY, lastPt.mZ);
|
||||
dist = Ogre::Math::Abs((newPathTarget - currPathTarget).length());
|
||||
}
|
||||
|
||||
float targetPosThreshold;
|
||||
bool isOutside = actor.getCell()->getCell()->isExterior();
|
||||
@ -313,7 +322,7 @@ namespace MWMechanics
|
||||
else
|
||||
targetPosThreshold = 100;
|
||||
|
||||
if(dist > targetPosThreshold)
|
||||
if((dist < 0) || (dist > targetPosThreshold))
|
||||
{
|
||||
//construct new path only if target has moved away more than on <targetPosThreshold>
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
@ -334,8 +343,11 @@ namespace MWMechanics
|
||||
//maybe here is a mistake (?): PathFinder::getPathSize() returns number of grid points in the path,
|
||||
//not the actual path length. Here we should know if the new path is actually more effective.
|
||||
//if(pathFinder2.getPathSize() < mPathFinder.getPathSize())
|
||||
newPathFinder.syncStart(mPathFinder.getPath());
|
||||
mPathFinder = newPathFinder;
|
||||
if(!mPathFinder.getPath().empty())
|
||||
{
|
||||
newPathFinder.syncStart(mPathFinder.getPath());
|
||||
mPathFinder = newPathFinder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
@ -509,4 +511,4 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
|
||||
mTimeToStartDrowning = state.mTimeToStartDrowning;
|
||||
mLastDrowningHit = state.mLastDrowningHit;
|
||||
mLevelHealthBonus = state.mLevelHealthBonus;
|
||||
}
|
||||
}
|
||||
|
@ -393,6 +393,8 @@ namespace MWMechanics
|
||||
|
||||
void PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path)
|
||||
{
|
||||
if (mPath.size() < 2)
|
||||
return; //nothing to pop
|
||||
std::list<ESM::Pathgrid::Point>::const_iterator oldStart = path.begin();
|
||||
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreControllerManager.h>
|
||||
#include <OgreStaticGeometry.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include <components/esm/loadligh.hpp>
|
||||
#include <components/esm/loadweap.hpp>
|
||||
@ -293,6 +295,17 @@ void Animation::addAnimSource(const std::string &model)
|
||||
}
|
||||
}
|
||||
|
||||
if (grp == 0 && dstval->getNode()->getName() == "Bip01")
|
||||
{
|
||||
mNonAccumRoot = dstval->getNode();
|
||||
mAccumRoot = mNonAccumRoot->getParent();
|
||||
if(!mAccumRoot)
|
||||
{
|
||||
std::cerr<< "Non-Accum root for "<<mPtr.getCellRef().mRefID<<" is skeleton root??" <<std::endl;
|
||||
mNonAccumRoot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctrls[i].setSource(mAnimationTimePtr[grp]);
|
||||
grpctrls[grp].push_back(ctrls[i]);
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
#include "characterpreview.hpp"
|
||||
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
|
||||
#include <libs/openengine/ogre/selectionbuffer.hpp>
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <OgreRenderTarget.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreVector3.h>
|
||||
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <OgreMaterial.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreManualObject.h>
|
||||
#include <OgreTechnique.h>
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreParticleSystem.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "renderconst.hpp"
|
||||
|
@ -75,10 +75,9 @@ namespace MWRender
|
||||
|
||||
if (land)
|
||||
{
|
||||
if (!land->isDataLoaded(ESM::Land::DATA_VHGT))
|
||||
{
|
||||
land->loadData(ESM::Land::DATA_VHGT);
|
||||
}
|
||||
int mask = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX;
|
||||
if (!land->isDataLoaded(mask))
|
||||
land->loadData(mask);
|
||||
}
|
||||
|
||||
for (int cellY=0; cellY<cellSize; ++cellY)
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -4,6 +4,11 @@
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreParticleSystem.h>
|
||||
#include <OgreSubEntity.h>
|
||||
#include <OgreSkeleton.h>
|
||||
#include <OgreSkeletonInstance.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreBone.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
|
@ -109,6 +109,7 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh)
|
||||
{
|
||||
uniqueID = uniqueID+1;
|
||||
sg = mRenderer.getScene()->createStaticGeometry("sg" + Ogre::StringConverter::toString(uniqueID));
|
||||
sg->setOrigin(ptr.getRefData().getBaseNode()->getPosition());
|
||||
mStaticGeometrySmall[ptr.getCell()] = sg;
|
||||
|
||||
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
|
||||
@ -122,6 +123,7 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh)
|
||||
{
|
||||
uniqueID = uniqueID+1;
|
||||
sg = mRenderer.getScene()->createStaticGeometry("sg" + Ogre::StringConverter::toString(uniqueID));
|
||||
sg->setOrigin(ptr.getRefData().getBaseNode()->getPosition());
|
||||
mStaticGeometry[ptr.getCell()] = sg;
|
||||
}
|
||||
else
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <OgreMeshManager.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreMesh.h>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <OgreRenderTarget.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreControllerManager.h>
|
||||
#include <OgreMeshManager.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
|
||||
#include <SDL_video.h>
|
||||
|
||||
@ -649,6 +651,18 @@ void RenderingManager::setGlare(bool glare)
|
||||
mSkyManager->setGlare(glare);
|
||||
}
|
||||
|
||||
void RenderingManager::updateTerrain()
|
||||
{
|
||||
if (mTerrain)
|
||||
{
|
||||
// Avoid updating with dims.getCenter for each cell. Player position should be good enough
|
||||
mTerrain->update(mRendering.getCamera()->getRealPosition());
|
||||
mTerrain->syncLoad();
|
||||
// need to update again so the chunks that were just loaded can be made visible
|
||||
mTerrain->update(mRendering.getCamera()->getRealPosition());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingManager::requestMap(MWWorld::CellStore* cell)
|
||||
{
|
||||
if (cell->getCell()->isExterior())
|
||||
@ -659,9 +673,6 @@ void RenderingManager::requestMap(MWWorld::CellStore* cell)
|
||||
Ogre::Vector2 center (cell->getCell()->getGridX() + 0.5, cell->getCell()->getGridY() + 0.5);
|
||||
dims.merge(mTerrain->getWorldBoundingBox(center));
|
||||
|
||||
if (dims.isFinite())
|
||||
mTerrain->update(dims.getCenter());
|
||||
|
||||
mLocalMap->requestMap(cell, dims.getMinimum().z, dims.getMaximum().z);
|
||||
}
|
||||
else
|
||||
@ -981,13 +992,11 @@ void RenderingManager::screenshot(Image &image, int w, int h)
|
||||
|
||||
Ogre::PixelFormat pf = rt->suggestPixelFormat();
|
||||
|
||||
std::vector<Ogre::uchar> data;
|
||||
data.resize(w * h * Ogre::PixelUtil::getNumElemBytes(pf));
|
||||
|
||||
Ogre::PixelBox pb(w, h, 1, pf, &data[0]);
|
||||
rt->copyContentsToMemory(pb);
|
||||
|
||||
image.loadDynamicImage(&data[0], w, h, pf);
|
||||
image.loadDynamicImage(
|
||||
OGRE_ALLOC_T(Ogre::uchar, w * h * Ogre::PixelUtil::getNumElemBytes(pf), Ogre::MEMCATEGORY_GENERAL),
|
||||
w, h, 1, pf, true // autoDelete=true, frees memory we allocate
|
||||
);
|
||||
rt->copyContentsToMemory(image.getPixelBox()); // getPixelBox returns a box sharing the same memory as the image
|
||||
|
||||
Ogre::TextureManager::getSingleton().remove(tempName);
|
||||
mRendering.getCamera()->setAspectRatio(oldAspect);
|
||||
@ -1045,20 +1054,16 @@ void RenderingManager::enableTerrain(bool enable)
|
||||
{
|
||||
if (!mTerrain)
|
||||
{
|
||||
Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(listener);
|
||||
mTerrain = new Terrain::World(listener, mRendering.getScene(), new MWRender::TerrainStorage(), RV_Terrain,
|
||||
mTerrain = new Terrain::World(mRendering.getScene(), new MWRender::TerrainStorage(), RV_Terrain,
|
||||
Settings::Manager::getBool("distant land", "Terrain"),
|
||||
Settings::Manager::getBool("shader", "Terrain"));
|
||||
Settings::Manager::getBool("shader", "Terrain"), Terrain::Align_XY, 1, 64);
|
||||
mTerrain->applyMaterials(Settings::Manager::getBool("enabled", "Shadows"),
|
||||
Settings::Manager::getBool("split", "Shadows"));
|
||||
mTerrain->update(mRendering.getCamera()->getRealPosition());
|
||||
mTerrain->setLoadingListener(NULL);
|
||||
}
|
||||
mTerrain->setVisible(true);
|
||||
}
|
||||
else
|
||||
if (mTerrain)
|
||||
else if (mTerrain)
|
||||
mTerrain->setVisible(false);
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,10 @@ public:
|
||||
void removeWaterRippleEmitter (const MWWorld::Ptr& ptr);
|
||||
void updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
|
||||
|
||||
void updateTerrain ();
|
||||
///< update the terrain according to the player position. Usually done automatically, but should be done manually
|
||||
/// before calling requestMap
|
||||
|
||||
void requestMap (MWWorld::CellStore* cell);
|
||||
///< request the local map for a cell
|
||||
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include <OgreStringConverter.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRectangle2D.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <OgreShadowCameraSetupPSSM.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <OgreBillboardSet.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreSubEntity.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include <OgreMeshManager.h>
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <OgreStringConverter.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreResourceBackgroundQueue.h>
|
||||
#include <OgreRoot.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -13,12 +14,14 @@
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include <components/terrain/quadtreenode.hpp>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
Ogre::AxisAlignedBox TerrainStorage::getBounds()
|
||||
void TerrainStorage::getBounds(float& minX, float& maxX, float& minY, float& maxY)
|
||||
{
|
||||
int minX = 0, minY = 0, maxX = 0, maxY = 0;
|
||||
minX = 0, minY = 0, maxX = 0, maxY = 0;
|
||||
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
@ -39,8 +42,6 @@ namespace MWRender
|
||||
// since grid coords are at cell origin, we need to add 1 cell
|
||||
maxX += 1;
|
||||
maxY += 1;
|
||||
|
||||
return Ogre::AxisAlignedBox(minX, minY, 0, maxX, maxY, 0);
|
||||
}
|
||||
|
||||
ESM::Land* TerrainStorage::getLand(int cellX, int cellY)
|
||||
@ -48,10 +49,6 @@ namespace MWRender
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
ESM::Land* land = esmStore.get<ESM::Land>().search(cellX, cellY);
|
||||
// Load the data we are definitely going to need
|
||||
int mask = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX;
|
||||
if (land && !land->isDataLoaded(mask))
|
||||
land->loadData(mask);
|
||||
return land;
|
||||
}
|
||||
|
||||
@ -169,10 +166,10 @@ namespace MWRender
|
||||
|
||||
}
|
||||
|
||||
void TerrainStorage::fillVertexBuffers (int lodLevel, float size, const Ogre::Vector2& center,
|
||||
Ogre::HardwareVertexBufferSharedPtr vertexBuffer,
|
||||
Ogre::HardwareVertexBufferSharedPtr normalBuffer,
|
||||
Ogre::HardwareVertexBufferSharedPtr colourBuffer)
|
||||
void TerrainStorage::fillVertexBuffers (int lodLevel, float size, const Ogre::Vector2& center, Terrain::Alignment align,
|
||||
std::vector<float>& positions,
|
||||
std::vector<float>& normals,
|
||||
std::vector<Ogre::uint8>& colours)
|
||||
{
|
||||
// LOD level n means every 2^n-th vertex is kept
|
||||
size_t increment = 1 << lodLevel;
|
||||
@ -186,11 +183,8 @@ namespace MWRender
|
||||
|
||||
size_t numVerts = size*(ESM::Land::LAND_SIZE-1)/increment + 1;
|
||||
|
||||
std::vector<uint8_t> colors;
|
||||
colors.resize(numVerts*numVerts*4);
|
||||
std::vector<float> positions;
|
||||
colours.resize(numVerts*numVerts*4);
|
||||
positions.resize(numVerts*numVerts*3);
|
||||
std::vector<float> normals;
|
||||
normals.resize(numVerts*numVerts*3);
|
||||
|
||||
Ogre::Vector3 normal;
|
||||
@ -276,7 +270,7 @@ namespace MWRender
|
||||
color.a = 1;
|
||||
Ogre::uint32 rsColor;
|
||||
Ogre::Root::getSingleton().getRenderSystem()->convertColourValue(color, &rsColor);
|
||||
memcpy(&colors[vertX*numVerts*4 + vertY*4], &rsColor, sizeof(Ogre::uint32));
|
||||
memcpy(&colours[vertX*numVerts*4 + vertY*4], &rsColor, sizeof(Ogre::uint32));
|
||||
|
||||
++vertX;
|
||||
}
|
||||
@ -289,10 +283,6 @@ namespace MWRender
|
||||
assert(vertX_ == numVerts); // Ensure we covered whole area
|
||||
}
|
||||
assert(vertY_ == numVerts); // Ensure we covered whole area
|
||||
|
||||
vertexBuffer->writeData(0, vertexBuffer->getSizeInBytes(), &positions[0], true);
|
||||
normalBuffer->writeData(0, normalBuffer->getSizeInBytes(), &normals[0], true);
|
||||
colourBuffer->writeData(0, colourBuffer->getSizeInBytes(), &colors[0], true);
|
||||
}
|
||||
|
||||
TerrainStorage::UniqueTextureId TerrainStorage::getVtexIndexAt(int cellX, int cellY,
|
||||
@ -318,9 +308,6 @@ namespace MWRender
|
||||
ESM::Land* land = getLand(cellX, cellY);
|
||||
if (land)
|
||||
{
|
||||
if (!land->isDataLoaded(ESM::Land::DATA_VTEX))
|
||||
land->loadData(ESM::Land::DATA_VTEX);
|
||||
|
||||
int tex = land->mLandData->mTextures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
|
||||
if (tex == 0)
|
||||
return std::make_pair(0,0); // vtex 0 is always the base texture, regardless of plugin
|
||||
@ -345,8 +332,24 @@ namespace MWRender
|
||||
return texture;
|
||||
}
|
||||
|
||||
void TerrainStorage::getBlendmaps (const std::vector<Terrain::QuadTreeNode*>& nodes, std::vector<Terrain::LayerCollection>& out, bool pack)
|
||||
{
|
||||
for (std::vector<Terrain::QuadTreeNode*>::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
|
||||
{
|
||||
out.push_back(Terrain::LayerCollection());
|
||||
out.back().mTarget = *it;
|
||||
getBlendmapsImpl((*it)->getSize(), (*it)->getCenter(), pack, out.back().mBlendmaps, out.back().mLayers);
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainStorage::getBlendmaps(float chunkSize, const Ogre::Vector2 &chunkCenter,
|
||||
bool pack, std::vector<Ogre::TexturePtr> &blendmaps, std::vector<Terrain::LayerInfo> &layerList)
|
||||
bool pack, std::vector<Ogre::PixelBox> &blendmaps, std::vector<Terrain::LayerInfo> &layerList)
|
||||
{
|
||||
getBlendmapsImpl(chunkSize, chunkCenter, pack, blendmaps, layerList);
|
||||
}
|
||||
|
||||
void TerrainStorage::getBlendmapsImpl(float chunkSize, const Ogre::Vector2 &chunkCenter,
|
||||
bool pack, std::vector<Ogre::PixelBox> &blendmaps, std::vector<Terrain::LayerInfo> &layerList)
|
||||
{
|
||||
// TODO - blending isn't completely right yet; the blending radius appears to be
|
||||
// different at a cell transition (2 vertices, not 4), so we may need to create a larger blendmap
|
||||
@ -391,16 +394,14 @@ namespace MWRender
|
||||
|
||||
// Second iteration - create and fill in the blend maps
|
||||
const int blendmapSize = ESM::Land::LAND_TEXTURE_SIZE+1;
|
||||
std::vector<Ogre::uchar> data;
|
||||
data.resize(blendmapSize * blendmapSize * channels, 0);
|
||||
|
||||
for (int i=0; i<numBlendmaps; ++i)
|
||||
{
|
||||
Ogre::PixelFormat format = pack ? Ogre::PF_A8B8G8R8 : Ogre::PF_A8;
|
||||
static int count=0;
|
||||
Ogre::TexturePtr map = Ogre::TextureManager::getSingleton().createManual("terrain/blend/"
|
||||
+ Ogre::StringConverter::toString(count++), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D, blendmapSize, blendmapSize, 0, format);
|
||||
|
||||
Ogre::uchar* pData =
|
||||
OGRE_ALLOC_T(Ogre::uchar, blendmapSize*blendmapSize*channels, Ogre::MEMCATEGORY_GENERAL);
|
||||
memset(pData, 0, blendmapSize*blendmapSize*channels);
|
||||
|
||||
for (int y=0; y<blendmapSize; ++y)
|
||||
{
|
||||
@ -412,16 +413,12 @@ namespace MWRender
|
||||
int channel = pack ? std::max(0, (layerIndex-1) % 4) : 0;
|
||||
|
||||
if (blendIndex == i)
|
||||
data[y*blendmapSize*channels + x*channels + channel] = 255;
|
||||
pData[y*blendmapSize*channels + x*channels + channel] = 255;
|
||||
else
|
||||
data[y*blendmapSize*channels + x*channels + channel] = 0;
|
||||
pData[y*blendmapSize*channels + x*channels + channel] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// All done, upload to GPU
|
||||
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&data[0], data.size()));
|
||||
map->loadRawData(stream, blendmapSize, blendmapSize, format);
|
||||
blendmaps.push_back(map);
|
||||
blendmaps.push_back(Ogre::PixelBox(blendmapSize, blendmapSize, 1, format, pData));
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,6 +540,12 @@ namespace MWRender
|
||||
info.mSpecular = true;
|
||||
}
|
||||
|
||||
// This wasn't cached, so the textures are probably not loaded either.
|
||||
// Background load them so they are hopefully already loaded once we need them!
|
||||
Ogre::ResourceBackgroundQueue::getSingleton().load("Texture", info.mDiffuseMap, "General");
|
||||
if (!info.mNormalMap.empty())
|
||||
Ogre::ResourceBackgroundQueue::getSingleton().load("Texture", info.mNormalMap, "General");
|
||||
|
||||
mLayerInfoMap[texture] = info;
|
||||
|
||||
return info;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef MWRENDER_TERRAINSTORAGE_H
|
||||
#define MWRENDER_TERRAINSTORAGE_H
|
||||
|
||||
#include <components/esm/loadland.hpp>
|
||||
#include <components/esm/loadltex.hpp>
|
||||
|
||||
#include <components/terrain/storage.hpp>
|
||||
|
||||
namespace MWRender
|
||||
@ -14,10 +17,10 @@ namespace MWRender
|
||||
public:
|
||||
|
||||
/// Get bounds of the whole terrain in cell units
|
||||
virtual Ogre::AxisAlignedBox getBounds();
|
||||
virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY);
|
||||
|
||||
/// Get the minimum and maximum heights of a terrain chunk.
|
||||
/// @note Should only be called for chunks <= 1 cell, i.e. leafs of the quad tree.
|
||||
/// Get the minimum and maximum heights of a terrain region.
|
||||
/// @note Will only be called for chunks with size = minBatchSize, i.e. leafs of the quad tree.
|
||||
/// Larger chunks can simply merge AABB of children.
|
||||
/// @param size size of the chunk in cell units
|
||||
/// @param center center of the chunk in cell units
|
||||
@ -27,20 +30,23 @@ namespace MWRender
|
||||
virtual bool getMinMaxHeights (float size, const Ogre::Vector2& center, float& min, float& max);
|
||||
|
||||
/// Fill vertex buffers for a terrain chunk.
|
||||
/// @note May be called from background threads. Make sure to only call thread-safe functions from here!
|
||||
/// @note returned colors need to be in render-system specific format! Use RenderSystem::convertColourValue.
|
||||
/// @param lodLevel LOD level, 0 = most detailed
|
||||
/// @param size size of the terrain chunk in cell units
|
||||
/// @param center center of the chunk in cell units
|
||||
/// @param vertexBuffer buffer to write vertices
|
||||
/// @param normalBuffer buffer to write vertex normals
|
||||
/// @param colourBuffer buffer to write vertex colours
|
||||
virtual void fillVertexBuffers (int lodLevel, float size, const Ogre::Vector2& center,
|
||||
Ogre::HardwareVertexBufferSharedPtr vertexBuffer,
|
||||
Ogre::HardwareVertexBufferSharedPtr normalBuffer,
|
||||
Ogre::HardwareVertexBufferSharedPtr colourBuffer);
|
||||
/// @param positions buffer to write vertices
|
||||
/// @param normals buffer to write vertex normals
|
||||
/// @param colours buffer to write vertex colours
|
||||
virtual void fillVertexBuffers (int lodLevel, float size, const Ogre::Vector2& center, Terrain::Alignment align,
|
||||
std::vector<float>& positions,
|
||||
std::vector<float>& normals,
|
||||
std::vector<Ogre::uint8>& colours);
|
||||
|
||||
/// Create textures holding layer blend values for a terrain chunk.
|
||||
/// @note The terrain chunk shouldn't be larger than one cell since otherwise we might
|
||||
/// have to do a ridiculous amount of different layers. For larger chunks, composite maps should be used.
|
||||
/// @note May be called from *one* background thread.
|
||||
/// @param chunkSize size of the terrain chunk in cell units
|
||||
/// @param chunkCenter center of the chunk in cell units
|
||||
/// @param pack Whether to pack blend values for up to 4 layers into one texture (one in each channel) -
|
||||
@ -49,9 +55,21 @@ namespace MWRender
|
||||
/// @param blendmaps created blendmaps will be written here
|
||||
/// @param layerList names of the layer textures used will be written here
|
||||
virtual void getBlendmaps (float chunkSize, const Ogre::Vector2& chunkCenter, bool pack,
|
||||
std::vector<Ogre::TexturePtr>& blendmaps,
|
||||
std::vector<Ogre::PixelBox>& blendmaps,
|
||||
std::vector<Terrain::LayerInfo>& layerList);
|
||||
|
||||
/// Retrieve pixel data for textures holding layer blend values for terrain chunks and layer texture information.
|
||||
/// This variant is provided to eliminate the overhead of virtual function calls when retrieving a large number of blendmaps at once.
|
||||
/// @note The terrain chunks shouldn't be larger than one cell since otherwise we might
|
||||
/// have to do a ridiculous amount of different layers. For larger chunks, composite maps should be used.
|
||||
/// @note May be called from *one* background thread.
|
||||
/// @param nodes A collection of nodes for which to retrieve the aforementioned data
|
||||
/// @param out Output vector
|
||||
/// @param pack Whether to pack blend values for up to 4 layers into one texture (one in each channel) -
|
||||
/// otherwise, each texture contains blend values for one layer only. Shader-based rendering
|
||||
/// can utilize packing, FFP can't.
|
||||
virtual void getBlendmaps (const std::vector<Terrain::QuadTreeNode*>& nodes, std::vector<Terrain::LayerCollection>& out, bool pack);
|
||||
|
||||
virtual float getHeightAt (const Ogre::Vector3& worldPos);
|
||||
|
||||
virtual Terrain::LayerInfo getDefaultLayer();
|
||||
@ -81,6 +99,11 @@ namespace MWRender
|
||||
std::map<std::string, Terrain::LayerInfo> mLayerInfoMap;
|
||||
|
||||
Terrain::LayerInfo getLayerInfo(const std::string& texture);
|
||||
|
||||
// Non-virtual
|
||||
void getBlendmapsImpl (float chunkSize, const Ogre::Vector2& chunkCenter, bool pack,
|
||||
std::vector<Ogre::PixelBox>& blendmaps,
|
||||
std::vector<Terrain::LayerInfo>& layerList);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreTechnique.h>
|
||||
#include <OgreRectangle2D.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
|
@ -1,11 +1,16 @@
|
||||
#include "water.hpp"
|
||||
|
||||
#include <OgreRenderTarget.h>
|
||||
#include <OgreRenderTexture.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreMeshManager.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include "sky.hpp"
|
||||
#include "renderingmanager.hpp"
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "locals.hpp"
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "openal_output.hpp"
|
||||
@ -172,6 +174,7 @@ class OpenAL_SoundStream : public Sound
|
||||
DecoderPtr mDecoder;
|
||||
|
||||
volatile bool mIsFinished;
|
||||
volatile bool mIsInitialBatchEnqueued;
|
||||
|
||||
void updateAll(bool local);
|
||||
|
||||
@ -264,7 +267,7 @@ private:
|
||||
|
||||
OpenAL_SoundStream::OpenAL_SoundStream(OpenAL_Output &output, ALuint src, DecoderPtr decoder, float basevol, float pitch, int flags)
|
||||
: Sound(Ogre::Vector3(0.0f), 1.0f, basevol, pitch, 1.0f, 1000.0f, flags)
|
||||
, mOutput(output), mSource(src), mSamplesQueued(0), mDecoder(decoder), mIsFinished(true)
|
||||
, mOutput(output), mSource(src), mSamplesQueued(0), mDecoder(decoder), mIsFinished(true), mIsInitialBatchEnqueued(false)
|
||||
{
|
||||
throwALerror();
|
||||
|
||||
@ -315,26 +318,8 @@ void OpenAL_SoundStream::play()
|
||||
alSourcei(mSource, AL_BUFFER, 0);
|
||||
throwALerror();
|
||||
mSamplesQueued = 0;
|
||||
|
||||
std::vector<char> data(mBufferSize);
|
||||
|
||||
bool finished = false;
|
||||
for(ALuint i = 0;i < sNumBuffers && !finished;i++)
|
||||
{
|
||||
size_t got = mDecoder->read(&data[0], data.size());
|
||||
finished = (got < data.size());
|
||||
if(got > 0)
|
||||
{
|
||||
ALuint bufid = mBuffers[i];
|
||||
alBufferData(bufid, mFormat, &data[0], got, mSampleRate);
|
||||
alSourceQueueBuffers(mSource, 1, &bufid);
|
||||
throwALerror();
|
||||
mSamplesQueued += getBufferSampleCount(bufid);
|
||||
}
|
||||
}
|
||||
|
||||
mIsFinished = finished;
|
||||
alSourcePlay(mSource);
|
||||
mIsFinished = false;
|
||||
mIsInitialBatchEnqueued = false;
|
||||
mOutput.mStreamThread->add(this);
|
||||
}
|
||||
|
||||
@ -342,6 +327,7 @@ void OpenAL_SoundStream::stop()
|
||||
{
|
||||
mOutput.mStreamThread->remove(this);
|
||||
mIsFinished = true;
|
||||
mIsInitialBatchEnqueued = false;
|
||||
|
||||
alSourceStop(mSource);
|
||||
alSourcei(mSource, AL_BUFFER, 0);
|
||||
@ -454,6 +440,24 @@ bool OpenAL_SoundStream::process()
|
||||
} while(processed > 0);
|
||||
throwALerror();
|
||||
}
|
||||
else if (!mIsInitialBatchEnqueued) { // nothing enqueued yet
|
||||
std::vector<char> data(mBufferSize);
|
||||
|
||||
for(ALuint i = 0;i < sNumBuffers && !finished;i++)
|
||||
{
|
||||
size_t got = mDecoder->read(&data[0], data.size());
|
||||
finished = (got < data.size());
|
||||
if(got > 0)
|
||||
{
|
||||
ALuint bufid = mBuffers[i];
|
||||
alBufferData(bufid, mFormat, &data[0], got, mSampleRate);
|
||||
alSourceQueueBuffers(mSource, 1, &bufid);
|
||||
throwALerror();
|
||||
mSamplesQueued += getBufferSampleCount(bufid);
|
||||
}
|
||||
}
|
||||
mIsInitialBatchEnqueued = true;
|
||||
}
|
||||
|
||||
if(state != AL_PLAYING && state != AL_PAUSED)
|
||||
{
|
||||
@ -471,6 +475,7 @@ bool OpenAL_SoundStream::process()
|
||||
std::cout<< "Error updating stream \""<<mDecoder->getName()<<"\"" <<std::endl;
|
||||
mSamplesQueued = 0;
|
||||
mIsFinished = true;
|
||||
mIsInitialBatchEnqueued = false;
|
||||
}
|
||||
return !mIsFinished;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||
else
|
||||
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile);
|
||||
|
||||
std::ofstream stream (slot->mPath.string().c_str());
|
||||
std::ofstream stream (slot->mPath.string().c_str(), std::ios::binary);
|
||||
|
||||
ESM::ESMWriter writer;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <components/interpreter/types.hpp>
|
||||
#include <components/esm/variant.hpp>
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <openengine/bullet/trace.h>
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
|
@ -43,7 +43,7 @@ namespace
|
||||
mPhysics (physics), mRendering (rendering)
|
||||
{}
|
||||
|
||||
bool InsertFunctor::InsertFunctor::operator() (const MWWorld::Ptr& ptr)
|
||||
bool InsertFunctor::operator() (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
if (mRescale)
|
||||
{
|
||||
@ -79,55 +79,6 @@ namespace
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void insertCellRefList(MWRender::RenderingManager& rendering,
|
||||
T& cellRefList, MWWorld::CellStore &cell, MWWorld::PhysicsSystem& physics, bool rescale, Loading::Listener* loadingListener)
|
||||
{
|
||||
if (!cellRefList.mList.empty())
|
||||
{
|
||||
const MWWorld::Class& class_ =
|
||||
MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell));
|
||||
for (typename T::List::iterator it = cellRefList.mList.begin();
|
||||
it != cellRefList.mList.end(); it++)
|
||||
{
|
||||
if (rescale)
|
||||
{
|
||||
if (it->mRef.mScale<0.5)
|
||||
it->mRef.mScale = 0.5;
|
||||
else if (it->mRef.mScale>2)
|
||||
it->mRef.mScale = 2;
|
||||
}
|
||||
|
||||
if (it->mData.getCount() && it->mData.isEnabled())
|
||||
{
|
||||
MWWorld::Ptr ptr (&*it, &cell);
|
||||
|
||||
try
|
||||
{
|
||||
rendering.addObject(ptr);
|
||||
class_.insertObject(ptr, physics);
|
||||
|
||||
float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees();
|
||||
float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees();
|
||||
float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees();
|
||||
MWBase::Environment::get().getWorld()->localRotateObject(ptr, ax, ay, az);
|
||||
|
||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().mScale);
|
||||
class_.adjustPosition(ptr);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::string error ("error during rendering: ");
|
||||
std::cerr << error + e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
loadingListener->increaseProgress(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -211,8 +162,6 @@ namespace MWWorld
|
||||
mRendering.cellAdded (cell);
|
||||
|
||||
mRendering.configureAmbient(*cell);
|
||||
mRendering.requestMap(cell);
|
||||
mRendering.configureAmbient(*cell);
|
||||
}
|
||||
|
||||
// register local scripts
|
||||
@ -246,6 +195,11 @@ namespace MWWorld
|
||||
mechMgr->updateCell(old, player);
|
||||
mechMgr->watchActor(player);
|
||||
|
||||
mRendering.updateTerrain();
|
||||
|
||||
for (CellStoreCollection::iterator active = mActiveCells.begin(); active!=mActiveCells.end(); ++active)
|
||||
mRendering.requestMap(*active);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||
}
|
||||
|
||||
@ -260,12 +214,13 @@ namespace MWWorld
|
||||
|
||||
void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
|
||||
{
|
||||
mRendering.enableTerrain(true);
|
||||
Nif::NIFFile::CacheLock cachelock;
|
||||
|
||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(loadingListener);
|
||||
|
||||
mRendering.enableTerrain(true);
|
||||
|
||||
std::string loadingExteriorText = "#{sLoadingMessage3}";
|
||||
loadingListener->setLabel(loadingExteriorText);
|
||||
|
||||
@ -410,11 +365,11 @@ namespace MWWorld
|
||||
Nif::NIFFile::CacheLock lock;
|
||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5);
|
||||
|
||||
mRendering.enableTerrain(false);
|
||||
|
||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(loadingListener);
|
||||
|
||||
mRendering.enableTerrain(false);
|
||||
|
||||
std::string loadingInteriorText = "#{sLoadingMessage2}";
|
||||
loadingListener->setLabel(loadingInteriorText);
|
||||
|
||||
|
@ -388,6 +388,8 @@ namespace MWWorld
|
||||
|
||||
typedef std::vector<ESM::LandTexture>::const_iterator iterator;
|
||||
|
||||
// Must be threadsafe! Called from terrain background loading threads.
|
||||
// Not a big deal here, since ESM::LandTexture can never be modified or inserted/erased
|
||||
const ESM::LandTexture *search(size_t index, size_t plugin) const {
|
||||
assert(plugin < mStatic.size());
|
||||
const LandTextureList <exl = mStatic[plugin];
|
||||
@ -487,6 +489,8 @@ namespace MWWorld
|
||||
return iterator(mStatic.end());
|
||||
}
|
||||
|
||||
// Must be threadsafe! Called from terrain background loading threads.
|
||||
// Not a big deal here, since ESM::Land can never be modified or inserted/erased
|
||||
ESM::Land *search(int x, int y) const {
|
||||
ESM::Land land;
|
||||
land.mX = x, land.mY = y;
|
||||
|
@ -1873,6 +1873,8 @@ namespace MWWorld
|
||||
|
||||
bool World::getLOS(const MWWorld::Ptr& npc,const MWWorld::Ptr& targetNpc)
|
||||
{
|
||||
if (!targetNpc.getRefData().isEnabled() || !npc.getRefData().isEnabled())
|
||||
return false; // cannot get LOS unless both NPC's are enabled
|
||||
Ogre::Vector3 halfExt1 = mPhysEngine->getCharacter(npc.getRefData().getHandle())->getHalfExtents();
|
||||
float* pos1 = npc.getRefData().getPosition().pos;
|
||||
Ogre::Vector3 halfExt2 = mPhysEngine->getCharacter(targetNpc.getRefData().getHandle())->getHalfExtents();
|
||||
|
@ -1,177 +0,0 @@
|
||||
# Locate SDL library
|
||||
# This module defines
|
||||
# SDL_LIBRARY, the name of the library to link against
|
||||
# SDL_FOUND, if false, do not try to link to SDL
|
||||
# SDL_INCLUDE_DIR, where to find SDL.h
|
||||
#
|
||||
# This module responds to the the flag:
|
||||
# SDL_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL_main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the the proper link flags
|
||||
# as part of the returned SDL_LIBRARY variable.
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDLmain which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL_LIBRARY_TEMP in your configuration
|
||||
# and no SDL_LIBRARY, it means CMake did not find your SDL library
|
||||
# (SDL.dll, libsdl.so, SDL.framework, etc).
|
||||
# Set SDL_LIBRARY_TEMP to point to your SDL library, and configure again.
|
||||
# Similarly, if you see an empty SDLMAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL_LIBRARY
|
||||
# variable, but when these values are unset, SDL_LIBRARY does not get created.
|
||||
#
|
||||
#
|
||||
# $SDLDIR is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDLDIR
|
||||
# used in building SDL.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL guidelines.
|
||||
# Added a search for SDLmain which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention
|
||||
# is #include "SDL.h", not <SDL/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL/ (see FreeBSD).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
FIND_PATH(SDL_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
$ENV{SDLDIR}
|
||||
PATH_SUFFIXES include/SDL include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include/SDL12
|
||||
/usr/local/include/SDL11 # FreeBSD ports
|
||||
/usr/include/SDL12
|
||||
/usr/include/SDL11
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
#MESSAGE("SDL_INCLUDE_DIR is ${SDL_INCLUDE_DIR}")
|
||||
|
||||
# SDL-1.1 is the name used by FreeBSD ports...
|
||||
# don't confuse it for the version number.
|
||||
FIND_LIBRARY(SDL_LIBRARY_TEMP
|
||||
NAMES SDL SDL-1.1
|
||||
HINTS
|
||||
$ENV{SDLDIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
#MESSAGE("SDL_LIBRARY_TEMP is ${SDL_LIBRARY_TEMP}")
|
||||
|
||||
IF(NOT SDL_BUILDING_LIBRARY)
|
||||
IF(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework")
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDLmain for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
FIND_LIBRARY(SDLMAIN_LIBRARY
|
||||
NAMES SDLmain SDLmain-1.1
|
||||
HINTS
|
||||
$ENV{SDLDIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
ENDIF(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework")
|
||||
ENDIF(NOT SDL_BUILDING_LIBRARY)
|
||||
|
||||
# SDL may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
IF(NOT APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -lmwindows
|
||||
# (Actually on second look, I think it only needs one of the m* libraries.)
|
||||
IF(MINGW)
|
||||
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
ENDIF(MINGW)
|
||||
|
||||
SET(SDL_FOUND "NO")
|
||||
IF(SDL_LIBRARY_TEMP)
|
||||
# For SDLmain
|
||||
IF(NOT SDL_BUILDING_LIBRARY)
|
||||
IF(SDLMAIN_LIBRARY)
|
||||
SET(SDL_LIBRARY_TEMP ${SDLMAIN_LIBRARY} ${SDL_LIBRARY_TEMP})
|
||||
ENDIF(SDLMAIN_LIBRARY)
|
||||
ENDIF(NOT SDL_BUILDING_LIBRARY)
|
||||
|
||||
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
IF(APPLE)
|
||||
SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} "-framework Cocoa")
|
||||
ENDIF(APPLE)
|
||||
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if I used the Threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
IF(NOT APPLE)
|
||||
SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# For MinGW library
|
||||
IF(MINGW)
|
||||
SET(SDL_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL_LIBRARY_TEMP})
|
||||
ENDIF(MINGW)
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL_LIBRARY ${SDL_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL_LIBRARY_TEMP "${SDL_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
|
||||
SET(SDL_FOUND "YES")
|
||||
ENDIF(SDL_LIBRARY_TEMP)
|
||||
|
||||
#MESSAGE("SDL_LIBRARY is ${SDL_LIBRARY}")
|
||||
|
@ -85,10 +85,6 @@ function(get_git_head_revision _refspecvar _hashvar)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
|
||||
#get_git_head_revision(refspec hash)
|
||||
|
||||
if(NOT GIT_FOUND)
|
||||
@ -133,7 +129,8 @@ endfunction()
|
||||
|
||||
function(get_git_tag_revision _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
|
@ -73,8 +73,9 @@ add_component_dir (translation
|
||||
translation
|
||||
)
|
||||
|
||||
add_definitions(-DTERRAIN_USE_SHADER=1)
|
||||
add_component_dir (terrain
|
||||
quadtreenode chunk world storage material
|
||||
quadtreenode chunk world storage material buffercache defs
|
||||
)
|
||||
|
||||
add_component_dir (loadinglistener
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <OgreArchive.h>
|
||||
#include <OgreArchiveFactory.h>
|
||||
#include <OgreArchiveManager.h>
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include "bsa_file.hpp"
|
||||
|
||||
#include "../files/constrainedfiledatastream.hpp"
|
||||
|
@ -24,7 +24,7 @@
|
||||
#ifndef BSA_BSA_FILE_H
|
||||
#define BSA_BSA_FILE_H
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <libs/platform/strings.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef OPENMW_ESM_DEFS_H
|
||||
#define OPENMW_ESM_DEFS_H
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <libs/platform/string.h>
|
||||
|
||||
namespace ESM
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef OPENMW_ESM_READER_H
|
||||
#define OPENMW_ESM_READER_H
|
||||
|
||||
#include <libs/platform/stdint.h>
|
||||
#include <stdint.h>
|
||||
#include <libs/platform/string.h>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
@ -80,8 +80,8 @@ namespace ESM
|
||||
rec.name = name;
|
||||
rec.position = mStream->tellp();
|
||||
rec.size = 0;
|
||||
writeT<int>(0); // Size goes here
|
||||
writeT<int>(0); // Unused header?
|
||||
writeT<uint32_t>(0); // Size goes here
|
||||
writeT<uint32_t>(0); // Unused header?
|
||||
writeT(flags);
|
||||
mRecords.push_back(rec);
|
||||
|
||||
@ -105,7 +105,7 @@ namespace ESM
|
||||
rec.name = name;
|
||||
rec.position = mStream->tellp();
|
||||
rec.size = 0;
|
||||
writeT<int>(0); // Size goes here
|
||||
writeT<uint32_t>(0); // Size goes here
|
||||
mRecords.push_back(rec);
|
||||
|
||||
assert(mRecords.back().size == 0);
|
||||
@ -120,7 +120,7 @@ namespace ESM
|
||||
mStream->seekp(rec.position);
|
||||
|
||||
mCounting = false;
|
||||
write (reinterpret_cast<const char*> (&rec.size), sizeof(int));
|
||||
write (reinterpret_cast<const char*> (&rec.size), sizeof(uint32_t));
|
||||
mCounting = true;
|
||||
|
||||
mStream->seekp(0, std::ios::end);
|
||||
|
@ -17,7 +17,7 @@ class ESMWriter
|
||||
{
|
||||
std::string name;
|
||||
std::streampos position;
|
||||
size_t size;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -249,7 +249,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
|
||||
|
||||
if (id.mPaged)
|
||||
{
|
||||
id.mWorldspace = "default";
|
||||
id.mWorldspace = "sys::default";
|
||||
id.mIndex.mX = mData.mX;
|
||||
id.mIndex.mY = mData.mY;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user