mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 07:56:37 +00:00 
			
		
		
		
	Merge branch 'master' into graphics
This commit is contained in:
		
						commit
						52516ca4b4
					
				
					 13 changed files with 315 additions and 87 deletions
				
			
		|  | @ -240,18 +240,9 @@ void OMW::Engine::setNewGame(bool newGame) | ||||||
|     mNewGame = newGame; |     mNewGame = newGame; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Initialise and enter main loop.
 | std::string OMW::Engine::loadSettings (Settings::Manager & settings) | ||||||
| 
 |  | ||||||
| void OMW::Engine::go() |  | ||||||
| { | { | ||||||
|     assert (!mCellName.empty()); |  | ||||||
|     assert (!mMaster.empty()); |  | ||||||
|     assert (!mOgre); |  | ||||||
| 
 |  | ||||||
|     mOgre = new OEngine::Render::OgreRenderer; |  | ||||||
| 
 |  | ||||||
|     // Create the settings manager and load default settings file
 |     // Create the settings manager and load default settings file
 | ||||||
|     Settings::Manager settings; |  | ||||||
|     const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; |     const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; | ||||||
|     const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg"; |     const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg"; | ||||||
| 
 | 
 | ||||||
|  | @ -272,10 +263,6 @@ void OMW::Engine::go() | ||||||
|     else if (boost::filesystem::exists(globaldefault)) |     else if (boost::filesystem::exists(globaldefault)) | ||||||
|         settings.loadUser(globaldefault); |         settings.loadUser(globaldefault); | ||||||
| 
 | 
 | ||||||
|     // Get the path for the keybinder xml file
 |  | ||||||
|     std::string keybinderUser = (mCfgMgr.getUserPath() / "input.xml").string(); |  | ||||||
|     bool keybinderUserExists = boost::filesystem::exists(keybinderUser); |  | ||||||
| 
 |  | ||||||
|     mFpsLevel = settings.getInt("fps", "HUD"); |     mFpsLevel = settings.getInt("fps", "HUD"); | ||||||
| 
 | 
 | ||||||
|     // load nif overrides
 |     // load nif overrides
 | ||||||
|  | @ -285,6 +272,13 @@ void OMW::Engine::go() | ||||||
|     else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) |     else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) | ||||||
|         nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); |         nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); | ||||||
| 
 | 
 | ||||||
|  |     return settingspath; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void OMW::Engine::prepareEngine (Settings::Manager & settings) | ||||||
|  | { | ||||||
|  |     Nif::NIFFile::CacheLock cachelock; | ||||||
|  | 
 | ||||||
|     std::string renderSystem = settings.getString("render system", "Video"); |     std::string renderSystem = settings.getString("render system", "Video"); | ||||||
|     if (renderSystem == "") |     if (renderSystem == "") | ||||||
|     { |     { | ||||||
|  | @ -294,6 +288,9 @@ void OMW::Engine::go() | ||||||
|         renderSystem = "OpenGL Rendering Subsystem"; |         renderSystem = "OpenGL Rendering Subsystem"; | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     mOgre = new OEngine::Render::OgreRenderer; | ||||||
|  |      | ||||||
|     mOgre->configure( |     mOgre->configure( | ||||||
|         mCfgMgr.getLogPath().string(), |         mCfgMgr.getLogPath().string(), | ||||||
|         renderSystem, |         renderSystem, | ||||||
|  | @ -328,16 +325,13 @@ void OMW::Engine::go() | ||||||
|     // cursor replacer (converts the cursor from the bsa so they can be used by mygui)
 |     // cursor replacer (converts the cursor from the bsa so they can be used by mygui)
 | ||||||
|     MWGui::CursorReplace replacer; |     MWGui::CursorReplace replacer; | ||||||
| 
 | 
 | ||||||
|     // Create encoder
 |  | ||||||
|     ToUTF8::Utf8Encoder encoder (mEncoding); |  | ||||||
| 
 |  | ||||||
|     // Create the world
 |     // Create the world
 | ||||||
|     mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, |     mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, | ||||||
|         mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap, |         mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap, | ||||||
|         mActivationDistanceOverride)); |         mActivationDistanceOverride)); | ||||||
| 
 | 
 | ||||||
|     //Load translation data
 |     //Load translation data
 | ||||||
|     mTranslationDataStorage.setEncoder(&encoder); |     mTranslationDataStorage.setEncoder(mEncoder); | ||||||
|     mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster); |     mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster); | ||||||
| 
 | 
 | ||||||
|     // Create window manager - this manages all the MW-specific GUI windows
 |     // Create window manager - this manages all the MW-specific GUI windows
 | ||||||
|  | @ -365,6 +359,11 @@ void OMW::Engine::go() | ||||||
|     mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts, mTranslationDataStorage)); |     mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts, mTranslationDataStorage)); | ||||||
| 
 | 
 | ||||||
|     // Sets up the input system
 |     // Sets up the input system
 | ||||||
|  | 
 | ||||||
|  |     // Get the path for the keybinder xml file
 | ||||||
|  |     std::string keybinderUser = (mCfgMgr.getUserPath() / "input.xml").string(); | ||||||
|  |     bool keybinderUserExists = boost::filesystem::exists(keybinderUser); | ||||||
|  | 
 | ||||||
|     mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, |     mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, | ||||||
|         MWBase::Environment::get().getWorld()->getPlayer(), |         MWBase::Environment::get().getWorld()->getPlayer(), | ||||||
|          *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); |          *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); | ||||||
|  | @ -390,9 +389,6 @@ void OMW::Engine::go() | ||||||
| 
 | 
 | ||||||
