mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Merge remote-tracking branch 'real/master'
This commit is contained in:
commit
7c8b3f1239
22 changed files with 359 additions and 131 deletions
|
@ -240,18 +240,9 @@ void OMW::Engine::setNewGame(bool newGame)
|
|||
mNewGame = newGame;
|
||||
}
|
||||
|
||||
// Initialise and enter main loop.
|
||||
|
||||
void OMW::Engine::go()
|
||||
std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||
{
|
||||
assert (!mCellName.empty());
|
||||
assert (!mMaster.empty());
|
||||
assert (!mOgre);
|
||||
|
||||
mOgre = new OEngine::Render::OgreRenderer;
|
||||
|
||||
// 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 globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg";
|
||||
|
||||
|
@ -272,10 +263,6 @@ void OMW::Engine::go()
|
|||
else if (boost::filesystem::exists(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");
|
||||
|
||||
// load nif overrides
|
||||
|
@ -285,6 +272,13 @@ void OMW::Engine::go()
|
|||
else if (boost::filesystem::exists(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");
|
||||
if (renderSystem == "")
|
||||
{
|
||||
|
@ -294,6 +288,9 @@ void OMW::Engine::go()
|
|||
renderSystem = "OpenGL Rendering Subsystem";
|
||||
#endif
|
||||
}
|
||||
|
||||
mOgre = new OEngine::Render::OgreRenderer;
|
||||
|
||||
mOgre->configure(
|
||||
mCfgMgr.getLogPath().string(),
|
||||
renderSystem,
|
||||
|
@ -328,16 +325,13 @@ void OMW::Engine::go()
|
|||
// cursor replacer (converts the cursor from the bsa so they can be used by mygui)
|
||||
MWGui::CursorReplace replacer;
|
||||
|
||||
// Create encoder
|
||||
ToUTF8::Utf8Encoder encoder (mEncoding);
|
||||
|
||||
// Create the world
|
||||
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
||||
mResDir, mCfgMgr.getCachePath(), mNewGame, &encoder, mFallbackMap,
|
||||
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap,
|
||||
mActivationDistanceOverride));
|
||||
|
||||
//Load translation data
|
||||
mTranslationDataStorage.setEncoder(&encoder);
|
||||
mTranslationDataStorage.setEncoder(mEncoder);
|
||||
mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster);
|
||||
|
||||
// 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));
|
||||
|
||||
// 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,
|
||||
MWBase::Environment::get().getWorld()->getPlayer(),
|
||||
*MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists));
|
||||
|
@ -388,13 +387,8 @@ void OMW::Engine::go()
|
|||
MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos);
|
||||
}
|
||||
|
||||
std::cout << "\nPress Q/ESC or close window to exit.\n";
|
||||
|
||||
mOgre->getRoot()->addFrameListener (this);
|
||||
|
||||
// Play some good 'ol tunes
|
||||
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore"));
|
||||
|
||||
// scripts
|
||||
if (mCompileAll)
|
||||
{
|
||||
|
@ -407,10 +401,35 @@ void OMW::Engine::go()
|
|||
<< "%)"
|
||||
<< 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())
|
||||
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
|
||||
|
||||
std::cout << "\nPress Q/ESC or close window to exit.\n";
|
||||
|
||||
// Start the main rendering loop
|
||||
mOgre->start();
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <components/compiler/extensions.hpp>
|
||||
#include <components/files/collections.hpp>
|
||||
#include <components/translation/translation.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include "mwbase/environment.hpp"
|
||||
|
||||
|
@ -61,6 +62,7 @@ namespace OMW
|
|||
{
|
||||
MWBase::Environment mEnvironment;
|
||||
ToUTF8::FromType mEncoding;
|
||||
ToUTF8::Utf8Encoder* mEncoder;
|
||||
Files::PathContainer mDataDirs;
|
||||
boost::filesystem::path mResDir;
|
||||
OEngine::Render::OgreRenderer *mOgre;
|
||||
|
@ -103,6 +105,12 @@ namespace OMW
|
|||
|
||||
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:
|
||||
Engine(Files::ConfigurationManager& configurationManager);
|
||||
virtual ~Engine();
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/actioneat.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
|
@ -154,6 +157,10 @@ namespace MWClass
|
|||
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;
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
|
@ -163,6 +170,12 @@ namespace MWClass
|
|||
params.mEffectID = ref->mBase->mData.mEffectID[i];
|
||||
params.mAttribute = ref->mBase->mData.mAttributes[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);
|
||||
}
|
||||
info.effects = list;
|
||||
|
|
|
@ -440,7 +440,7 @@ namespace MWGui
|
|||
|
||||
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
spellList.push_back(*it);
|
||||
spellList.push_back (it->first);
|
||||
}
|
||||
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
|
|
|
@ -98,19 +98,19 @@ namespace MWGui
|
|||
|
||||
MWMechanics::Spells& playerSpells = MWWorld::Class::get (player).getCreatureStats (player).getSpells();
|
||||
MWMechanics::Spells& merchantSpells = MWWorld::Class::get (actor).getCreatureStats (actor).getSpells();
|
||||
|
||||
|
||||
for (MWMechanics::Spells::TIterator iter = merchantSpells.begin(); iter!=merchantSpells.end(); ++iter)
|
||||
{
|
||||
const ESM::Spell* spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (*iter);
|
||||
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
|
||||
|
||||
if (spell->mData.mType!=ESM::Spell::ST_Spell)
|
||||
continue; // don't try to sell diseases, curses or powers
|
||||
|
||||
|
||||
if (std::find (playerSpells.begin(), playerSpells.end(), *iter)!=playerSpells.end())
|
||||
continue; // we have that spell already
|
||||
|
||||
addSpell (*iter);
|
||||
|
||||
addSpell (iter->first);
|
||||
}
|
||||
|
||||
updateLabels();
|
||||
|
|
|
@ -436,7 +436,7 @@ namespace MWGui
|
|||
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
const ESM::Spell* spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(*it);
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (it->first);
|
||||
|
||||
// only normal spells count
|
||||
if (spell->mData.mType != ESM::Spell::ST_Spell)
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace MWGui
|
|||
|
||||
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||
{
|
||||
spellList.push_back(*it);
|
||||
spellList.push_back (it->first);
|
||||
}
|
||||
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
|
|
|
@ -390,8 +390,13 @@ void MWSpellEffect::setSpellEffect(const SpellEffectParams& params)
|
|||
|
||||
void MWSpellEffect::updateWidgets()
|
||||
{
|
||||
if (!mWindowManager)
|
||||
if (!mEffectParams.mKnown)
|
||||
{
|
||||
mTextWidget->setCaption ("?");
|
||||
mRequestedWidth = mTextWidget->getTextSize().width + 24;
|
||||
mImageWidget->setImageTexture ("");
|
||||
return;
|
||||
}
|
||||
|
||||
const MWWorld::ESMStore &store =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
|
@ -400,7 +405,6 @@ void MWSpellEffect::updateWidgets()
|
|||
store.get<ESM::MagicEffect>().search(mEffectParams.mEffectID);
|
||||
|
||||
assert(magicEffect);
|
||||
assert(mWindowManager);
|
||||
|
||||
std::string pt = mWindowManager->getGameSettingString("spoint", "");
|
||||
std::string pts = mWindowManager->getGameSettingString("spoints", "");
|
||||
|
|
|
@ -37,12 +37,15 @@ namespace MWGui
|
|||
, mEffectID(-1)
|
||||
, mNoTarget(false)
|
||||
, mIsConstant(false)
|
||||
, mKnown(true)
|
||||
{
|
||||
}
|
||||
|
||||
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 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
|
||||
short mEffectID;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void MagicEffects::add (const ESM::EffectList& list)
|
||||
void MagicEffects::add (const ESM::EffectList& list, float magnitude)
|
||||
{
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (list.mList.begin()); iter!=list.mList.end();
|
||||
++iter)
|
||||
|
@ -78,9 +78,13 @@ namespace MWMechanics
|
|||
if (iter->mMagnMin>=iter->mMagnMax)
|
||||
param.mMagnitude = iter->mMagnMin;
|
||||
else
|
||||
{
|
||||
if (magnitude==-1)
|
||||
magnitude = static_cast<float> (std::rand()) / RAND_MAX;
|
||||
|
||||
param.mMagnitude = static_cast<int> (
|
||||
(iter->mMagnMax-iter->mMagnMin+1)*
|
||||
(static_cast<float> (std::rand()) / RAND_MAX) + iter->mMagnMin);
|
||||
(iter->mMagnMax-iter->mMagnMin+1)*magnitude + iter->mMagnMin);
|
||||
}
|
||||
|
||||
add (*iter, param);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,8 @@ namespace MWMechanics
|
|||
|
||||
void add (const EffectKey& key, const EffectParam& param);
|
||||
|
||||
void add (const ESM::EffectList& list);
|
||||
void add (const ESM::EffectList& list, float magnitude = -1);
|
||||
///< \param magnitude normalised magnitude (-1: random)
|
||||
|
||||
MagicEffects& operator+= (const MagicEffects& effects);
|
||||
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
|
||||
#include "spells.hpp"
|
||||
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
#include <components/esm/loadspel.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include "magiceffects.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const
|
||||
{
|
||||
effects.add (spell->mEffects);
|
||||
}
|
||||
|
||||
Spells::TIterator Spells::begin() const
|
||||
{
|
||||
return mSpells.begin();
|
||||
|
@ -29,13 +26,13 @@ namespace MWMechanics
|
|||
|
||||
void Spells::add (const std::string& spellId)
|
||||
{
|
||||
if (std::find (mSpells.begin(), mSpells.end(), spellId)==mSpells.end())
|
||||
mSpells.push_back (spellId);
|
||||
if (mSpells.find (spellId)==mSpells.end())
|
||||
mSpells.insert (std::make_pair (spellId, static_cast<float> (std::rand()) / RAND_MAX));
|
||||
}
|
||||
|
||||
void Spells::remove (const std::string& spellId)
|
||||
{
|
||||
TContainer::iterator iter = std::find (mSpells.begin(), mSpells.end(), spellId);
|
||||
TContainer::iterator iter = mSpells.find (spellId);
|
||||
|
||||
if (iter!=mSpells.end())
|
||||
mSpells.erase (iter);
|
||||
|
@ -51,11 +48,11 @@ namespace MWMechanics
|
|||
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
|
||||
{
|
||||
const ESM::Spell *spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (*iter);
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
|
||||
|
||||
if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight ||
|
||||
spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse)
|
||||
addSpell (spell, effects);
|
||||
effects.add (spell->mEffects, iter->second);
|
||||
}
|
||||
|
||||
return effects;
|
||||
|
@ -75,18 +72,18 @@ namespace MWMechanics
|
|||
{
|
||||
return mSelectedSpell;
|
||||
}
|
||||
|
||||
|
||||
bool Spells::hasCommonDisease() const
|
||||
{
|
||||
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
|
||||
{
|
||||
const ESM::Spell *spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (*iter);
|
||||
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
|
||||
|
||||
if (spell->mData.mFlags & ESM::Spell::ST_Disease)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -95,12 +92,12 @@ namespace MWMechanics
|
|||
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
|
||||
{
|
||||
const ESM::Spell *spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (*iter);
|
||||
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find (iter->first);
|
||||
|
||||
if (spell->mData.mFlags & ESM::Spell::ST_Blight)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef GAME_MWMECHANICS_SPELLS_H
|
||||
#define GAME_MWMECHANICS_SPELLS_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
|
@ -21,16 +21,14 @@ namespace MWMechanics
|
|||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<std::string> TContainer;
|
||||
typedef std::map<std::string, float> TContainer; // ID, normalised magnitude
|
||||
typedef TContainer::const_iterator TIterator;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> mSpells;
|
||||
TContainer mSpells;
|
||||
std::string mSelectedSpell;
|
||||
|
||||
void addSpell (const ESM::Spell *, MagicEffects& effects) const;
|
||||
|
||||
public:
|
||||
|
||||
TIterator begin() const;
|
||||
|
@ -55,10 +53,10 @@ namespace MWMechanics
|
|||
|
||||
const std::string getSelectedSpell() const;
|
||||
///< May return an empty string.
|
||||
|
||||
|
||||
bool hasCommonDisease() const;
|
||||
|
||||
bool hasBlightDisease() const;
|
||||
bool hasBlightDisease() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -485,7 +485,7 @@ namespace MWScript
|
|||
for (MWMechanics::Spells::TIterator iter (
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).getSpells().begin());
|
||||
iter!=MWWorld::Class::get (ptr).getCreatureStats (ptr).getSpells().end(); ++iter)
|
||||
if (*iter==id)
|
||||
if (iter->first==id)
|
||||
{
|
||||
value = 1;
|
||||
break;
|
||||
|
@ -1188,7 +1188,7 @@ namespace MWScript
|
|||
extensions.registerFunction ("getpccrimelevel", 'f', "", opcodeGetPCCrimeLevel);
|
||||
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
|
||||
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);
|
||||
|
||||
|
||||
extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit);
|
||||
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
|
||||
opcodeRemoveSpellExplicit);
|
||||
|
@ -1286,7 +1286,7 @@ namespace MWScript
|
|||
interpreter.installSegment5 (opcodeGetPCCrimeLevel, new OpGetPCCrimeLevel);
|
||||
interpreter.installSegment5 (opcodeSetPCCrimeLevel, new OpSetPCCrimeLevel);
|
||||
interpreter.installSegment5 (opcodeModPCCrimeLevel, new OpModPCCrimeLevel);
|
||||
|
||||
|
||||
interpreter.installSegment5 (opcodeAddSpell, new OpAddSpell<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeAddSpellExplicit, new OpAddSpell<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>);
|
||||
|
|
|
@ -172,6 +172,8 @@ namespace MWWorld
|
|||
|
||||
void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
|
||||
{
|
||||
Nif::NIFFile::CacheLock cachelock;
|
||||
|
||||
mRendering.preCellChange(mCurrentCell);
|
||||
|
||||
// remove active
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
namespace Files {
|
||||
|
||||
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
|
||||
std::ostringstream verStream;
|
||||
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";
|
||||
#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)) {
|
||||
ogreRoot.loadPlugin(pluginPath);
|
||||
return true;
|
||||
ogreRoot.loadPlugin(pluginPath);
|
||||
return true;
|
||||
}
|
||||
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,161 @@
|
|||
#include "controller.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
//TODO: when threading is needed, enable these
|
||||
//#include <boost/mutex.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Nif;
|
||||
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();
|
||||
// Make sure to close the file after it was loaded into memory
|
||||
inp.setNull();
|
||||
}
|
||||
|
||||
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
|
||||
where we stash all the functions we couldn't add as inline
|
||||
definitions in the record types.
|
||||
|
@ -211,14 +362,14 @@ void NiSkinInstance::post(NIFFile *nif)
|
|||
}
|
||||
}
|
||||
|
||||
Ogre::Matrix4 Node::getLocalTransform()
|
||||
Ogre::Matrix4 Node::getLocalTransform() const
|
||||
{
|
||||
Ogre::Matrix4 mat4(Ogre::Matrix4::IDENTITY);
|
||||
mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation));
|
||||
return mat4;
|
||||
}
|
||||
|
||||
Ogre::Matrix4 Node::getWorldTransform()
|
||||
Ogre::Matrix4 Node::getWorldTransform() const
|
||||
{
|
||||
if(parent != NULL)
|
||||
return parent->getWorldTransform() * getLocalTransform();
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#include <vector>
|
||||
#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 "record.hpp"
|
||||
|
@ -93,6 +98,14 @@ class NIFFile
|
|||
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:
|
||||
/// Used for error handling
|
||||
void fail(const std::string &msg)
|
||||
|
@ -108,19 +121,21 @@ public:
|
|||
<< "File: "<<filename <<std::endl;
|
||||
}
|
||||
|
||||
/// Open a NIF stream. The name is used for error messages.
|
||||
NIFFile(const std::string &name)
|
||||
: filename(name)
|
||||
{
|
||||
inp = Ogre::ResourceGroupManager::getSingleton().openResource(name);
|
||||
parse();
|
||||
}
|
||||
typedef boost::shared_ptr <NIFFile> ptr;
|
||||
|
||||
~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++)
|
||||
delete records[i];
|
||||
}
|
||||
CacheLock () { lockCache (); }
|
||||
~CacheLock () { unlockCache (); }
|
||||
};
|
||||
|
||||
/// Get a given record
|
||||
Record *getRecord(size_t index)
|
||||
|
|
|
@ -111,8 +111,8 @@ public:
|
|||
boneIndex = ind;
|
||||
}
|
||||
|
||||
Ogre::Matrix4 getLocalTransform();
|
||||
Ogre::Matrix4 getWorldTransform();
|
||||
Ogre::Matrix4 getLocalTransform() const;
|
||||
Ogre::Matrix4 getWorldTransform() const;
|
||||
};
|
||||
|
||||
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);
|
||||
btQuaternion quat;
|
||||
|
@ -62,7 +62,7 @@ btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m)
|
|||
return quat;
|
||||
}
|
||||
|
||||
btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v)
|
||||
btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 const &v)
|
||||
{
|
||||
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
|
||||
// every error as early and intrusively as possible, as it's most
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -164,8 +165,8 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
|
|||
return false;
|
||||
}
|
||||
|
||||
void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
|
||||
const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
|
||||
void ManualBulletShapeLoader::handleNode(Nif::Node const *node, int flags,
|
||||
const Nif::Transformation *parentTrafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
|
||||
{
|
||||
|
||||
// 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
|
||||
Nif::Extra *e = node;
|
||||
Nif::Extra const *e = node;
|
||||
while (!e->extra.empty())
|
||||
{
|
||||
// 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
|
||||
// overwriting it. TODO: Is this necessary?
|
||||
Nif::Transformation &final = node->trafo;
|
||||
|
||||
// For both position and rotation we have that:
|
||||
// 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
|
||||
final.rotation = trafo->rotation * final.rotation;
|
||||
childTrafo.rotation = parentTrafo->rotation * childTrafo.rotation;
|
||||
|
||||
// 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->boxRotation = node->boundRot;
|
||||
|
||||
|
@ -243,20 +244,20 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
|
|||
// For NiNodes, loop through children
|
||||
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();
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -265,12 +266,12 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
|
|||
for (int i=0; i<n; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
assert(shape != NULL);
|
||||
|
|
|
@ -79,25 +79,25 @@ public:
|
|||
void load(const std::string &name,const std::string &group);
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
*Helper function
|
||||
*/
|
||||
bool hasRootCollisionNode(Nif::Node* node);
|
||||
bool hasRootCollisionNode(Nif::Node const * node);
|
||||
|
||||
/**
|
||||
*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 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;
|
||||
if(!skel->hasBone(node->name))
|
||||
|
@ -252,10 +252,11 @@ void loadResource(Ogre::Resource *resource)
|
|||
Ogre::Skeleton *skel = dynamic_cast<Ogre::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));
|
||||
|
||||
std::vector<Nif::NiKeyframeController*> ctrls;
|
||||
std::vector<Nif::NiKeyframeController const*> ctrls;
|
||||
buildBones(skel, node, ctrls);
|
||||
|
||||
std::vector<std::string> targets;
|
||||
|
@ -266,7 +267,7 @@ void loadResource(Ogre::Resource *resource)
|
|||
float maxtime = 0.0f;
|
||||
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);
|
||||
Nif::Named *target = dynamic_cast<Nif::Named*>(ctrl->target.getPtr());
|
||||
if(target != NULL)
|
||||
|
@ -289,8 +290,8 @@ void loadResource(Ogre::Resource *resource)
|
|||
|
||||
for(size_t i = 0;i < ctrls.size();i++)
|
||||
{
|
||||
Nif::NiKeyframeController *kfc = ctrls[i];
|
||||
Nif::NiKeyframeData *kf = kfc->data.getPtr();
|
||||
Nif::NiKeyframeController const *kfc = ctrls[i];
|
||||
Nif::NiKeyframeData const *kf = kfc->data.getPtr();
|
||||
|
||||
/* Get the keyframes and make sure they're sorted first to last */
|
||||
Nif::QuaternionKeyList quatkeys = kf->mRotations;
|
||||
|
@ -711,7 +712,7 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
|
|||
|
||||
|
||||
// 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;
|
||||
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||
|
@ -909,18 +910,18 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
|
|||
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)
|
||||
{
|
||||
handleNiTriShape(mesh, dynamic_cast<Nif::NiTriShape*>(node));
|
||||
handleNiTriShape(mesh, dynamic_cast<Nif::NiTriShape const *>(node));
|
||||
return true;
|
||||
}
|
||||
|
||||
Nif::NiNode *ninode = dynamic_cast<Nif::NiNode*>(node);
|
||||
Nif::NiNode const *ninode = dynamic_cast<Nif::NiNode const *>(node);
|
||||
if(ninode)
|
||||
{
|
||||
Nif::NodeList &children = ninode->children;
|
||||
Nif::NodeList const &children = ninode->children;
|
||||
for(size_t i = 0;i < children.length();i++)
|
||||
{
|
||||
if(!children[i].empty())
|
||||
|
@ -956,8 +957,8 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
Nif::NIFFile nif(mName);
|
||||
Nif::Node *node = dynamic_cast<Nif::Node*>(nif.getRecord(0));
|
||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create (mName);
|
||||
Nif::Node const *node = dynamic_cast<Nif::Node const *>(nif->getRecord(0));
|
||||
findTriShape(mesh, node);
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1055,8 @@ MeshPairList NIFLoader::load(std::string name, std::string skelName, const std::
|
|||
return meshiter->second;
|
||||
|
||||
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)
|
||||
{
|
||||
nif.warn("Found no records in NIF.");
|
||||
|
@ -1062,10 +1064,10 @@ MeshPairList NIFLoader::load(std::string name, std::string skelName, const std::
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
|
||||
Nif::Node const *node = dynamic_cast<Nif::Node const *>(r);
|
||||
if(node == NULL)
|
||||
{
|
||||
nif.warn("First record in file was not a node, but a "+
|
||||
|
|
Loading…
Reference in a new issue