Merge branch 'master' into sdl_input

pull/16/head
Jordan Milne 12 years ago
commit 3fb920a66f

@ -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,
@ -365,6 +362,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));
@ -388,13 +390,8 @@ void OMW::Engine::go()
MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos);
} }
std::cout << "\nPress Q/ESC or close window to exit.\n";
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)
{ {
@ -407,10 +404,31 @@ 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);
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"
@ -103,6 +104,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)) {
ogreRoot.loadPlugin(pluginPath);
return true;
}
else {
#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)) { if (boost::filesystem::exists(pluginPath)) {
ogreRoot.loadPlugin(pluginPath); ogreRoot.loadPlugin(pluginPath);
return true; return true;
} }
else { else {
return false; 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;
} }
typedef boost::shared_ptr <NIFFile> ptr;
/// Open a NIF stream. The name is used for error messages. /// Open a NIF stream. The name is used for error messages.
NIFFile(const std::string &name) NIFFile(const std::string &name, psudo_private_modifier);
: filename(name) ~NIFFile();
{
inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); static ptr create (const std::string &name);
parse(); static void lockCache ();
} static void unlockCache ();
~NIFFile() 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;
@ -711,7 +712,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();
@ -909,18 +910,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())
@ -956,8 +957,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);
} }
@ -1054,7 +1055,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.");
@ -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 // 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…
Cancel
Save