|     mOgre->getRoot()->addFrameListener (this); |     mOgre->getRoot()->addFrameListener (this); | ||||||
| 
 | 
 | ||||||
|     // Play some good 'ol tunes
 |  | ||||||
|     MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); |  | ||||||
| 
 |  | ||||||
|     // scripts
 |     // scripts
 | ||||||
|     if (mCompileAll) |     if (mCompileAll) | ||||||
|     { |     { | ||||||
|  | @ -405,10 +401,35 @@ void OMW::Engine::go() | ||||||
|                 << "%)" |                 << "%)" | ||||||
|                 << std::endl; |                 << std::endl; | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Initialise and enter main loop.
 | ||||||
|  | 
 | ||||||
|  | void OMW::Engine::go() | ||||||
|  | { | ||||||
|  |     assert (!mCellName.empty()); | ||||||
|  |     assert (!mMaster.empty()); | ||||||
|  |     assert (!mOgre); | ||||||
|  | 
 | ||||||
|  |     Settings::Manager settings; | ||||||
|  | 	std::string settingspath; | ||||||
|  | 
 | ||||||
|  |     settingspath = loadSettings (settings); | ||||||
|  | 
 | ||||||
|  |     // Create encoder
 | ||||||
|  |     ToUTF8::Utf8Encoder encoder (mEncoding); | ||||||
|  |     mEncoder = &encoder; | ||||||
|  | 
 | ||||||
|  |     prepareEngine (settings); | ||||||
|  | 
 | ||||||
|  |     // Play some good 'ol tunes
 | ||||||
|  |     MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); | ||||||
| 
 | 
 | ||||||
|     if (!mStartupScript.empty()) |     if (!mStartupScript.empty()) | ||||||
|         MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript); |         MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript); | ||||||
| 
 | 
 | ||||||
|  |     std::cout << "\nPress Q/ESC or close window to exit.\n"; | ||||||
|  | 
 | ||||||
|     // Start the main rendering loop
 |     // Start the main rendering loop
 | ||||||
|     mOgre->start(); |     mOgre->start(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include <components/compiler/extensions.hpp> | #include <components/compiler/extensions.hpp> | ||||||
| #include <components/files/collections.hpp> | #include <components/files/collections.hpp> | ||||||
| #include <components/translation/translation.hpp> | #include <components/translation/translation.hpp> | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
| 
 | 
 | ||||||
| #include "mwbase/environment.hpp" | #include "mwbase/environment.hpp" | ||||||
| 
 | 
 | ||||||
|  | @ -61,6 +62,7 @@ namespace OMW | ||||||
|     { |     { | ||||||
|             MWBase::Environment mEnvironment; |             MWBase::Environment mEnvironment; | ||||||
|             ToUTF8::FromType mEncoding; |             ToUTF8::FromType mEncoding; | ||||||
|  |             ToUTF8::Utf8Encoder* mEncoder; | ||||||
|             Files::PathContainer mDataDirs; |             Files::PathContainer mDataDirs; | ||||||
|             boost::filesystem::path mResDir; |             boost::filesystem::path mResDir; | ||||||
|             OEngine::Render::OgreRenderer *mOgre; |             OEngine::Render::OgreRenderer *mOgre; | ||||||
|  | @ -103,6 +105,12 @@ namespace OMW | ||||||
| 
 | 
 | ||||||
|             virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); |             virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); | ||||||
| 
 | 
 | ||||||
|  |             /// Load settings from various files, returns the path to the user settings file
 | ||||||
|  |             std::string loadSettings (Settings::Manager & settings); | ||||||
|  | 
 | ||||||
|  |             /// Prepare engine for game play
 | ||||||
|  |             void prepareEngine (Settings::Manager & settings); | ||||||
|  | 
 | ||||||
|         public: |         public: | ||||||
|             Engine(Files::ConfigurationManager& configurationManager); |             Engine(Files::ConfigurationManager& configurationManager); | ||||||
|             virtual ~Engine(); |             virtual ~Engine(); | ||||||
|  |  | ||||||
|  | @ -12,6 +12,9 @@ | ||||||
| #include "../mwworld/cellstore.hpp" | #include "../mwworld/cellstore.hpp" | ||||||
| #include "../mwworld/physicssystem.hpp" | #include "../mwworld/physicssystem.hpp" | ||||||
| #include "../mwworld/actioneat.hpp" | #include "../mwworld/actioneat.hpp" | ||||||
|  | #include "../mwworld/player.hpp" | ||||||
|  | 
 | ||||||
|  | #include "../mwmechanics/npcstats.hpp" | ||||||
| 
 | 
 | ||||||
| #include "../mwgui/tooltips.hpp" | #include "../mwgui/tooltips.hpp" | ||||||
| 
 | 
 | ||||||
|  | @ -154,6 +157,10 @@ namespace MWClass | ||||||
|             text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); |             text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); | ||||||
|  |         MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); | ||||||
|  |         int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); | ||||||
|  | 
 | ||||||
