forked from teamnwah/openmw-tes3coop
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
d024c1a93f
28 changed files with 242 additions and 208 deletions
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
|
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
|
|
||||||
#include "model/settings/usersettings.hpp"
|
#include "model/settings/usersettings.hpp"
|
||||||
#include "model/doc/documentmanager.hpp"
|
#include "model/doc/documentmanager.hpp"
|
||||||
|
|
||||||
|
@ -37,6 +39,7 @@ namespace CS
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Nif::Cache mNifCache;
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
CSMSettings::UserSettings mUserSettings;
|
CSMSettings::UserSettings mUserSettings;
|
||||||
CSMDoc::DocumentManager mDocumentManager;
|
CSMDoc::DocumentManager mDocumentManager;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <components/bsa/resources.hpp>
|
#include <components/bsa/resources.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/translation/translation.hpp>
|
#include <components/translation/translation.hpp>
|
||||||
#include <components/nif/niffile.hpp>
|
|
||||||
#include <components/nifoverrides/nifoverrides.hpp>
|
#include <components/nifoverrides/nifoverrides.hpp>
|
||||||
|
|
||||||
#include <components/nifbullet/bulletnifloader.hpp>
|
#include <components/nifbullet/bulletnifloader.hpp>
|
||||||
|
@ -315,8 +314,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mEnvironment.setStateManager (
|
mEnvironment.setStateManager (
|
||||||
new MWState::StateManager (mCfgMgr.getUserDataPath() / "saves", mContentFiles.at (0)));
|
new MWState::StateManager (mCfgMgr.getUserDataPath() / "saves", mContentFiles.at (0)));
|
||||||
|
|
||||||
Nif::NIFFile::CacheLock cachelock;
|
|
||||||
|
|
||||||
std::string renderSystem = settings.getString("render system", "Video");
|
std::string renderSystem = settings.getString("render system", "Video");
|
||||||
if (renderSystem == "")
|
if (renderSystem == "")
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#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 <components/settings/settings.hpp>
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "mwbase/environment.hpp"
|
#include "mwbase/environment.hpp"
|
||||||
|
|
||||||
|
@ -94,6 +96,8 @@ namespace OMW
|
||||||
std::vector<std::string> mScriptBlacklist;
|
std::vector<std::string> mScriptBlacklist;
|
||||||
bool mScriptBlacklistUse;
|
bool mScriptBlacklistUse;
|
||||||
|
|
||||||
|
Nif::Cache mNifCache;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
Engine (const Engine&);
|
Engine (const Engine&);
|
||||||
Engine& operator= (const Engine&);
|
Engine& operator= (const Engine&);
|
||||||
|
|
|
@ -37,10 +37,11 @@ namespace MWGui
|
||||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked);
|
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onOkButtonClicked);
|
||||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked);
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onCancelButtonClicked);
|
||||||
mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteButtonClicked);
|
mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SaveGameDialog::onDeleteButtonClicked);
|
||||||
mCharacterSelection->eventComboChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
|
mCharacterSelection->eventComboAccept += MyGUI::newDelegate(this, &SaveGameDialog::onCharacterSelected);
|
||||||
mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected);
|
mSaveList->eventListChangePosition += MyGUI::newDelegate(this, &SaveGameDialog::onSlotSelected);
|
||||||
mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick);
|
mSaveList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SaveGameDialog::onSlotMouseClick);
|
||||||
mSaveList->eventListSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onSlotActivated);
|
mSaveList->eventListSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onSlotActivated);
|
||||||
|
mSaveList->eventKeyButtonPressed += MyGUI::newDelegate(this, &SaveGameDialog::onKeyButtonPressed);
|
||||||
mSaveNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onEditSelectAccept);
|
mSaveNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &SaveGameDialog::onEditSelectAccept);
|
||||||
mSaveNameEdit->eventEditTextChange += MyGUI::newDelegate(this, &SaveGameDialog::onSaveNameChanged);
|
mSaveNameEdit->eventEditTextChange += MyGUI::newDelegate(this, &SaveGameDialog::onSaveNameChanged);
|
||||||
}
|
}
|
||||||
|
@ -247,6 +248,12 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveGameDialog::onKeyButtonPressed(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char character)
|
||||||
|
{
|
||||||
|
if (key == MyGUI::KeyCode::Delete && mCurrentSlot)
|
||||||
|
confirmDeleteSave();
|
||||||
|
}
|
||||||
|
|
||||||
void SaveGameDialog::onOkButtonClicked(MyGUI::Widget *sender)
|
void SaveGameDialog::onOkButtonClicked(MyGUI::Widget *sender)
|
||||||
{
|
{
|
||||||
accept();
|
accept();
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWGui
|
||||||
private:
|
private:
|
||||||
void confirmDeleteSave();
|
void confirmDeleteSave();
|
||||||
|
|
||||||
|
void onKeyButtonPressed(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char character);
|
||||||
void onCancelButtonClicked (MyGUI::Widget* sender);
|
void onCancelButtonClicked (MyGUI::Widget* sender);
|
||||||
void onOkButtonClicked (MyGUI::Widget* sender);
|
void onOkButtonClicked (MyGUI::Widget* sender);
|
||||||
void onDeleteButtonClicked (MyGUI::Widget* sender);
|
void onDeleteButtonClicked (MyGUI::Widget* sender);
|
||||||
|
|
|
@ -32,6 +32,15 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId, bool commanded)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
|
||||||
|
: mAlwaysFollow(follow->mAlwaysFollow), mRemainingDuration(follow->mRemainingDuration)
|
||||||
|
, mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ)
|
||||||
|
, mActorRefId(follow->mTargetId), mActorId(-1), mCellId(follow->mCellId)
|
||||||
|
, mCommanded(follow->mCommanded)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr target = getTarget();
|
MWWorld::Ptr target = getTarget();
|
||||||
|
@ -131,15 +140,6 @@ void MWMechanics::AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) co
|
||||||
sequence.mPackages.push_back(package);
|
sequence.mPackages.push_back(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
|
|
||||||
: mAlwaysFollow(follow->mAlwaysFollow), mRemainingDuration(follow->mRemainingDuration)
|
|
||||||
, mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ)
|
|
||||||
, mActorRefId(follow->mTargetId), mCellId(follow->mCellId)
|
|
||||||
, mCommanded(follow->mCommanded)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MWWorld::Ptr MWMechanics::AiFollow::getTarget()
|
MWWorld::Ptr MWMechanics::AiFollow::getTarget()
|
||||||
{
|
{
|
||||||
if (mActorId == -2)
|
if (mActorId == -2)
|
||||||
|
|
|
@ -32,12 +32,18 @@ AiPursue *MWMechanics::AiPursue::clone() const
|
||||||
}
|
}
|
||||||
bool AiPursue::execute (const MWWorld::Ptr& actor, float duration)
|
bool AiPursue::execute (const MWWorld::Ptr& actor, float duration)
|
||||||
{
|
{
|
||||||
|
if(actor.getClass().getCreatureStats(actor).isDead())
|
||||||
|
return true;
|
||||||
|
|
||||||
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
||||||
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); //The target to follow
|
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); //The target to follow
|
||||||
|
|
||||||
if(target == MWWorld::Ptr())
|
if(target == MWWorld::Ptr())
|
||||||
return true; //Target doesn't exist
|
return true; //Target doesn't exist
|
||||||
|
|
||||||
|
if(target.getClass().getCreatureStats(target).isDead())
|
||||||
|
return true;
|
||||||
|
|
||||||
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
|
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
|
||||||
|
|
||||||
//Set the target desition from the actor
|
//Set the target desition from the actor
|
||||||
|
|
|
@ -1663,6 +1663,9 @@ void CharacterController::updateVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
mAnimation->setAlpha(alpha);
|
mAnimation->setAlpha(alpha);
|
||||||
|
|
||||||
|
float light = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude();
|
||||||
|
mAnimation->setLightEffect(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::determineAttackType()
|
void CharacterController::determineAttackType()
|
||||||
|
@ -1671,9 +1674,9 @@ void CharacterController::determineAttackType()
|
||||||
|
|
||||||
if(mPtr.getClass().hasInventoryStore(mPtr))
|
if(mPtr.getClass().hasInventoryStore(mPtr))
|
||||||
{
|
{
|
||||||
if (move[1]) // forward-backward
|
if (move[1] && !move[0]) // forward-backward
|
||||||
mAttackType = "thrust";
|
mAttackType = "thrust";
|
||||||
else if (move[0]) //sideway
|
else if (move[0] && !move[1]) //sideway
|
||||||
mAttackType = "slash";
|
mAttackType = "slash";
|
||||||
else
|
else
|
||||||
mAttackType = "chop";
|
mAttackType = "chop";
|
||||||
|
|
|
@ -71,6 +71,7 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node)
|
||||||
, mNonAccumCtrl(NULL)
|
, mNonAccumCtrl(NULL)
|
||||||
, mAccumulate(0.0f)
|
, mAccumulate(0.0f)
|
||||||
, mNullAnimationTimePtr(OGRE_NEW NullAnimationTime)
|
, mNullAnimationTimePtr(OGRE_NEW NullAnimationTime)
|
||||||
|
, mGlowLight(NULL)
|
||||||
{
|
{
|
||||||
for(size_t i = 0;i < sNumGroups;i++)
|
for(size_t i = 0;i < sNumGroups;i++)
|
||||||
mAnimationTimePtr[i].bind(OGRE_NEW AnimationTime(this));
|
mAnimationTimePtr[i].bind(OGRE_NEW AnimationTime(this));
|
||||||
|
@ -78,6 +79,8 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node)
|
||||||
|
|
||||||
Animation::~Animation()
|
Animation::~Animation()
|
||||||
{
|
{
|
||||||
|
setLightEffect(0);
|
||||||
|
|
||||||
mEffects.clear();
|
mEffects.clear();
|
||||||
|
|
||||||
mAnimSources.clear();
|
mAnimSources.clear();
|
||||||
|
@ -110,6 +113,11 @@ void Animation::setObjectRoot(const std::string &model, bool baseonly)
|
||||||
|
|
||||||
mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) :
|
mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) :
|
||||||
NifOgre::Loader::createObjectBase(mInsert, mdlname));
|
NifOgre::Loader::createObjectBase(mInsert, mdlname));
|
||||||
|
|
||||||
|
// Fast forward auto-play particles, which will have been set up as Emitting by the loader.
|
||||||
|
for (unsigned int i=0; i<mObjectRoot->mParticles.size(); ++i)
|
||||||
|
mObjectRoot->mParticles[i]->fastForward(1, 0.1);
|
||||||
|
|
||||||
if(mObjectRoot->mSkelBase)
|
if(mObjectRoot->mSkelBase)
|
||||||
{
|
{
|
||||||
mSkelBase = mObjectRoot->mSkelBase;
|
mSkelBase = mObjectRoot->mSkelBase;
|
||||||
|
@ -1194,8 +1202,9 @@ bool Animation::allowSwitchViewMode() const
|
||||||
{
|
{
|
||||||
for (AnimStateMap::const_iterator stateiter = mStates.begin(); stateiter != mStates.end(); ++stateiter)
|
for (AnimStateMap::const_iterator stateiter = mStates.begin(); stateiter != mStates.end(); ++stateiter)
|
||||||
{
|
{
|
||||||
if(stateiter->second.mPriority > MWMechanics::Priority_Movement
|
if((stateiter->second.mPriority > MWMechanics::Priority_Movement
|
||||||
&& stateiter->second.mPriority < MWMechanics::Priority_Torch)
|
&& stateiter->second.mPriority < MWMechanics::Priority_Torch)
|
||||||
|
|| stateiter->second.mPriority == MWMechanics::Priority_Death)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1391,6 +1400,37 @@ Ogre::Vector3 Animation::getEnchantmentColor(MWWorld::Ptr item)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animation::setLightEffect(float effect)
|
||||||
|
{
|
||||||
|
if (effect == 0)
|
||||||
|
{
|
||||||
|
if (mGlowLight)
|
||||||
|
{
|
||||||
|
mInsert->getCreator()->destroySceneNode(mGlowLight->getParentSceneNode());
|
||||||
|
mInsert->getCreator()->destroyLight(mGlowLight);
|
||||||
|
mGlowLight = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!mGlowLight)
|
||||||
|
{
|
||||||
|
mGlowLight = mInsert->getCreator()->createLight();
|
||||||
|
|
||||||
|
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
|
||||||
|
for(size_t i = 0;i < mObjectRoot->mEntities.size();i++)
|
||||||
|
{
|
||||||
|
Ogre::Entity *ent = mObjectRoot->mEntities[i];
|
||||||
|
bounds.merge(ent->getBoundingBox());
|
||||||
|
}
|
||||||
|
mInsert->createChildSceneNode(bounds.getCenter())->attachObject(mGlowLight);
|
||||||
|
}
|
||||||
|
mGlowLight->setType(Ogre::Light::LT_POINT);
|
||||||
|
effect += 3;
|
||||||
|
mGlowLight->setAttenuation(1.0f / (0.03 * (0.5/effect)), 0, 0.5/effect, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
|
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
|
||||||
: Animation(ptr, ptr.getRefData().getBaseNode())
|
: Animation(ptr, ptr.getRefData().getBaseNode())
|
||||||
|
|
|
@ -126,6 +126,8 @@ protected:
|
||||||
|
|
||||||
MWWorld::Ptr mPtr;
|
MWWorld::Ptr mPtr;
|
||||||
|
|
||||||
|
Ogre::Light* mGlowLight;
|
||||||
|
|
||||||
Ogre::SceneNode *mInsert;
|
Ogre::SceneNode *mInsert;
|
||||||
Ogre::Entity *mSkelBase;
|
Ogre::Entity *mSkelBase;
|
||||||
NifOgre::ObjectScenePtr mObjectRoot;
|
NifOgre::ObjectScenePtr mObjectRoot;
|
||||||
|
@ -301,6 +303,11 @@ public:
|
||||||
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
||||||
void updateEffects(float duration);
|
void updateEffects(float duration);
|
||||||
|
|
||||||
|
// TODO: move outside of this class
|
||||||
|
/// Makes this object glow, by placing a Light in its center.
|
||||||
|
/// @param effect Controls the radius and intensity of the light.
|
||||||
|
void setLightEffect(float effect);
|
||||||
|
|
||||||
virtual void showWeapons(bool showWeapon);
|
virtual void showWeapons(bool showWeapon);
|
||||||
virtual void showCarriedLeft(bool show) {}
|
virtual void showCarriedLeft(bool show) {}
|
||||||
virtual void attachArrow() {}
|
virtual void attachArrow() {}
|
||||||
|
|
|
@ -552,6 +552,10 @@ NifOgre::ObjectScenePtr NpcAnimation::insertBoundedPart(const std::string &model
|
||||||
std::for_each(objects->mEntities.begin(), objects->mEntities.end(), SetObjectGroup(group));
|
std::for_each(objects->mEntities.begin(), objects->mEntities.end(), SetObjectGroup(group));
|
||||||
std::for_each(objects->mParticles.begin(), objects->mParticles.end(), SetObjectGroup(group));
|
std::for_each(objects->mParticles.begin(), objects->mParticles.end(), SetObjectGroup(group));
|
||||||
|
|
||||||
|
// Fast forward auto-play particles, which will have been set up as Emitting by the loader.
|
||||||
|
for (unsigned int i=0; i<objects->mParticles.size(); ++i)
|
||||||
|
objects->mParticles[i]->fastForward(1, 0.1);
|
||||||
|
|
||||||
if(objects->mSkelBase)
|
if(objects->mSkelBase)
|
||||||
{
|
{
|
||||||
Ogre::AnimationStateSet *aset = objects->mSkelBase->getAllAnimationStates();
|
Ogre::AnimationStateSet *aset = objects->mSkelBase->getAllAnimationStates();
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "../mwmechanics/spellcasting.hpp"
|
#include "../mwmechanics/spellcasting.hpp"
|
||||||
|
|
||||||
#include "../mwrender/effectmanager.hpp"
|
#include "../mwrender/effectmanager.hpp"
|
||||||
|
#include "../mwrender/animation.hpp"
|
||||||
|
#include "../mwrender/renderconst.hpp"
|
||||||
|
|
||||||
#include "../mwsound/sound.hpp"
|
#include "../mwsound/sound.hpp"
|
||||||
|
|
||||||
|
@ -41,6 +43,9 @@ namespace MWWorld
|
||||||
if(state.mObject->mControllers[i].getSource().isNull())
|
if(state.mObject->mControllers[i].getSource().isNull())
|
||||||
state.mObject->mControllers[i].setSource(Ogre::SharedPtr<MWRender::EffectAnimationTime> (new MWRender::EffectAnimationTime()));
|
state.mObject->mControllers[i].setSource(Ogre::SharedPtr<MWRender::EffectAnimationTime> (new MWRender::EffectAnimationTime()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Misc,
|
||||||
|
MWRender::RQG_Main, MWRender::RQG_Alpha, 0.f, false, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileManager::update(NifOgre::ObjectScenePtr object, float duration)
|
void ProjectileManager::update(NifOgre::ObjectScenePtr object, float duration)
|
||||||
|
|
|
@ -259,8 +259,6 @@ 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;
|
|
||||||
|
|
||||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||||
Loading::ScopedLoad load(loadingListener);
|
Loading::ScopedLoad load(loadingListener);
|
||||||
|
|
||||||
|
@ -408,7 +406,6 @@ namespace MWWorld
|
||||||
if(!loadcell)
|
if(!loadcell)
|
||||||
loadcell = *mCurrentCell != *cell;
|
loadcell = *mCurrentCell != *cell;
|
||||||
|
|
||||||
Nif::NIFFile::CacheLock lock;
|
|
||||||
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
|
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
|
||||||
|
|
||||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||||
|
|
|
@ -22,6 +22,10 @@ add_component_dir (nif
|
||||||
controlled effect niftypes record controller extra node record_ptr data niffile property
|
controlled effect niftypes record controller extra node record_ptr data niffile property
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_component_dir (nifcache
|
||||||
|
nifcache
|
||||||
|
)
|
||||||
|
|
||||||
add_component_dir (nifogre
|
add_component_dir (nifogre
|
||||||
ogrenifloader skeleton material mesh particles controller
|
ogrenifloader skeleton material mesh particles controller
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,143 +35,11 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
//TODO: when threading is needed, enable these
|
|
||||||
//#include <boost/mutex.hpp>
|
|
||||||
#include <boost/thread/locks.hpp>
|
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
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.
|
/// Open a NIF stream. The name is used for error messages.
|
||||||
NIFFile::NIFFile(const std::string &name, psudo_private_modifier)
|
NIFFile::NIFFile(const std::string &name)
|
||||||
: ver(0)
|
: ver(0)
|
||||||
, filename(name)
|
, filename(name)
|
||||||
{
|
{
|
||||||
|
@ -180,8 +48,6 @@ NIFFile::NIFFile(const std::string &name, psudo_private_modifier)
|
||||||
|
|
||||||
NIFFile::~NIFFile()
|
NIFFile::~NIFFile()
|
||||||
{
|
{
|
||||||
LoadedCache::release (this);
|
|
||||||
|
|
||||||
for(std::size_t i=0; i<records.size(); i++)
|
for(std::size_t i=0; i<records.size(); i++)
|
||||||
delete records[i];
|
delete records[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,6 @@ class NIFFile
|
||||||
/// Parse the file
|
/// Parse the file
|
||||||
void parse();
|
void parse();
|
||||||
|
|
||||||
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 &);
|
NIFFile (NIFFile const &);
|
||||||
void operator = (NIFFile const &);
|
void operator = (NIFFile const &);
|
||||||
|
|
||||||
|
@ -96,22 +91,10 @@ 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, psudo_private_modifier);
|
NIFFile(const std::string &name);
|
||||||
~NIFFile();
|
~NIFFile();
|
||||||
|
|
||||||
static ptr create (const std::string &name);
|
|
||||||
static void lockCache ();
|
|
||||||
static void unlockCache ();
|
|
||||||
|
|
||||||
struct CacheLock
|
|
||||||
{
|
|
||||||
CacheLock () { lockCache (); }
|
|
||||||
~CacheLock () { unlockCache (); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Get a given record
|
/// Get a given record
|
||||||
Record *getRecord(size_t index) const
|
Record *getRecord(size_t index) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,8 @@ http://www.gnu.org/licenses/ .
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
|
|
||||||
#include "../nif/niffile.hpp"
|
#include "../nif/niffile.hpp"
|
||||||
#include "../nif/node.hpp"
|
#include "../nif/node.hpp"
|
||||||
#include "../nif/data.hpp"
|
#include "../nif/data.hpp"
|
||||||
|
@ -74,7 +76,7 @@ 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::ptr pnif (Nif::NIFFile::create (mResourceName.substr(0, mResourceName.length()-7)));
|
Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(mResourceName.substr(0, mResourceName.length()-7)));
|
||||||
Nif::NIFFile & nif = *pnif.get ();
|
Nif::NIFFile & nif = *pnif.get ();
|
||||||
if (nif.numRoots() < 1)
|
if (nif.numRoots() < 1)
|
||||||
{
|
{
|
||||||
|
@ -388,7 +390,7 @@ bool findBoundingBox (const Nif::Node* node, Ogre::Vector3& halfExtents, Ogre::V
|
||||||
|
|
||||||
bool getBoundingBox(const std::string& nifFile, Ogre::Vector3& halfExtents, Ogre::Vector3& translation, Ogre::Quaternion& orientation)
|
bool getBoundingBox(const std::string& nifFile, Ogre::Vector3& halfExtents, Ogre::Vector3& translation, Ogre::Quaternion& orientation)
|
||||||
{
|
{
|
||||||
Nif::NIFFile::ptr pnif (Nif::NIFFile::create (nifFile));
|
Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(nifFile));
|
||||||
Nif::NIFFile & nif = *pnif.get ();
|
Nif::NIFFile & nif = *pnif.get ();
|
||||||
|
|
||||||
if (nif.numRoots() < 1)
|
if (nif.numRoots() < 1)
|
||||||
|
|
40
components/nifcache/nifcache.cpp
Normal file
40
components/nifcache/nifcache.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "nifcache.hpp"
|
||||||
|
|
||||||
|
namespace Nif
|
||||||
|
{
|
||||||
|
|
||||||
|
Cache* Cache::sThis = 0;
|
||||||
|
|
||||||
|
Cache& Cache::getInstance()
|
||||||
|
{
|
||||||
|
assert (sThis);
|
||||||
|
return *sThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache* Cache::getInstancePtr()
|
||||||
|
{
|
||||||
|
return sThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache::Cache()
|
||||||
|
{
|
||||||
|
assert (!sThis);
|
||||||
|
sThis = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NIFFilePtr Cache::load(const std::string &filename)
|
||||||
|
{
|
||||||
|
// TODO: normalize file path to make sure we're not loading the same file twice
|
||||||
|
|
||||||
|
LoadedMap::iterator it = mLoadedMap.find(filename);
|
||||||
|
if (it != mLoadedMap.end())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NIFFilePtr file(new Nif::NIFFile(filename));
|
||||||
|
mLoadedMap[filename] = file;
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
components/nifcache/nifcache.hpp
Normal file
48
components/nifcache/nifcache.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_NIFCACHE_H
|
||||||
|
#define OPENMW_COMPONENTS_NIFCACHE_H
|
||||||
|
|
||||||
|
#include <components/nif/niffile.hpp>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
namespace Nif
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Nif::NIFFile> NIFFilePtr;
|
||||||
|
|
||||||
|
/// @brief A basic resource manager for NIF files
|
||||||
|
class Cache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Cache();
|
||||||
|
|
||||||
|
/// Queue this file for background loading. A worker thread will start loading the file.
|
||||||
|
/// To get the loaded NIFFilePtr, use the load method, which will wait until the worker thread is finished
|
||||||
|
/// and then return the loaded file.
|
||||||
|
//void loadInBackground (const std::string& file);
|
||||||
|
|
||||||
|
/// Read and parse the given file. May retrieve from cache if this file has been used previously.
|
||||||
|
/// @note If the file is currently loading in the background, this function will block until
|
||||||
|
/// the background loading finishes, then return the background loaded file.
|
||||||
|
/// @note Returns a SharedPtr to the file and the file will stay loaded as long as the user holds on to this pointer.
|
||||||
|
/// When all external SharedPtrs to a file are released, the cache may decide to unload the file.
|
||||||
|
NIFFilePtr load (const std::string& filename);
|
||||||
|
|
||||||
|
/// Return instance of this class.
|
||||||
|
static Cache& getInstance();
|
||||||
|
static Cache* getInstancePtr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Cache* sThis;
|
||||||
|
|
||||||
|
Cache(const Cache&);
|
||||||
|
Cache& operator =(const Cache&);
|
||||||
|
|
||||||
|
typedef std::map<std::string, NIFFilePtr> LoadedMap;
|
||||||
|
|
||||||
|
LoadedMap mLoadedMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,6 +15,7 @@
|
||||||
#include <OgreKeyFrame.h>
|
#include <OgreKeyFrame.h>
|
||||||
|
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include "material.hpp"
|
#include "material.hpp"
|
||||||
|
@ -383,7 +384,7 @@ void NIFMeshLoader::loadResource(Ogre::Resource *resource)
|
||||||
Ogre::Mesh *mesh = dynamic_cast<Ogre::Mesh*>(resource);
|
Ogre::Mesh *mesh = dynamic_cast<Ogre::Mesh*>(resource);
|
||||||
OgreAssert(mesh, "Attempting to load a mesh into a non-mesh resource!");
|
OgreAssert(mesh, "Attempting to load a mesh into a non-mesh resource!");
|
||||||
|
|
||||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create(mName);
|
Nif::NIFFilePtr nif = Nif::Cache::getInstance().load(mName);
|
||||||
if(mShapeIndex >= nif->numRecords())
|
if(mShapeIndex >= nif->numRecords())
|
||||||
{
|
{
|
||||||
Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
|
Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include <extern/shiny/Main/Factory.hpp>
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
|
||||||
|
@ -390,9 +391,10 @@ public:
|
||||||
class Value : public NodeTargetValue<Ogre::Real>, public ValueInterpolator
|
class Value : public NodeTargetValue<Ogre::Real>, public ValueInterpolator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Nif::QuaternionKeyList mRotations;
|
const Nif::QuaternionKeyList* mRotations;
|
||||||
Nif::Vector3KeyList mTranslations;
|
const Nif::Vector3KeyList* mTranslations;
|
||||||
Nif::FloatKeyList mScales;
|
const Nif::FloatKeyList* mScales;
|
||||||
|
Nif::NIFFilePtr mNif; // Hold a SharedPtr to make sure key lists stay valid
|
||||||
|
|
||||||
using ValueInterpolator::interpKey;
|
using ValueInterpolator::interpKey;
|
||||||
|
|
||||||
|
@ -420,31 +422,33 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value(Ogre::Node *target, const Nif::NiKeyframeData *data)
|
/// @note The NiKeyFrameData must be valid as long as this KeyframeController exists.
|
||||||
|
Value(Ogre::Node *target, const Nif::NIFFilePtr& nif, const Nif::NiKeyframeData *data)
|
||||||
: NodeTargetValue<Ogre::Real>(target)
|
: NodeTargetValue<Ogre::Real>(target)
|
||||||
, mRotations(data->mRotations)
|
, mRotations(&data->mRotations)
|
||||||
, mTranslations(data->mTranslations)
|
, mTranslations(&data->mTranslations)
|
||||||
, mScales(data->mScales)
|
, mScales(&data->mScales)
|
||||||
|
, mNif(nif)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual Ogre::Quaternion getRotation(float time) const
|
virtual Ogre::Quaternion getRotation(float time) const
|
||||||
{
|
{
|
||||||
if(mRotations.mKeys.size() > 0)
|
if(mRotations->mKeys.size() > 0)
|
||||||
return interpKey(mRotations.mKeys, time);
|
return interpKey(mRotations->mKeys, time);
|
||||||
return mNode->getOrientation();
|
return mNode->getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Ogre::Vector3 getTranslation(float time) const
|
virtual Ogre::Vector3 getTranslation(float time) const
|
||||||
{
|
{
|
||||||
if(mTranslations.mKeys.size() > 0)
|
if(mTranslations->mKeys.size() > 0)
|
||||||
return interpKey(mTranslations.mKeys, time);
|
return interpKey(mTranslations->mKeys, time);
|
||||||
return mNode->getPosition();
|
return mNode->getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Ogre::Vector3 getScale(float time) const
|
virtual Ogre::Vector3 getScale(float time) const
|
||||||
{
|
{
|
||||||
if(mScales.mKeys.size() > 0)
|
if(mScales->mKeys.size() > 0)
|
||||||
return Ogre::Vector3(interpKey(mScales.mKeys, time));
|
return Ogre::Vector3(interpKey(mScales->mKeys, time));
|
||||||
return mNode->getScale();
|
return mNode->getScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,12 +460,12 @@ public:
|
||||||
|
|
||||||
virtual void setValue(Ogre::Real time)
|
virtual void setValue(Ogre::Real time)
|
||||||
{
|
{
|
||||||
if(mRotations.mKeys.size() > 0)
|
if(mRotations->mKeys.size() > 0)
|
||||||
mNode->setOrientation(interpKey(mRotations.mKeys, time));
|
mNode->setOrientation(interpKey(mRotations->mKeys, time));
|
||||||
if(mTranslations.mKeys.size() > 0)
|
if(mTranslations->mKeys.size() > 0)
|
||||||
mNode->setPosition(interpKey(mTranslations.mKeys, time));
|
mNode->setPosition(interpKey(mTranslations->mKeys, time));
|
||||||
if(mScales.mKeys.size() > 0)
|
if(mScales->mKeys.size() > 0)
|
||||||
mNode->setScale(Ogre::Vector3(interpKey(mScales.mKeys, time)));
|
mNode->setScale(Ogre::Vector3(interpKey(mScales->mKeys, time)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -916,8 +920,10 @@ class NIFObjectLoader
|
||||||
|
|
||||||
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
||||||
|
|
||||||
if (partflags&Nif::NiNode::ParticleFlag_AutoPlay)
|
// Emitting state will be overwritten on frame update by the ParticleSystemController,
|
||||||
partsys->fastForward(1, 0.1);
|
// but set up an initial value anyway so the user can fast-forward particle systems
|
||||||
|
// immediately after creation if desired.
|
||||||
|
partsys->setEmitting(partflags&Nif::NiNode::ParticleFlag_AutoPlay);
|
||||||
}
|
}
|
||||||
ctrl = ctrl->next;
|
ctrl = ctrl->next;
|
||||||
}
|
}
|
||||||
|
@ -929,7 +935,7 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags)
|
static void createNodeControllers(const Nif::NIFFilePtr& nif, const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
if (ctrl->flags & Nif::NiNode::ControllerFlag_Active)
|
if (ctrl->flags & Nif::NiNode::ControllerFlag_Active)
|
||||||
|
@ -963,7 +969,7 @@ class NIFObjectLoader
|
||||||
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
||||||
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
||||||
Ogre::ControllerValueRealPtr());
|
Ogre::ControllerValueRealPtr());
|
||||||
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, nif, key->data.getPtr()));
|
||||||
KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
||||||
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
||||||
Ogre::ControllerFunctionRealPtr func(function);
|
Ogre::ControllerFunctionRealPtr func(function);
|
||||||
|
@ -1016,7 +1022,7 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createObjects(const std::string &name, const std::string &group,
|
static void createObjects(const Nif::NIFFilePtr& nif, const std::string &name, const std::string &group,
|
||||||
Ogre::SceneNode *sceneNode, const Nif::Node *node,
|
Ogre::SceneNode *sceneNode, const Nif::Node *node,
|
||||||
ObjectScenePtr scene, int flags, int animflags, int partflags)
|
ObjectScenePtr scene, int flags, int animflags, int partflags)
|
||||||
{
|
{
|
||||||
|
@ -1073,7 +1079,7 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!node->controller.empty())
|
if(!node->controller.empty())
|
||||||
createNodeControllers(name, node->controller, scene, animflags);
|
createNodeControllers(nif, name, node->controller, scene, animflags);
|
||||||
|
|
||||||
if(node->recType == Nif::RC_NiCamera)
|
if(node->recType == Nif::RC_NiCamera)
|
||||||
{
|
{
|
||||||
|
@ -1098,7 +1104,7 @@ class NIFObjectLoader
|
||||||
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())
|
||||||
createObjects(name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags);
|
createObjects(nif, name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1127,7 @@ class NIFObjectLoader
|
||||||
public:
|
public:
|
||||||
static void load(Ogre::SceneNode *sceneNode, ObjectScenePtr scene, const std::string &name, const std::string &group, int flags=0)
|
static void load(Ogre::SceneNode *sceneNode, ObjectScenePtr scene, const std::string &name, const std::string &group, int flags=0)
|
||||||
{
|
{
|
||||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
Nif::NIFFilePtr nif = Nif::Cache::getInstance().load(name);
|
||||||
if(nif->numRoots() < 1)
|
if(nif->numRoots() < 1)
|
||||||
{
|
{
|
||||||
nif->warn("Found no root nodes in "+name+".");
|
nif->warn("Found no root nodes in "+name+".");
|
||||||
|
@ -1145,13 +1151,13 @@ public:
|
||||||
// Create a base skeleton entity if this NIF needs one
|
// Create a base skeleton entity if this NIF needs one
|
||||||
createSkelBase(name, group, sceneNode->getCreator(), node, scene);
|
createSkelBase(name, group, sceneNode->getCreator(), node, scene);
|
||||||
}
|
}
|
||||||
createObjects(name, group, sceneNode, node, scene, flags, 0, 0);
|
createObjects(nif, name, group, sceneNode, node, scene, flags, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadKf(Ogre::Skeleton *skel, const std::string &name,
|
static void loadKf(Ogre::Skeleton *skel, const std::string &name,
|
||||||
TextKeyMap &textKeys, std::vector<Ogre::Controller<Ogre::Real> > &ctrls)
|
TextKeyMap &textKeys, std::vector<Ogre::Controller<Ogre::Real> > &ctrls)
|
||||||
{
|
{
|
||||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
Nif::NIFFilePtr nif = Nif::Cache::getInstance().load(name);
|
||||||
if(nif->numRoots() < 1)
|
if(nif->numRoots() < 1)
|
||||||
{
|
{
|
||||||
nif->warn("Found no root nodes in "+name+".");
|
nif->warn("Found no root nodes in "+name+".");
|
||||||
|
@ -1202,7 +1208,7 @@ public:
|
||||||
|
|
||||||
Ogre::Bone *trgtbone = skel->getBone(strdata->string);
|
Ogre::Bone *trgtbone = skel->getBone(strdata->string);
|
||||||
Ogre::ControllerValueRealPtr srcval;
|
Ogre::ControllerValueRealPtr srcval;
|
||||||
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, nif, key->data.getPtr()));
|
||||||
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, false));
|
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, false));
|
||||||
|
|
||||||
ctrls.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
ctrls.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <OgreBone.h>
|
#include <OgreBone.h>
|
||||||
|
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
|
#include <components/nifcache/nifcache.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
namespace NifOgre
|
namespace NifOgre
|
||||||
|
@ -83,7 +84,7 @@ void NIFSkeletonLoader::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::ptr nif(Nif::NIFFile::create(skel->getName()));
|
Nif::NIFFilePtr nif(Nif::Cache::getInstance().load(skel->getName()));
|
||||||
const Nif::Node *node = static_cast<const Nif::Node*>(nif->getRoot(0));
|
const Nif::Node *node = static_cast<const Nif::Node*>(nif->getRoot(0));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
2
extern/shiny/Main/Factory.cpp
vendored
2
extern/shiny/Main/Factory.cpp
vendored
|
@ -803,7 +803,7 @@ namespace sh
|
||||||
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
||||||
{
|
{
|
||||||
if (it->second.getMaterial()->isUnreferenced())
|
if (it->second.getMaterial()->isUnreferenced())
|
||||||
it->second.destroyAll();
|
it->second.getMaterial()->unreferenceTextures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
extern/shiny/Main/Platform.hpp
vendored
1
extern/shiny/Main/Platform.hpp
vendored
|
@ -69,6 +69,7 @@ namespace sh
|
||||||
virtual void removeAll () = 0; ///< remove all configurations
|
virtual void removeAll () = 0; ///< remove all configurations
|
||||||
|
|
||||||
virtual bool isUnreferenced() = 0;
|
virtual bool isUnreferenced() = 0;
|
||||||
|
virtual void unreferenceTextures() = 0;
|
||||||
virtual void ensureLoaded() = 0;
|
virtual void ensureLoaded() = 0;
|
||||||
|
|
||||||
virtual void setLodLevels (const std::string& lodLevels) = 0;
|
virtual void setLodLevels (const std::string& lodLevels) = 0;
|
||||||
|
|
5
extern/shiny/Platforms/Ogre/OgreMaterial.cpp
vendored
5
extern/shiny/Platforms/Ogre/OgreMaterial.cpp
vendored
|
@ -35,6 +35,11 @@ namespace sh
|
||||||
return (!mMaterial.isNull() && mMaterial.useCount() <= Ogre::ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS+1);
|
return (!mMaterial.isNull() && mMaterial.useCount() <= Ogre::ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OgreMaterial::unreferenceTextures()
|
||||||
|
{
|
||||||
|
mMaterial->unload();
|
||||||
|
}
|
||||||
|
|
||||||
OgreMaterial::~OgreMaterial()
|
OgreMaterial::~OgreMaterial()
|
||||||
{
|
{
|
||||||
if (!mMaterial.isNull())
|
if (!mMaterial.isNull())
|
||||||
|
|
1
extern/shiny/Platforms/Ogre/OgreMaterial.hpp
vendored
1
extern/shiny/Platforms/Ogre/OgreMaterial.hpp
vendored
|
@ -19,6 +19,7 @@ namespace sh
|
||||||
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex);
|
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex);
|
||||||
|
|
||||||
virtual bool isUnreferenced();
|
virtual bool isUnreferenced();
|
||||||
|
virtual void unreferenceTextures();
|
||||||
virtual void ensureLoaded();
|
virtual void ensureLoaded();
|
||||||
|
|
||||||
virtual void removeAll ();
|
virtual void removeAll ();
|
||||||
|
|
|
@ -113,7 +113,7 @@
|
||||||
<State name="disabled" colour="0.70 0.57 0.33" shift="0"/>
|
<State name="disabled" colour="0.70 0.57 0.33" shift="0"/>
|
||||||
<State name="normal" colour="0.70 0.57 0.33" shift="0"/>
|
<State name="normal" colour="0.70 0.57 0.33" shift="0"/>
|
||||||
<State name="highlighted" colour="0.85 0.76 0.60" shift="0"/>
|
<State name="highlighted" colour="0.85 0.76 0.60" shift="0"/>
|
||||||
<State name="pushed" colour="0.33 0.38 0.67" shift="0"/>
|
<State name="pushed" colour="1 1 1" shift="0"/>
|
||||||
<State name="disabled_checked" colour="0.33 0.38 0.67" shift="0"/>
|
<State name="disabled_checked" colour="0.33 0.38 0.67" shift="0"/>
|
||||||
<State name="normal_checked" colour="0.33 0.38 0.67" shift="0"/>
|
<State name="normal_checked" colour="0.33 0.38 0.67" shift="0"/>
|
||||||
<State name="highlighted_checked" colour="0.33 0.38 0.67" shift="0"/>
|
<State name="highlighted_checked" colour="0.33 0.38 0.67" shift="0"/>
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace Render
|
||||||
void SelectionBuffer::setupRenderTarget()
|
void SelectionBuffer::setupRenderTarget()
|
||||||
{
|
{
|
||||||
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
|
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
|
||||||
|
mRenderTarget->removeAllViewports();
|
||||||
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
|
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
|
||||||
vp->setOverlaysEnabled(false);
|
vp->setOverlaysEnabled(false);
|
||||||
vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
|
vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
|
||||||
|
@ -65,6 +66,7 @@ namespace Render
|
||||||
{
|
{
|
||||||
Ogre::MaterialManager::getSingleton ().addListener (this);
|
Ogre::MaterialManager::getSingleton ().addListener (this);
|
||||||
|
|
||||||
|
mTexture->load();
|
||||||
if (mRenderTarget == NULL)
|
if (mRenderTarget == NULL)
|
||||||
setupRenderTarget();
|
setupRenderTarget();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue