From 475f4f9311d1d13348174130711dee02978c5f14 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 17 Feb 2013 20:03:39 +0100 Subject: [PATCH 1/7] implicitly add Tribunal/Bloodmoon GMSTs to base, if present neither in base nor in modified --- apps/opencs/model/doc/document.cpp | 129 +++++++++++++++++++++++++++++ apps/opencs/model/doc/document.hpp | 9 ++ apps/opencs/model/world/data.cpp | 10 +++ apps/opencs/model/world/data.hpp | 4 + 4 files changed, 152 insertions(+) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 796135c3ff..e8d3a4eef3 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -18,6 +18,135 @@ void CSMDoc::Document::load (const std::vector::const_i if (lastAsModified) getData().loadFile (*end2, false); + + addOptionalGmsts(); +} + +void CSMDoc::Document::addOptionalGmsts() +{ + static const char *sFloats[] = + { + "fCombatDistanceWerewolfMod", + "fFleeDistance", + "fWereWolfAcrobatics", + "fWereWolfAgility", + "fWereWolfAlchemy", + "fWereWolfAlteration", + "fWereWolfArmorer", + "fWereWolfAthletics", + "fWereWolfAxe", + "fWereWolfBlock", + "fWereWolfBluntWeapon", + "fWereWolfConjuration", + "fWereWolfDestruction", + "fWereWolfEnchant", + "fWereWolfEndurance", + "fWereWolfFatigue", + "fWereWolfHandtoHand", + "fWereWolfHealth", + "fWereWolfHeavyArmor", + "fWereWolfIllusion", + "fWereWolfIntellegence", + "fWereWolfLightArmor", + "fWereWolfLongBlade", + "fWereWolfLuck", + "fWereWolfMagicka", + "fWereWolfMarksman", + "fWereWolfMediumArmor", + "fWereWolfMerchantile", + "fWereWolfMysticism", + "fWereWolfPersonality", + "fWereWolfRestoration", + "fWereWolfRunMult", + "fWereWolfSecurity", + "fWereWolfShortBlade", + "fWereWolfSilverWeaponDamageMult", + "fWereWolfSneak", + "fWereWolfSpear", + "fWereWolfSpeechcraft", + "fWereWolfSpeed", + "fWereWolfStrength", + "fWereWolfUnarmored", + "fWereWolfWillPower", + 0 + }; + + static const char *sIntegers[] = + { + "iWereWolfBounty", + "iWereWolfFightMod", + "iWereWolfFleeMod", + "iWereWolfLevelToAttack", + 0 + }; + + static const char *sStrings[] = + { + "sCompanionShare", + "sCompanionWarningButtonOne", + "sCompanionWarningButtonTwo", + "sCompanionWarningMessage", + "sDeleteNote", + "sEditNote", + "sEffectSummonCreature01", + "sEffectSummonCreature02", + "sEffectSummonCreature03", + "sEffectSummonCreature04", + "sEffectSummonCreature05", + "sEffectSummonFabricant", + "sLevitateDisabled", + "sMagicCreature01ID", + "sMagicCreature02ID", + "sMagicCreature03ID", + "sMagicCreature04ID", + "sMagicCreature05ID", + "sMagicFabricantID", + "sMaxSale", + "sProfitValue", + "sTeleportDisabled", + "sWerewolfAlarmMessage", + "sWerewolfPopup", + "sWerewolfRefusal", + "sWerewolfRestMessage", + 0 + }; + + for (int i=0; sFloats[i]; ++i) + { + ESM::GameSetting gmst; + gmst.mId = sFloats[i]; + gmst.mF = 0; + gmst.mType = ESM::VT_Float; + addOptionalGmst (gmst); + } + + for (int i=0; sIntegers[i]; ++i) + { + ESM::GameSetting gmst; + gmst.mId = sIntegers[i]; + gmst.mI = 0; + gmst.mType = ESM::VT_Long; + addOptionalGmst (gmst); + } + + for (int i=0; sStrings[i]; ++i) + { + ESM::GameSetting gmst; + gmst.mId = sStrings[i]; + gmst.mType = ESM::VT_String; + addOptionalGmst (gmst); + } +} + +void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst) +{ + if (getData().getGmsts().searchId (gmst.mId)==-1) + { + CSMWorld::Record record; + record.mBase = gmst; + record.mState = CSMWorld::RecordBase::State_BaseOnly; + getData().getGmsts().appendRecord (record); + } } void CSMDoc::Document::createBase() diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 0162681bcb..413e840d37 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -17,6 +17,11 @@ class QAbstractItemModel; +namespace ESM +{ + struct GameSetting; +} + namespace CSMDoc { class Document : public QObject @@ -46,6 +51,10 @@ namespace CSMDoc void createBase(); + void addOptionalGmsts(); + + void addOptionalGmst (const ESM::GameSetting& gmst); + public: Document (const std::vector& files, bool new_); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 92bd2bdb04..c59763f512 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -54,6 +54,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getGlobals() return mGlobals; } +const CSMWorld::IdCollection& CSMWorld::Data::getGmsts() const +{ + return mGmsts; +} + +CSMWorld::IdCollection& CSMWorld::Data::getGmsts() +{ + return mGmsts; +} + QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 519817a3b4..3745346511 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -40,6 +40,10 @@ namespace CSMWorld IdCollection& getGlobals(); + const IdCollection& getGmsts() const; + + IdCollection& getGmsts(); + QAbstractTableModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// From a50ff34774225cd12905a8c7e05740d07b2b5e16 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 18 Feb 2013 09:23:14 +0100 Subject: [PATCH 2/7] better default value for string GMSTs --- apps/opencs/model/doc/document.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index e8d3a4eef3..da29f6c687 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -133,6 +133,7 @@ void CSMDoc::Document::addOptionalGmsts() { ESM::GameSetting gmst; gmst.mId = sStrings[i]; + gmst.mStr = ""; gmst.mType = ESM::VT_String; addOptionalGmst (gmst); } From 43d63929217c43092a56f7a07d1c78c6f15728d2 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sat, 16 Feb 2013 20:56:17 +0100 Subject: [PATCH 3/7] Change the way pinnable window are made visible This ensure pinned window are not displayed in main menu, dialogue and container mode. --- apps/openmw/mwgui/window_pinnable_base.cpp | 10 ---------- apps/openmw/mwgui/window_pinnable_base.hpp | 1 - apps/openmw/mwgui/windowmanagerimp.cpp | 15 ++++++++++++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/window_pinnable_base.cpp b/apps/openmw/mwgui/window_pinnable_base.cpp index 4ddf49d27b..2e66a4805c 100644 --- a/apps/openmw/mwgui/window_pinnable_base.cpp +++ b/apps/openmw/mwgui/window_pinnable_base.cpp @@ -11,16 +11,6 @@ WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, MWBase::Win t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed); } -void WindowPinnableBase::setVisible(bool b) -{ - // Pinned windows can not be hidden - if (mPinned && !b) - return; - - WindowBase::setVisible(b); - mVisible = b; -} - void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName) { if ("PinToggle" == eventName) diff --git a/apps/openmw/mwgui/window_pinnable_base.hpp b/apps/openmw/mwgui/window_pinnable_base.hpp index 250dde1f85..c577564c79 100644 --- a/apps/openmw/mwgui/window_pinnable_base.hpp +++ b/apps/openmw/mwgui/window_pinnable_base.hpp @@ -11,7 +11,6 @@ namespace MWGui { public: WindowPinnableBase(const std::string& parLayout, MWBase::WindowManager& parWindowManager); - void setVisible(bool b); bool pinned() { return mPinned; } private: diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e03b91216d..39f7d07767 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -310,9 +310,16 @@ void WindowManager::updateVisible() setSpellVisibility((mAllowed & GW_Magic) && !mSpellWindow->pinned()); setHMSVisibility((mAllowed & GW_Stats) && !mStatsWindow->pinned()); - // If in game mode, don't show anything. + // If in game mode, show only the pinned windows if (gameMode) + { + mMap->setVisible(mMap->pinned()); + mStatsWindow->setVisible(mStatsWindow->pinned()); + mInventoryWindow->setVisible(mInventoryWindow->pinned()); + mSpellWindow->setVisible(mSpellWindow->pinned()); + return; + } GuiMode mode = mGuiModes.back(); @@ -327,6 +334,12 @@ void WindowManager::updateVisible() mSettingsWindow->setVisible(true); break; case GM_Console: + // Show the pinned windows + mMap->setVisible(mMap->pinned()); + mStatsWindow->setVisible(mStatsWindow->pinned()); + mInventoryWindow->setVisible(mInventoryWindow->pinned()); + mSpellWindow->setVisible(mSpellWindow->pinned()); + mConsole->enable(); break; case GM_Scroll: From 3ba3c71556d4e9b8abeb0fab8c329c86bec81082 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sun, 17 Feb 2013 02:56:07 +0100 Subject: [PATCH 4/7] Make the "lock window" button to change state visually --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/exposedwindow.cpp | 26 ++++++++++++++++++++++ apps/openmw/mwgui/exposedwindow.hpp | 26 ++++++++++++++++++++++ apps/openmw/mwgui/window_pinnable_base.cpp | 11 +++++++++ apps/openmw/mwgui/window_pinnable_base.hpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 2 ++ files/mygui/openmw_inventory_window.layout | 2 +- files/mygui/openmw_map_window.layout | 2 +- files/mygui/openmw_spell_window.layout | 2 +- files/mygui/openmw_stats_window.layout | 2 +- files/mygui/openmw_windows.skin.xml | 14 +++++++++++- 11 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 apps/openmw/mwgui/exposedwindow.cpp create mode 100644 apps/openmw/mwgui/exposedwindow.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index df679d4cbc..3dd5ed45d5 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -30,7 +30,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog trainingwindow travelwindow imagebutton + enchantingdialog trainingwindow travelwindow imagebutton exposedwindow ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/exposedwindow.cpp b/apps/openmw/mwgui/exposedwindow.cpp new file mode 100644 index 0000000000..fa37568d7b --- /dev/null +++ b/apps/openmw/mwgui/exposedwindow.cpp @@ -0,0 +1,26 @@ +#include "exposedwindow.hpp" + +#include "MyGUI_Window.h" + +namespace MWGui +{ + MyGUI::VectorWidgetPtr ExposedWindow::getSkinWidgetsByName (const std::string &name) + { + return MyGUI::Widget::getSkinWidgetsByName (name); + } + + MyGUI::Widget* ExposedWindow::getSkinWidget(const std::string & _name, bool _throw) + { + MyGUI::VectorWidgetPtr widgets = getSkinWidgetsByName (_name); + + if (widgets.empty()) + { + MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'"); + return nullptr; + } + else + { + return widgets[0]; + } + } +} diff --git a/apps/openmw/mwgui/exposedwindow.hpp b/apps/openmw/mwgui/exposedwindow.hpp new file mode 100644 index 0000000000..906d0b4065 --- /dev/null +++ b/apps/openmw/mwgui/exposedwindow.hpp @@ -0,0 +1,26 @@ +#ifndef MWGUI_EXPOSEDWINDOW_H +#define MWGUI_EXPOSEDWINDOW_H + +#include "MyGUI_Window.h" + +namespace MWGui +{ + + /** + * @brief subclass to provide access to some Widget internals. + */ + class ExposedWindow : public MyGUI::Window + { + MYGUI_RTTI_DERIVED(ExposedWindow) + + public: + MyGUI::VectorWidgetPtr getSkinWidgetsByName (const std::string &name); + + MyGUI::Widget* getSkinWidget(const std::string & _name, bool _throw = true); + ///< Get a widget defined in the inner skin of this window. + }; + +} + +#endif + diff --git a/apps/openmw/mwgui/window_pinnable_base.cpp b/apps/openmw/mwgui/window_pinnable_base.cpp index 2e66a4805c..781c427ef4 100644 --- a/apps/openmw/mwgui/window_pinnable_base.cpp +++ b/apps/openmw/mwgui/window_pinnable_base.cpp @@ -2,6 +2,8 @@ #include "../mwbase/windowmanager.hpp" +#include "exposedwindow.hpp" + using namespace MWGui; WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, MWBase::WindowManager& parWindowManager) @@ -9,6 +11,9 @@ WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, MWBase::Win { MyGUI::WindowPtr t = static_cast(mMainWidget); t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed); + + ExposedWindow* window = static_cast(mMainWidget); + mPinButton = window->getSkinWidget ("Button"); } void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName) @@ -16,6 +21,12 @@ void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std: if ("PinToggle" == eventName) { mPinned = !mPinned; + + if (mPinned) + mPinButton->changeWidgetSkin ("PinDown"); + else + mPinButton->changeWidgetSkin ("PinUp"); + onPinToggled(); } diff --git a/apps/openmw/mwgui/window_pinnable_base.hpp b/apps/openmw/mwgui/window_pinnable_base.hpp index c577564c79..7426b16fcf 100644 --- a/apps/openmw/mwgui/window_pinnable_base.hpp +++ b/apps/openmw/mwgui/window_pinnable_base.hpp @@ -19,6 +19,7 @@ namespace MWGui protected: virtual void onPinToggled() = 0; + MyGUI::Widget* mPinButton; bool mPinned; bool mVisible; }; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 39f7d07767..1dc11f2c44 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -52,6 +52,7 @@ #include "enchantingdialog.hpp" #include "trainingwindow.hpp" #include "imagebutton.hpp" +#include "exposedwindow.hpp" using namespace MWGui; @@ -127,6 +128,7 @@ WindowManager::WindowManager( MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 3a60916f7f..88cc5638d3 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_map_window.layout b/files/mygui/openmw_map_window.layout index b5479b6761..d4b87e60d1 100644 --- a/files/mygui/openmw_map_window.layout +++ b/files/mygui/openmw_map_window.layout @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_spell_window.layout b/files/mygui/openmw_spell_window.layout index d489f41b8a..6c6629605b 100644 --- a/files/mygui/openmw_spell_window.layout +++ b/files/mygui/openmw_spell_window.layout @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_stats_window.layout b/files/mygui/openmw_stats_window.layout index c2c8a5daea..55ee7b9dac 100644 --- a/files/mygui/openmw_stats_window.layout +++ b/files/mygui/openmw_stats_window.layout @@ -1,7 +1,7 @@ - + diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index a9eb23d68a..72b6861254 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -8,6 +8,18 @@ + + + + + + + + + + + + @@ -473,7 +485,7 @@ - + From 2dea86bbc7cb8b95415d626d1a8b90de894e1416 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sun, 17 Feb 2013 03:04:38 +0100 Subject: [PATCH 5/7] Make the "lock window" button appealing --- files/mygui/openmw_windows.skin.xml | 116 ++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 8 deletions(-) diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index 72b6861254..93aa8fd209 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -8,17 +8,117 @@ - - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -485,7 +585,7 @@ - + From 3dc28baa287dd9d2169bace23bf89d2cb792e084 Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Sun, 17 Feb 2013 16:29:38 +0100 Subject: [PATCH 6/7] Remove "PinToggle" event from layout file --- apps/openmw/mwgui/window_pinnable_base.cpp | 24 ++++++++-------------- apps/openmw/mwgui/window_pinnable_base.hpp | 2 +- files/mygui/openmw_windows.skin.xml | 4 +--- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwgui/window_pinnable_base.cpp b/apps/openmw/mwgui/window_pinnable_base.cpp index 781c427ef4..651b3a1e98 100644 --- a/apps/openmw/mwgui/window_pinnable_base.cpp +++ b/apps/openmw/mwgui/window_pinnable_base.cpp @@ -9,26 +9,20 @@ using namespace MWGui; WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, MWBase::WindowManager& parWindowManager) : WindowBase(parLayout, parWindowManager), mPinned(false), mVisible(false) { - MyGUI::WindowPtr t = static_cast(mMainWidget); - t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed); - ExposedWindow* window = static_cast(mMainWidget); mPinButton = window->getSkinWidget ("Button"); + + mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked); } -void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName) +void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender) { - if ("PinToggle" == eventName) - { - mPinned = !mPinned; + mPinned = !mPinned; - if (mPinned) - mPinButton->changeWidgetSkin ("PinDown"); - else - mPinButton->changeWidgetSkin ("PinUp"); + if (mPinned) + mPinButton->changeWidgetSkin ("PinDown"); + else + mPinButton->changeWidgetSkin ("PinUp"); - onPinToggled(); - } - - eventDone(this); + onPinToggled(); } diff --git a/apps/openmw/mwgui/window_pinnable_base.hpp b/apps/openmw/mwgui/window_pinnable_base.hpp index 7426b16fcf..50259858e2 100644 --- a/apps/openmw/mwgui/window_pinnable_base.hpp +++ b/apps/openmw/mwgui/window_pinnable_base.hpp @@ -14,7 +14,7 @@ namespace MWGui bool pinned() { return mPinned; } private: - void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); + void onPinButtonClicked(MyGUI::Widget* _sender); protected: virtual void onPinToggled() = 0; diff --git a/files/mygui/openmw_windows.skin.xml b/files/mygui/openmw_windows.skin.xml index 93aa8fd209..73f68e80dc 100644 --- a/files/mygui/openmw_windows.skin.xml +++ b/files/mygui/openmw_windows.skin.xml @@ -585,9 +585,7 @@ - - - + From f4749f10dadaf119fad8b3b85e0d74a23d72e781 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 20 Feb 2013 05:35:52 +0100 Subject: [PATCH 7/7] NIF bullet loader fix for incorrect collision shapes (credit goes to Chris, he asked me to push this) --- components/nifbullet/bullet_nif_loader.cpp | 134 ++++++--------------- components/nifbullet/bullet_nif_loader.hpp | 18 +-- 2 files changed, 46 insertions(+), 106 deletions(-) diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 9c6dafa34a..a619bdda23 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -43,25 +43,14 @@ http://www.gnu.org/licenses/ . typedef unsigned char ubyte; -using namespace NifBullet; - +namespace NifBullet +{ ManualBulletShapeLoader::~ManualBulletShapeLoader() { } -btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 const &m) -{ - Ogre::Quaternion oquat(m); - btQuaternion quat; - quat.setW(oquat.w); - quat.setX(oquat.x); - quat.setY(oquat.y); - quat.setZ(oquat.z); - return quat; -} - btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 const &v) { return btVector3(v[0], v[1], v[2]); @@ -90,7 +79,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) return; } - // The first record is assumed to be the root node Nif::Record *r = nif.getRecord(0); assert(r != NULL); @@ -106,13 +94,11 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) bool hasCollisionNode = hasRootCollisionNode(node); //do a first pass - handleNode(node,0,NULL,hasCollisionNode,false,false); + handleNode(node,0,hasCollisionNode,false,false); //if collide = false, then it does a second pass which create a shape for raycasting. if(cShape->mCollide == false) - { - handleNode(node,0,NULL,hasCollisionNode,false,true); - } + handleNode(node,0,hasCollisionNode,false,true); //cShape->collide = hasCollisionNode&&cShape->collide; @@ -129,9 +115,9 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) delete m_meshInterface; } }; + if(mBoundingBox != NULL) cShape->Shape = mBoundingBox; - else { currentShape = new TriangleMeshShape(mTriMesh,true); @@ -141,34 +127,30 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node const * node) { - if (node->recType == Nif::RC_NiNode) + if(node->recType == Nif::RC_RootCollisionNode) + return true; + + const Nif::NiNode *ninode = dynamic_cast(node); + if(ninode) { - Nif::NodeList &list = ((Nif::NiNode*)node)->children; - int n = list.length(); - for (int i=0; ichildren; + for(size_t i = 0;i < list.length();i++) { - if (!list[i].empty()) + if(!list[i].empty()) { - if(hasRootCollisionNode(list[i].getPtr())) return true;; + if(hasRootCollisionNode(list[i].getPtr())) + return true; } } } - else if (node->recType == Nif::RC_NiTriShape) - { - return false; - } - else if(node->recType == Nif::RC_RootCollisionNode) - { - return true; - } return false; } -void ManualBulletShapeLoader::handleNode(Nif::Node const *node, int flags, - const Nif::Transformation *parentTrafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) +void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags, + bool hasCollisionNode, bool isCollisionNode, + bool raycastingOnly) { - // Accumulate the flags from all the child nodes. This works for all // the flags we currently use, at least. flags |= node->flags; @@ -209,70 +191,36 @@ void ManualBulletShapeLoader::handleNode(Nif::Node const *node, int flags, } } - Nif::Transformation childTrafo = node->trafo; - - if (parentTrafo) - { - - // Get a non-const reference to the node's data, since we're - // overwriting it. TODO: Is this necessary? - - // For both position and rotation we have that: - // final_vector = old_vector + old_rotation*new_vector*old_scale - childTrafo.pos = parentTrafo->pos + parentTrafo->rotation*childTrafo.pos*parentTrafo->scale; - - // Merge the rotations together - childTrafo.rotation = parentTrafo->rotation * childTrafo.rotation; - - // Scale - childTrafo.scale *= parentTrafo->scale; - - } - if(node->hasBounds) { - - - btVector3 boxsize = getbtVector(node->boundXYZ); cShape->boxTranslation = node->boundPos; cShape->boxRotation = node->boundRot; - - mBoundingBox = new btBoxShape(boxsize); + mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ)); } - - // For NiNodes, loop through children - if (node->recType == Nif::RC_NiNode) - { - Nif::NodeList const &list = ((Nif::NiNode const *)node)->children; - int n = list.length(); - for (int i=0; irecType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) + if(node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) { cShape->mCollide = !(flags&0x800); - handleNiTriShape(dynamic_cast(node), flags,childTrafo.rotation,childTrafo.pos,childTrafo.scale,raycastingOnly); + handleNiTriShape(static_cast(node), flags, node->getWorldTransform(), raycastingOnly); } - else if(node->recType == Nif::RC_RootCollisionNode) + + // For NiNodes, loop through children + const Nif::NiNode *ninode = dynamic_cast(node); + if(ninode) { - Nif::NodeList &list = ((Nif::NiNode*)node)->children; - int n = list.length(); - for (int i=0; irecType == Nif::RC_RootCollisionNode); + + const Nif::NodeList &list = ninode->children; + for(size_t i = 0;i < list.length();i++) { - if (!list[i].empty()) - handleNode(list[i].getPtr(), flags,&childTrafo, hasCollisionNode,true,raycastingOnly); + if(!list[i].empty()) + handleNode(list[i].getPtr(), flags, hasCollisionNode, isCollisionNode, raycastingOnly); } } } -void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape const *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale, - bool raycastingOnly) +void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, + bool raycastingOnly) { assert(shape != NULL); @@ -296,18 +244,14 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape const *shape, int return; - Nif::NiTriShapeData *data = shape->data.getPtr(); - + const Nif::NiTriShapeData *data = shape->data.getPtr(); const std::vector &vertices = data->vertices; - const Ogre::Matrix3 &rot = shape->trafo.rotation; - const Ogre::Vector3 &pos = shape->trafo.pos; - float scale = shape->trafo.scale * parentScale; - short* triangles = &data->triangles[0]; + const short *triangles = &data->triangles[0]; for(size_t i = 0;i < data->triangles.size();i+=3) { - Ogre::Vector3 b1 = pos + rot*vertices[triangles[i+0]]*scale; - Ogre::Vector3 b2 = pos + rot*vertices[triangles[i+1]]*scale; - Ogre::Vector3 b3 = pos + rot*vertices[triangles[i+2]]*scale; + Ogre::Vector3 b1 = transform*vertices[triangles[i+0]]; + Ogre::Vector3 b2 = transform*vertices[triangles[i+1]]; + Ogre::Vector3 b3 = transform*vertices[triangles[i+2]]; mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z)); } } @@ -320,3 +264,5 @@ void ManualBulletShapeLoader::load(const std::string &name,const std::string &gr return; OEngine::Physic::BulletShapeManager::getSingleton().create(name,group,true,this); } + +} // namespace NifBullet diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 520878ce1c..0629b208de 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -51,19 +51,18 @@ namespace NifBullet class ManualBulletShapeLoader : public OEngine::Physic::BulletShapeLoader { public: - ManualBulletShapeLoader():resourceGroup("General"){} virtual ~ManualBulletShapeLoader(); - void warn(std::string msg) + void warn(const std::string &msg) { std::cerr << "NIFLoader: Warn:" << msg << "\n"; } - void fail(std::string msg) + void fail(const std::string &msg) { std::cerr << "NIFLoader: Fail: "<< msg << std::endl; - assert(1); + abort(); } /** @@ -79,31 +78,26 @@ public: void load(const std::string &name,const std::string &group); private: - btQuaternion getbtQuat(Ogre::Matrix3 const &m); - btVector3 getbtVector(Ogre::Vector3 const &v); /** *Parse a node. */ - void handleNode(Nif::Node const *node, int flags, - const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly); + void handleNode(Nif::Node const *node, int flags, bool hasCollisionNode, bool isCollisionNode, bool raycastingOnly); /** *Helper function */ - bool hasRootCollisionNode(Nif::Node const * node); + bool hasRootCollisionNode(const Nif::Node *node); /** *convert a NiTriShape to a bullet trishape. */ - void handleNiTriShape(Nif::NiTriShape const *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly); + void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Ogre::Matrix4 &transform, bool raycastingOnly); std::string resourceName; std::string resourceGroup; - - OEngine::Physic::BulletShape* cShape;//current shape btTriangleMesh *mTriMesh; btBoxShape *mBoundingBox;