|         MWGui::Widgets::SpellEffectList list; |         MWGui::Widgets::SpellEffectList list; | ||||||
|         for (int i=0; i<4; ++i) |         for (int i=0; i<4; ++i) | ||||||
|         { |         { | ||||||
|  | @ -163,6 +170,12 @@ namespace MWClass | ||||||
|             params.mEffectID = ref->mBase->mData.mEffectID[i]; |             params.mEffectID = ref->mBase->mData.mEffectID[i]; | ||||||
|             params.mAttribute = ref->mBase->mData.mAttributes[i]; |             params.mAttribute = ref->mBase->mData.mAttributes[i]; | ||||||
|             params.mSkill = ref->mBase->mData.mSkills[i]; |             params.mSkill = ref->mBase->mData.mSkills[i]; | ||||||
|  | 
 | ||||||
|  |             params.mKnown = ( (i == 0 && alchemySkill >= 15) | ||||||
|  |                  || (i == 1 && alchemySkill >= 30) | ||||||
|  |                  || (i == 2 && alchemySkill >= 45) | ||||||
|  |                  || (i == 3 && alchemySkill >= 60)); | ||||||
|  | 
 | ||||||
|             list.push_back(params); |             list.push_back(params); | ||||||
|         } |         } | ||||||
|         info.effects = list; |         info.effects = list; | ||||||
|  |  | ||||||
|  | @ -390,8 +390,13 @@ void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) | ||||||
| 
 | 
 | ||||||
| void MWSpellEffect::updateWidgets() | void MWSpellEffect::updateWidgets() | ||||||
| { | { | ||||||
|     if (!mWindowManager) |     if (!mEffectParams.mKnown) | ||||||
|  |     { | ||||||
|  |         mTextWidget->setCaption ("?"); | ||||||
|  |         mRequestedWidth = mTextWidget->getTextSize().width + 24; | ||||||
|  |         mImageWidget->setImageTexture (""); | ||||||
|         return; |         return; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     const MWWorld::ESMStore &store = |     const MWWorld::ESMStore &store = | ||||||
|         MWBase::Environment::get().getWorld()->getStore(); |         MWBase::Environment::get().getWorld()->getStore(); | ||||||
|  | @ -400,7 +405,6 @@ void MWSpellEffect::updateWidgets() | ||||||
|         store.get<ESM::MagicEffect>().search(mEffectParams.mEffectID); |         store.get<ESM::MagicEffect>().search(mEffectParams.mEffectID); | ||||||
| 
 | 
 | ||||||
|     assert(magicEffect); |     assert(magicEffect); | ||||||
|     assert(mWindowManager); |  | ||||||
| 
 | 
 | ||||||
|     std::string pt =  mWindowManager->getGameSettingString("spoint", ""); |     std::string pt =  mWindowManager->getGameSettingString("spoint", ""); | ||||||
|     std::string pts =  mWindowManager->getGameSettingString("spoints", ""); |     std::string pts =  mWindowManager->getGameSettingString("spoints", ""); | ||||||
|  |  | ||||||
|  | @ -37,12 +37,15 @@ namespace MWGui | ||||||
|                 , mEffectID(-1) |                 , mEffectID(-1) | ||||||
|                 , mNoTarget(false) |                 , mNoTarget(false) | ||||||
|                 , mIsConstant(false) |                 , mIsConstant(false) | ||||||
|  |                 , mKnown(true) | ||||||
|             { |             { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             bool mNoTarget; // potion effects for example have no target (target is always the player)
 |             bool mNoTarget; // potion effects for example have no target (target is always the player)
 | ||||||
|             bool mIsConstant; // constant effect means that duration will not be displayed
 |             bool mIsConstant; // constant effect means that duration will not be displayed
 | ||||||
| 
 | 
 | ||||||
|  |             bool mKnown; // is this effect known to the player? (If not, will display as a question mark instead)
 | ||||||
|  | 
 | ||||||
|             // value of -1 here means the effect is unknown to the player
 |             // value of -1 here means the effect is unknown to the player
 | ||||||
|             short mEffectID; |             short mEffectID; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -172,6 +172,8 @@ namespace MWWorld | ||||||
| 
 | 
 | ||||||
|     void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) |     void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) | ||||||
|     { |     { | ||||||
|  |         Nif::NIFFile::CacheLock cachelock; | ||||||
|  | 
 | ||||||
|         mRendering.preCellChange(mCurrentCell); |         mRendering.preCellChange(mCurrentCell); | ||||||
| 
 | 
 | ||||||
|         // remove active
 |         // remove active
 | ||||||
|  |  | ||||||
|  | @ -6,11 +6,6 @@ | ||||||
| namespace Files { | namespace Files { | ||||||
| 
 | 
 | ||||||
| bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { | bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { | ||||||
|     // Append plugin suffix if debugging.
 |  | ||||||
| #if defined(DEBUG) |  | ||||||
| 	pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE | #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE | ||||||
| 	std::ostringstream verStream; | 	std::ostringstream verStream; | ||||||
| 	verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; | 	verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; | ||||||
|  | @ -28,13 +23,28 @@ bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre:: | ||||||
|     pluginExt = ".so"; |     pluginExt = ".so"; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     std::string pluginPath = pluginDir + "/" + pluginName + pluginExt; |     // Append plugin suffix if debugging.
 | ||||||
|  |     std::string pluginPath; | ||||||
|  | #if defined(DEBUG) | ||||||
|  |     pluginPath = pluginDir + "/" + pluginName + OGRE_PLUGIN_DEBUG_SUFFIX + pluginExt; | ||||||
|     if (boost::filesystem::exists(pluginPath)) { |     if (boost::filesystem::exists(pluginPath)) { | ||||||
|     	ogreRoot.loadPlugin(pluginPath); |         ogreRoot.loadPlugin(pluginPath); | ||||||
|     	return true; |         return true; | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|     	return false; | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 | ||||||
|  |         return false; | ||||||
|  | #endif //OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 | ||||||
|  |     } | ||||||
|  | #endif //defined(DEBUG)
 | ||||||
|  |      | ||||||
|  |     pluginPath = pluginDir + "/" + pluginName + pluginExt; | ||||||
|  |     if (boost::filesystem::exists(pluginPath)) { | ||||||
|  |         ogreRoot.loadPlugin(pluginPath); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         return false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -34,10 +34,159 @@ | ||||||
| #include "controller.hpp" | #include "controller.hpp" | ||||||
| 
 | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | 
 | ||||||
|  | //TODO: when threading is needed, enable these
 | ||||||
|  | //#include <boost/mutex.hpp>
 | ||||||
|  | //#include <boost/thread/locks.hpp>
 | ||||||
|  | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| using namespace Nif; | using namespace Nif; | ||||||
| using namespace Misc; | using namespace Misc; | ||||||
| 
 | 
 | ||||||
|  | class NIFFile::LoadedCache | ||||||
|  | { | ||||||
|  |     //TODO: enable this to make cache thread safe...
 | ||||||
|  |     //typedef boost::mutex mutex;
 | ||||||
|  |      | ||||||
|  |     struct mutex | ||||||
|  |     { | ||||||
|  |         void lock () {}; | ||||||
|  |         void unlock () {} | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     typedef boost::lock_guard <mutex> lock_guard; | ||||||
|  |     typedef std::map < std::string, boost::weak_ptr <NIFFile> > loaded_map; | ||||||
|  |     typedef std::vector < boost::shared_ptr <NIFFile> > locked_files; | ||||||
|  | 
 | ||||||
|  |     static int sLockLevel; | ||||||
|  |     static mutex sProtector; | ||||||
|  |     static loaded_map sLoadedMap; | ||||||
|  |     static locked_files sLockedFiles; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 
 | ||||||
|  |     static ptr create (const std::string &name) | ||||||
|  |     { | ||||||
|  |         lock_guard _ (sProtector); | ||||||
|  | 
 | ||||||
|  |         ptr result; | ||||||
|  | 
 | ||||||
|  |         // lookup the resource
 | ||||||
|  |         loaded_map::iterator i = sLoadedMap.find (name); | ||||||
|  | 
 | ||||||
|  |         if (i == sLoadedMap.end ()) // it doesn't existing currently,
 | ||||||
|  |         {                           // or hasn't in the very near past
 | ||||||
|  | 
 | ||||||
|  |             // create it now, for smoother threading if needed, the
 | ||||||
|  |             // loading should be performed outside of the sLoaderMap
 | ||||||
|  |             // lock and an alternate mechanism should be used to
 | ||||||
|  |             // synchronize threads competing to load the same resource
 | ||||||
|  |             result = boost::make_shared <NIFFile> (name, psudo_private_modifier()); | ||||||
|  | 
 | ||||||
|  |             // if we are locking the cache add an extra reference
 | ||||||
|  |             // to keep the file in memory
 | ||||||
|  |             if (sLockLevel > 0) | ||||||
|  |                 sLockedFiles.push_back (result); | ||||||
|  | 
 | ||||||
|  |             // stash a reference to the resource so that future
 | ||||||
|  |             // calls can benefit
 | ||||||
|  |             sLoadedMap [name] = boost::weak_ptr <NIFFile> (result); | ||||||
|  |         } | ||||||
|  |         else // it may (probably) still exists
 | ||||||
|  |         { | ||||||
|  |             // attempt to get the reference
 | ||||||
|  |             result = i->second.lock (); | ||||||
|  | 
 | ||||||
|  |             if (!result) // resource is in the process of being destroyed
 | ||||||
|  |             { | ||||||
|  |                 // create a new instance, to replace the one that has
 | ||||||
|  |                 // begun the irreversible process of being destroyed
 | ||||||
|  |                 result = boost::make_shared <NIFFile> (name, psudo_private_modifier()); | ||||||
|  | 
 | ||||||
|  |                 // respect the cache lock...
 | ||||||
|  |                 if (sLockLevel > 0) | ||||||
|  |                     sLockedFiles.push_back (result); | ||||||
|  | 
 | ||||||
|  |                 // we potentially overwrite an expired pointer here
 | ||||||
|  |                 // but the other thread performing the delete on
 | ||||||
|  |                 // the previous copy of this resource will detect it
 | ||||||
|  |                 // and make sure not to erase the new reference
 | ||||||
|  |                 sLoadedMap [name] = boost::weak_ptr <NIFFile> (result); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // we made it!
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void release (NIFFile * file) | ||||||
|  |     { | ||||||
|  |         lock_guard _ (sProtector); | ||||||
|  | 
 | ||||||
|  |         loaded_map::iterator i = sLoadedMap.find (file->filename); | ||||||
|  | 
 | ||||||
|  |         // its got to be in here, it just might not be us...
 | ||||||
|  |         assert (i != sLoadedMap.end ()); | ||||||
|  | 
 | ||||||
|  |         // if weak_ptr is still expired, this resource hasn't been recreated
 | ||||||
|  |         // between the initiation of the final release due to destruction
 | ||||||
|  |         // of the last shared pointer and this thread acquiring the lock on
 | ||||||
|  |         // the loader map
 | ||||||
|  |         if (i->second.expired ()) | ||||||
|  |             sLoadedMap.erase (i); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void lockCache () | ||||||
|  |     { | ||||||
|  |         lock_guard _ (sProtector); | ||||||
|  | 
 | ||||||
|  |         sLockLevel++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static void unlockCache () | ||||||
|  |     { | ||||||
|  |         locked_files resetList; | ||||||
|  | 
 | ||||||
|  |         { | ||||||
|  |             lock_guard _ (sProtector); | ||||||
|  | 
 | ||||||
|  |             if (--sLockLevel) | ||||||
|  |                 sLockedFiles.swap(resetList); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // this not necessary, but makes it clear that the
 | ||||||
|  |         // deletion of the locked cache entries is being done
 | ||||||
|  |         // outside the protection of sProtector
 | ||||||
|  |         resetList.clear (); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int NIFFile::LoadedCache::sLockLevel = 0; | ||||||
|  | NIFFile::LoadedCache::mutex NIFFile::LoadedCache::sProtector; | ||||||
|  | NIFFile::LoadedCache::loaded_map NIFFile::LoadedCache::sLoadedMap; | ||||||
|  | NIFFile::LoadedCache::locked_files NIFFile::LoadedCache::sLockedFiles; | ||||||
|  | 
 | ||||||
|  | // these three calls are forwarded to the cache implementation...
 | ||||||
|  | void NIFFile::lockCache ()     { LoadedCache::lockCache (); } | ||||||
|  | void NIFFile::unlockCache ()   { LoadedCache::unlockCache (); } | ||||||
|  | NIFFile::ptr NIFFile::create (const std::string &name) { return LoadedCache::create  (name); } | ||||||
|  | 
 | ||||||
|  | /// Open a NIF stream. The name is used for error messages.
 | ||||||
|  | NIFFile::NIFFile(const std::string &name, psudo_private_modifier) | ||||||
|  |     : filename(name) | ||||||
|  | { | ||||||
|  |     inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); | ||||||
|  |     parse(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | NIFFile::~NIFFile() | ||||||
|  | { | ||||||
|  |     LoadedCache::release (this); | ||||||
|  | 
 | ||||||
|  |     for(std::size_t i=0; i<records.size(); i++) | ||||||
|  |         delete records[i]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* This file implements functions from the NIFFile class. It is also
 | /* This file implements functions from the NIFFile class. It is also
 | ||||||
|    where we stash all the functions we couldn't add as inline |    where we stash all the functions we couldn't add as inline | ||||||
|    definitions in the record types. |    definitions in the record types. | ||||||
|  | @ -211,14 +360,14 @@ void NiSkinInstance::post(NIFFile *nif) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Ogre::Matrix4 Node::getLocalTransform() | Ogre::Matrix4 Node::getLocalTransform() const | ||||||
| { | { | ||||||
|     Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY); |     Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY); | ||||||
|     mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation)); |     mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation)); | ||||||
|     return mat4; |     return mat4; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Ogre::Matrix4 Node::getWorldTransform() | Ogre::Matrix4 Node::getWorldTransform() const | ||||||
| { | { | ||||||
|     if(parent != NULL) |     if(parent != NULL) | ||||||
|         return parent->getWorldTransform() * getLocalTransform(); |         return parent->getWorldTransform() * getLocalTransform(); | ||||||
|  |  | ||||||
|  | @ -37,6 +37,11 @@ | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <cassert> | #include <cassert> | ||||||
| 
 | 
 | ||||||
|  | #include <boost/weak_ptr.hpp> | ||||||
|  | #include <boost/shared_ptr.hpp> | ||||||
|  | #include <boost/make_shared.hpp> | ||||||
|  | #include <boost/detail/endian.hpp> | ||||||
|  | 
 | ||||||
| #include <libs/platform/stdint.h> | #include <libs/platform/stdint.h> | ||||||
| 
 | 
 | ||||||
| #include "record.hpp" | #include "record.hpp" | ||||||
|  | @ -93,6 +98,14 @@ class NIFFile | ||||||
|         return u.f; |         return u.f; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     class LoadedCache; | ||||||
|  |     friend class LoadedCache; | ||||||
|  | 
 | ||||||
|  |     // attempt to protect NIFFile from misuse...
 | ||||||
|  |     struct psudo_private_modifier {}; // this dirty little trick should optimize out
 | ||||||
|  |     NIFFile (NIFFile const &); | ||||||
|  |     void operator = (NIFFile const &); | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     /// Used for error handling
 |     /// Used for error handling
 | ||||||
|     void fail(const std::string &msg) |     void fail(const std::string &msg) | ||||||
|  | @ -108,19 +121,21 @@ public: | ||||||
|                  << "File: "<<filename <<std::endl; |                  << "File: "<<filename <<std::endl; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Open a NIF stream. The name is used for error messages.
 |     typedef boost::shared_ptr <NIFFile> ptr; | ||||||
|     NIFFile(const std::string &name) |  | ||||||
|       : filename(name) |  | ||||||
|     { |  | ||||||
|         inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); |  | ||||||
|         parse(); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     ~NIFFile() |     /// Open a NIF stream. The name is used for error messages.
 | ||||||
|  |     NIFFile(const std::string &name, psudo_private_modifier); | ||||||
|  |     ~NIFFile(); | ||||||
|  | 
 | ||||||
|  |     static ptr create (const std::string &name); | ||||||
|  |     static void lockCache (); | ||||||
|  |     static void unlockCache (); | ||||||
|  | 
 | ||||||
|  |     struct CacheLock | ||||||
|     { |     { | ||||||
|         for(std::size_t i=0; i<records.size(); i++) |         CacheLock () { lockCache (); } | ||||||
|             delete records[i]; |         ~CacheLock () { unlockCache (); } | ||||||
|     } |     }; | ||||||
| 
 | 
 | ||||||
|     /// Get a given record
 |     /// Get a given record
 | ||||||
|     Record *getRecord(size_t index) |     Record *getRecord(size_t index) | ||||||
|  |  | ||||||
|  | @ -111,8 +111,8 @@ public: | ||||||
|         boneIndex = ind; |         boneIndex = ind; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Ogre::Matrix4 getLocalTransform(); |     Ogre::Matrix4 getLocalTransform() const; | ||||||
|     Ogre::Matrix4 getWorldTransform(); |     Ogre::Matrix4 getWorldTransform() const; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct NiNode : Node | struct NiNode : Node | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ ManualBulletShapeLoader::~ManualBulletShapeLoader() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m) | btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 const &m) | ||||||
| { | { | ||||||
|     Ogre::Quaternion oquat(m); |     Ogre::Quaternion oquat(m); | ||||||
|     btQuaternion quat; |     btQuaternion quat; | ||||||
|  | @ -62,7 +62,7 @@ btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m) | ||||||
|     return quat; |     return quat; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v) | btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 const &v) | ||||||
| { | { | ||||||
|     return btVector3(v[0], v[1], v[2]); |     return btVector3(v[0], v[1], v[2]); | ||||||
| } | } | ||||||
|  | @ -82,7 +82,8 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) | ||||||
|     // of the early stages of development. Right now we WANT to catch
 |     // of the early stages of development. Right now we WANT to catch
 | ||||||
|     // every error as early and intrusively as possible, as it's most
 |     // every error as early and intrusively as possible, as it's most
 | ||||||
|     // likely a sign of incomplete code rather than faulty input.
 |     // likely a sign of incomplete code rather than faulty input.
 | ||||||
|     Nif::NIFFile nif(resourceName.substr(0, resourceName.length()-7)); |     Nif::NIFFile::ptr pnif (Nif::NIFFile::create (resourceName.substr(0, resourceName.length()-7))); | ||||||
|  |     Nif::NIFFile & nif = *pnif.get (); | ||||||
|     if (nif.numRecords() < 1) |     if (nif.numRecords() < 1) | ||||||
|     { |     { | ||||||
|         warn("Found no records in NIF."); |         warn("Found no records in NIF."); | ||||||
|  | @ -138,7 +139,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) | bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node const * node) | ||||||
| { | { | ||||||
|     if (node->recType == Nif::RC_NiNode) |     if (node->recType == Nif::RC_NiNode) | ||||||
|     { |     { | ||||||
|  | @ -164,8 +165,8 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | void ManualBulletShapeLoader::handleNode(Nif::Node const *node, int flags, | ||||||
|    const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) |    const Nif::Transformation *parentTrafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|     // Accumulate the flags from all the child nodes. This works for all
 |     // Accumulate the flags from all the child nodes. This works for all
 | ||||||
|  | @ -181,7 +182,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Check for extra data
 |     // Check for extra data
 | ||||||
|     Nif::Extra *e = node; |     Nif::Extra const *e = node; | ||||||
|     while (!e->extra.empty()) |     while (!e->extra.empty()) | ||||||
|     { |     { | ||||||
|         // Get the next extra data in the list
 |         // Get the next extra data in the list
 | ||||||
|  | @ -208,23 +209,23 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     Nif::Transformation childTrafo = node->trafo; | ||||||
| 
 | 
 | ||||||
|     if (trafo) |     if (parentTrafo) | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|         // Get a non-const reference to the node's data, since we're
 |         // Get a non-const reference to the node's data, since we're
 | ||||||
|         // overwriting it. TODO: Is this necessary?
 |         // overwriting it. TODO: Is this necessary?
 | ||||||
|         Nif::Transformation &final = node->trafo; |  | ||||||
| 
 | 
 | ||||||
|         // For both position and rotation we have that:
 |         // For both position and rotation we have that:
 | ||||||
|         // final_vector = old_vector + old_rotation*new_vector*old_scale
 |         // final_vector = old_vector + old_rotation*new_vector*old_scale
 | ||||||
|         final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale; |         childTrafo.pos = parentTrafo->pos + parentTrafo->rotation*childTrafo.pos*parentTrafo->scale; | ||||||
| 
 | 
 | ||||||
|         // Merge the rotations together
 |         // Merge the rotations together
 | ||||||
|         final.rotation = trafo->rotation * final.rotation; |         childTrafo.rotation = parentTrafo->rotation * childTrafo.rotation; | ||||||
| 
 | 
 | ||||||
|         // Scale
 |         // Scale
 | ||||||
|         final.scale *= trafo->scale; |         childTrafo.scale *= parentTrafo->scale; | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -232,7 +233,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|          |          | ||||||
|         btVector3 boxsize = getbtVector((node->boundXYZ)); |         btVector3 boxsize = getbtVector(node->boundXYZ); | ||||||
|         cShape->boxTranslation = node->boundPos; |         cShape->boxTranslation = node->boundPos; | ||||||
|         cShape->boxRotation = node->boundRot; |         cShape->boxRotation = node->boundRot; | ||||||
| 
 | 
 | ||||||
|  | @ -243,20 +244,20 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | ||||||
|     // For NiNodes, loop through children
 |     // For NiNodes, loop through children
 | ||||||
|     if (node->recType == Nif::RC_NiNode) |     if (node->recType == Nif::RC_NiNode) | ||||||
|     { |     { | ||||||
|         Nif::NodeList &list = ((Nif::NiNode*)node)->children; |         Nif::NodeList const &list = ((Nif::NiNode const *)node)->children; | ||||||
|         int n = list.length(); |         int n = list.length(); | ||||||
|         for (int i=0; i<n; i++) |         for (int i=0; i<n; i++) | ||||||
|         { |         { | ||||||
|             if (!list[i].empty()) |             if (!list[i].empty()) | ||||||
|             { |             { | ||||||
|                 handleNode(list[i].getPtr(), flags,&node->trafo,hasCollisionNode,isCollisionNode,raycastingOnly); |                 handleNode(list[i].getPtr(), flags,&childTrafo,hasCollisionNode,isCollisionNode,raycastingOnly); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) |     else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) | ||||||
|     { |     { | ||||||
|         cShape->mCollide = !(flags&0x800); |         cShape->mCollide = !(flags&0x800); | ||||||
|         handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly); |         handleNiTriShape(dynamic_cast<Nif::NiTriShape const *>(node), flags,childTrafo.rotation,childTrafo.pos,childTrafo.scale,raycastingOnly); | ||||||
|     } |     } | ||||||
|     else if(node->recType == Nif::RC_RootCollisionNode) |     else if(node->recType == Nif::RC_RootCollisionNode) | ||||||
|     { |     { | ||||||
|  | @ -265,12 +266,12 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | ||||||
|         for (int i=0; i<n; i++) |         for (int i=0; i<n; i++) | ||||||
|         { |         { | ||||||
|             if (!list[i].empty()) |             if (!list[i].empty()) | ||||||
|                 handleNode(list[i].getPtr(), flags,&node->trafo, hasCollisionNode,true,raycastingOnly); |                 handleNode(list[i].getPtr(), flags,&childTrafo, hasCollisionNode,true,raycastingOnly); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale, | void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape const *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale, | ||||||
|     bool raycastingOnly) |     bool raycastingOnly) | ||||||
| { | { | ||||||
|     assert(shape != NULL); |     assert(shape != NULL); | ||||||
|  |  | ||||||
|  | @ -79,25 +79,25 @@ public: | ||||||
|     void load(const std::string &name,const std::string &group); |     void load(const std::string &name,const std::string &group); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     btQuaternion getbtQuat(Ogre::Matrix3 &m); |     btQuaternion getbtQuat(Ogre::Matrix3 const &m); | ||||||
| 
 | 
 | ||||||
|     btVector3 getbtVector(Ogre::Vector3 &v); |     btVector3 getbtVector(Ogre::Vector3 const &v); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|     *Parse a node. |     *Parse a node. | ||||||
|     */ |     */ | ||||||
|     void handleNode(Nif::Node *node, int flags, |     void handleNode(Nif::Node const *node, int flags, | ||||||
|         const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly); |         const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|     *Helper function |     *Helper function | ||||||
|     */ |     */ | ||||||
|     bool hasRootCollisionNode(Nif::Node* node); |     bool hasRootCollisionNode(Nif::Node const * node); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|     *convert a NiTriShape to a bullet trishape. |     *convert a NiTriShape to a bullet trishape. | ||||||
|     */ |     */ | ||||||
|     void handleNiTriShape(Nif::NiTriShape *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly); |     void handleNiTriShape(Nif::NiTriShape const *shape, int flags,Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScales,bool raycastingOnly); | ||||||
| 
 | 
 | ||||||
|     std::string resourceName; |     std::string resourceName; | ||||||
|     std::string resourceGroup; |     std::string resourceGroup; | ||||||
|  |  | ||||||
|  | @ -187,7 +187,7 @@ static TextKeyMap extractTextKeys(const Nif::NiTextKeyExtraData *tk) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, std::vector<Nif::NiKeyframeController*> &ctrls, Ogre::Bone *parent=NULL) | void buildBones(Ogre::Skeleton *skel, const Nif::Node *node, std::vector<Nif::NiKeyframeController const*> &ctrls, Ogre::Bone *parent=NULL) | ||||||
| { | { | ||||||
|     Ogre::Bone *bone; |     Ogre::Bone *bone; | ||||||
|     if(!skel->hasBone(node->name)) |     if(!skel->hasBone(node->name)) | ||||||
|  | @ -252,10 +252,11 @@ void loadResource(Ogre::Resource *resource) | ||||||
|     Ogre::Skeleton *skel = dynamic_cast<Ogre::Skeleton*>(resource); |     Ogre::Skeleton *skel = dynamic_cast<Ogre::Skeleton*>(resource); | ||||||
|     OgreAssert(skel, "Attempting to load a skeleton into a non-skeleton resource!"); |     OgreAssert(skel, "Attempting to load a skeleton into a non-skeleton resource!"); | ||||||
| 
 | 
 | ||||||
|     Nif::NIFFile nif(skel->getName()); |     Nif::NIFFile::ptr pnif(Nif::NIFFile::create (skel->getName())); | ||||||
|  |     Nif::NIFFile & nif = *pnif.get (); | ||||||
|     const Nif::Node *node = dynamic_cast<const Nif::Node*>(nif.getRecord(0)); |     const Nif::Node *node = dynamic_cast<const Nif::Node*>(nif.getRecord(0)); | ||||||
| 
 | 
 | ||||||
|     std::vector<Nif::NiKeyframeController*> ctrls; |     std::vector<Nif::NiKeyframeController const*> ctrls; | ||||||
|     buildBones(skel, node, ctrls); |     buildBones(skel, node, ctrls); | ||||||
| 
 | 
 | ||||||
|     std::vector<std::string> targets; |     std::vector<std::string> targets; | ||||||
|  | @ -266,7 +267,7 @@ void loadResource(Ogre::Resource *resource) | ||||||
|     float maxtime = 0.0f; |     float maxtime = 0.0f; | ||||||
|     for(size_t i = 0;i < ctrls.size();i++) |     for(size_t i = 0;i < ctrls.size();i++) | ||||||
|     { |     { | ||||||
|         Nif::NiKeyframeController *ctrl = ctrls[i]; |         Nif::NiKeyframeController const *ctrl = ctrls[i]; | ||||||
|         maxtime = std::max(maxtime, ctrl->timeStop); |         maxtime = std::max(maxtime, ctrl->timeStop); | ||||||
|         Nif::Named *target = dynamic_cast<Nif::Named*>(ctrl->target.getPtr()); |         Nif::Named *target = dynamic_cast<Nif::Named*>(ctrl->target.getPtr()); | ||||||
|         if(target != NULL) |         if(target != NULL) | ||||||
|  | @ -289,8 +290,8 @@ void loadResource(Ogre::Resource *resource) | ||||||
| 
 | 
 | ||||||
|     for(size_t i = 0;i < ctrls.size();i++) |     for(size_t i = 0;i < ctrls.size();i++) | ||||||
|     { |     { | ||||||
|         Nif::NiKeyframeController *kfc = ctrls[i]; |         Nif::NiKeyframeController const *kfc = ctrls[i]; | ||||||
|         Nif::NiKeyframeData *kf = kfc->data.getPtr(); |         Nif::NiKeyframeData const *kf = kfc->data.getPtr(); | ||||||
| 
 | 
 | ||||||
|         /* Get the keyframes and make sure they're sorted first to last */ |         /* Get the keyframes and make sure they're sorted first to last */ | ||||||
|         Nif::QuaternionKeyList quatkeys = kf->mRotations; |         Nif::QuaternionKeyList quatkeys = kf->mRotations; | ||||||
|  | @ -713,7 +714,7 @@ class NIFMeshLoader : Ogre::ManualResourceLoader | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     // Convert NiTriShape to Ogre::SubMesh
 |     // Convert NiTriShape to Ogre::SubMesh
 | ||||||
|     void handleNiTriShape(Ogre::Mesh *mesh, Nif::NiTriShape *shape) |     void handleNiTriShape(Ogre::Mesh *mesh, Nif::NiTriShape const *shape) | ||||||
|     { |     { | ||||||
|         Ogre::SkeletonPtr skel; |         Ogre::SkeletonPtr skel; | ||||||
|         const Nif::NiTriShapeData *data = shape->data.getPtr(); |         const Nif::NiTriShapeData *data = shape->data.getPtr(); | ||||||
|  | @ -911,18 +912,18 @@ class NIFMeshLoader : Ogre::ManualResourceLoader | ||||||
|             sub->setMaterialName(mMaterialName); |             sub->setMaterialName(mMaterialName); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool findTriShape(Ogre::Mesh *mesh, Nif::Node *node) |     bool findTriShape(Ogre::Mesh *mesh, Nif::Node const *node) | ||||||
|     { |     { | ||||||
|         if(node->recType == Nif::RC_NiTriShape && mShapeName == node->name) |         if(node->recType == Nif::RC_NiTriShape && mShapeName == node->name) | ||||||
|         { |         { | ||||||
|             handleNiTriShape(mesh, dynamic_cast<Nif::NiTriShape*>(node)); |             handleNiTriShape(mesh, dynamic_cast<Nif::NiTriShape const *>(node)); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Nif::NiNode *ninode = dynamic_cast<Nif::NiNode*>(node); |         Nif::NiNode const *ninode = dynamic_cast<Nif::NiNode const *>(node); | ||||||
|         if(ninode) |         if(ninode) | ||||||
|         { |         { | ||||||
|             Nif::NodeList &children = ninode->children; |             Nif::NodeList const &children = ninode->children; | ||||||
|             for(size_t i = 0;i < children.length();i++) |             for(size_t i = 0;i < children.length();i++) | ||||||
|             { |             { | ||||||
|                 if(!children[i].empty()) |                 if(!children[i].empty()) | ||||||
|  | @ -958,8 +959,8 @@ public: | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Nif::NIFFile nif(mName); |         Nif::NIFFile::ptr nif = Nif::NIFFile::create (mName); | ||||||
|         Nif::Node *node = dynamic_cast<Nif::Node*>(nif.getRecord(0)); |         Nif::Node const *node = dynamic_cast<Nif::Node const *>(nif->getRecord(0)); | ||||||
|         findTriShape(mesh, node); |         findTriShape(mesh, node); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1056,7 +1057,8 @@ MeshPairList NIFLoader::load(std::string name, std::string skelName, const std:: | ||||||
|         return meshiter->second; |         return meshiter->second; | ||||||
| 
 | 
 | ||||||
|     MeshPairList &meshes = sMeshPairMap[name+"@skel="+skelName]; |     MeshPairList &meshes = sMeshPairMap[name+"@skel="+skelName]; | ||||||
|     Nif::NIFFile nif(name); |     Nif::NIFFile::ptr pnif = Nif::NIFFile::create (name); | ||||||
|  |     Nif::NIFFile &nif = *pnif.get (); | ||||||
|     if (nif.numRecords() < 1) |     if (nif.numRecords() < 1) | ||||||
|     { |     { | ||||||
|         nif.warn("Found no records in NIF."); |         nif.warn("Found no records in NIF."); | ||||||
|  | @ -1064,10 +1066,10 @@ MeshPairList NIFLoader::load(std::string name, std::string skelName, const std:: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // The first record is assumed to be the root node
 |     // The first record is assumed to be the root node
 | ||||||
|     Nif::Record *r = nif.getRecord(0); |     Nif::Record const *r = nif.getRecord(0); | ||||||
|     assert(r != NULL); |     assert(r != NULL); | ||||||
| 
 | 
 | ||||||
|     Nif::Node *node = dynamic_cast<Nif::Node*>(r); |     Nif::Node const *node = dynamic_cast<Nif::Node const *>(r); | ||||||
|     if(node == NULL) |     if(node == NULL) | ||||||
|     { |     { | ||||||
|         nif.warn("First record in file was not a node, but a "+ |         nif.warn("First record in file was not a node, but a "+ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue