mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-08-03 07:16:31 -04:00
This commit is contained in:
parent
5c94e2324f
commit
11565b5966
@ -23,7 +23,7 @@ add_openmw_dir (mwrender
|
|||||||
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
|
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
|
||||||
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
|
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
|
||||||
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
|
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
|
||||||
renderbin
|
renderbin actoranimation
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
155
apps/openmw/mwrender/actoranimation.cpp
Normal file
155
apps/openmw/mwrender/actoranimation.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "actoranimation.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osg/Vec4f>
|
||||||
|
|
||||||
|
#include <components/esm/loadligh.hpp>
|
||||||
|
#include <components/esm/loadcell.hpp>
|
||||||
|
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
#include <components/sceneutil/lightutil.hpp>
|
||||||
|
|
||||||
|
#include <components/fallback/fallback.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
|
#include "vismask.hpp"
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||||
|
bool disableListener)
|
||||||
|
: Animation(ptr, parentNode, resourceSystem),
|
||||||
|
mListenerDisabled(disableListener)
|
||||||
|
{
|
||||||
|
MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr);
|
||||||
|
|
||||||
|
for (MWWorld::ContainerStoreIterator iter = store.begin(MWWorld::ContainerStore::Type_Light); iter != store.end(); ++iter)
|
||||||
|
{
|
||||||
|
const ESM::Light* light = iter->get<ESM::Light>()->mBase;
|
||||||
|
if (!(light->mData.mFlags & ESM::Light::Carry))
|
||||||
|
{
|
||||||
|
addHiddenItemLight(*iter, light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mListenerDisabled)
|
||||||
|
store.setContListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ActorAnimation::~ActorAnimation()
|
||||||
|
{
|
||||||
|
if (!mListenerDisabled && mPtr.getRefData().getCustomData() && mPtr.getClass().getContainerStore(mPtr).getContListener() == this)
|
||||||
|
mPtr.getClass().getContainerStore(mPtr).setContListener(NULL);
|
||||||
|
|
||||||
|
for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter)
|
||||||
|
{
|
||||||
|
mInsert->removeChild(iter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorAnimation::itemAdded(const MWWorld::ConstPtr& item, int /*count*/)
|
||||||
|
{
|
||||||
|
if (item.getTypeName() == typeid(ESM::Light).name())
|
||||||
|
{
|
||||||
|
const ESM::Light* light = item.get<ESM::Light>()->mBase;
|
||||||
|
if (!(light->mData.mFlags & ESM::Light::Carry))
|
||||||
|
{
|
||||||
|
addHiddenItemLight(item, light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorAnimation::itemRemoved(const MWWorld::ConstPtr& item, int /*count*/)
|
||||||
|
{
|
||||||
|
if (item.getTypeName() == typeid(ESM::Light).name())
|
||||||
|
{
|
||||||
|
ItemLightMap::iterator iter = mItemLights.find(item);
|
||||||
|
if (iter != mItemLights.end())
|
||||||
|
{
|
||||||
|
if (!item.getRefData().getCount())
|
||||||
|
{
|
||||||
|
removeHiddenItemLight(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorAnimation::objectRootReset()
|
||||||
|
{
|
||||||
|
if (SceneUtil::LightListCallback* callback = findLightListCallback())
|
||||||
|
{
|
||||||
|
for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter)
|
||||||
|
{
|
||||||
|
callback->getIgnoredLightSources().insert(iter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight)
|
||||||
|
{
|
||||||
|
if (mItemLights.find(item) != mItemLights.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Fallback::Map* fallback = MWBase::Environment::get().getWorld()->getFallback();
|
||||||
|
static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
|
||||||
|
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
|
||||||
|
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
|
||||||
|
static float quadraticRadiusMult = fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
|
||||||
|
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
|
||||||
|
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
|
||||||
|
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
|
||||||
|
bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior();
|
||||||
|
|
||||||
|
osg::Vec4f ambient(1,1,1,1);
|
||||||
|
osg::ref_ptr<SceneUtil::LightSource> lightSource = SceneUtil::createLightSource(esmLight, Mask_Lighting, exterior, outQuadInLin,
|
||||||
|
useQuadratic, quadraticValue, quadraticRadiusMult, useLinear, linearRadiusMult, linearValue, ambient);
|
||||||
|
|
||||||
|
mInsert->addChild(lightSource);
|
||||||
|
|
||||||
|
if (SceneUtil::LightListCallback* callback = findLightListCallback())
|
||||||
|
callback->getIgnoredLightSources().insert(lightSource.get());
|
||||||
|
|
||||||
|
mItemLights.insert(std::make_pair(item, lightSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorAnimation::removeHiddenItemLight(const MWWorld::ConstPtr& item)
|
||||||
|
{
|
||||||
|
ItemLightMap::iterator iter = mItemLights.find(item);
|
||||||
|
if (iter == mItemLights.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SceneUtil::LightListCallback* callback = findLightListCallback())
|
||||||
|
{
|
||||||
|
std::set<SceneUtil::LightSource*>::iterator ignoredIter = callback->getIgnoredLightSources().find(iter->second.get());
|
||||||
|
if (ignoredIter != callback->getIgnoredLightSources().end())
|
||||||
|
callback->getIgnoredLightSources().erase(ignoredIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
mInsert->removeChild(iter->second);
|
||||||
|
mItemLights.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneUtil::LightListCallback* ActorAnimation::findLightListCallback()
|
||||||
|
{
|
||||||
|
if (osg::Callback* callback = mObjectRoot->getCullCallback())
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (SceneUtil::LightListCallback* lightListCallback = dynamic_cast<SceneUtil::LightListCallback *>(callback))
|
||||||
|
return lightListCallback;
|
||||||
|
}
|
||||||
|
while ((callback = callback->getNestedCallback()));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
apps/openmw/mwrender/actoranimation.hpp
Normal file
58
apps/openmw/mwrender/actoranimation.hpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef GAME_RENDER_ACTORANIMATION_H
|
||||||
|
#define GAME_RENDER_ACTORANIMATION_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
|
#include "animation.hpp"
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
class Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class ConstPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
class LightSource;
|
||||||
|
class LightListCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||||
|
bool disableListener=false);
|
||||||
|
virtual ~ActorAnimation();
|
||||||
|
|
||||||
|
virtual void itemAdded(const MWWorld::ConstPtr& item, int count);
|
||||||
|
virtual void itemRemoved(const MWWorld::ConstPtr& item, int count);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void objectRootReset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight);
|
||||||
|
void removeHiddenItemLight(const MWWorld::ConstPtr& item);
|
||||||
|
|
||||||
|
SceneUtil::LightListCallback* findLightListCallback();
|
||||||
|
|
||||||
|
typedef std::map<MWWorld::ConstPtr, osg::ref_ptr<SceneUtil::LightSource> > ItemLightMap;
|
||||||
|
ItemLightMap mItemLights;
|
||||||
|
|
||||||
|
bool mListenerDisabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1151,6 +1151,8 @@ namespace MWRender
|
|||||||
}
|
}
|
||||||
|
|
||||||
mObjectRoot->addCullCallback(new SceneUtil::LightListCallback);
|
mObjectRoot->addCullCallback(new SceneUtil::LightListCallback);
|
||||||
|
|
||||||
|
objectRootReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Group* Animation::getObjectRoot()
|
osg::Group* Animation::getObjectRoot()
|
||||||
|
@ -307,6 +307,8 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature);
|
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature);
|
||||||
|
|
||||||
|
virtual void objectRootReset() {}
|
||||||
|
|
||||||
/** Adds the keyframe controllers in the specified model as a new animation source. Note that the .nif
|
/** Adds the keyframe controllers in the specified model as a new animation source. Note that the .nif
|
||||||
* file extension will be replaced with .kf.
|
* file extension will be replaced with .kf.
|
||||||
* @note Later added animation sources have the highest priority when it comes to finding a particular animation.
|
* @note Later added animation sources have the highest priority when it comes to finding a particular animation.
|
||||||
|
@ -18,7 +18,7 @@ namespace MWRender
|
|||||||
|
|
||||||
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr,
|
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr,
|
||||||
const std::string& model, Resource::ResourceSystem* resourceSystem)
|
const std::string& model, Resource::ResourceSystem* resourceSystem)
|
||||||
: Animation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), resourceSystem)
|
: ActorAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), resourceSystem)
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>();
|
MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>();
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr,
|
|||||||
|
|
||||||
|
|
||||||
CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem)
|
CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem)
|
||||||
: Animation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), resourceSystem)
|
: ActorAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), resourceSystem)
|
||||||
, mShowWeapons(false)
|
, mShowWeapons(false)
|
||||||
, mShowCarriedLeft(false)
|
, mShowCarriedLeft(false)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const
|
|||||||
addAnimSource("meshes\\xbase_anim.nif");
|
addAnimSource("meshes\\xbase_anim.nif");
|
||||||
addAnimSource(model);
|
addAnimSource(model);
|
||||||
|
|
||||||
mPtr.getClass().getInventoryStore(mPtr).setListener(this, mPtr);
|
mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr);
|
||||||
|
|
||||||
updateParts();
|
updateParts();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef GAME_RENDER_CREATUREANIMATION_H
|
#ifndef GAME_RENDER_CREATUREANIMATION_H
|
||||||
#define GAME_RENDER_CREATUREANIMATION_H
|
#define GAME_RENDER_CREATUREANIMATION_H
|
||||||
|
|
||||||
#include "animation.hpp"
|
#include "actoranimation.hpp"
|
||||||
#include "weaponanimation.hpp"
|
#include "weaponanimation.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class CreatureAnimation : public Animation
|
class CreatureAnimation : public ActorAnimation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CreatureAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
|
CreatureAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
|
||||||
@ -22,7 +22,7 @@ namespace MWRender
|
|||||||
// For creatures with weapons and shields
|
// For creatures with weapons and shields
|
||||||
// Animation is already virtual anyway, so might as well make a separate class.
|
// Animation is already virtual anyway, so might as well make a separate class.
|
||||||
// Most creatures don't need weapons/shields, so this will save some memory.
|
// Most creatures don't need weapons/shields, so this will save some memory.
|
||||||
class CreatureWeaponAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
class CreatureWeaponAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
|
CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <components/sceneutil/attach.hpp>
|
#include <components/sceneutil/attach.hpp>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
#include <components/sceneutil/skeleton.hpp>
|
#include <components/sceneutil/skeleton.hpp>
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
|
||||||
#include <components/nifosg/nifloader.hpp> // TextKeyMapHolder
|
#include <components/nifosg/nifloader.hpp> // TextKeyMapHolder
|
||||||
|
|
||||||
@ -272,8 +273,8 @@ NpcAnimation::~NpcAnimation()
|
|||||||
// No need to getInventoryStore() to reset, if none exists
|
// No need to getInventoryStore() to reset, if none exists
|
||||||
// This is to avoid triggering the listener via ensureCustomData()->autoEquip()->fireEquipmentChanged()
|
// This is to avoid triggering the listener via ensureCustomData()->autoEquip()->fireEquipmentChanged()
|
||||||
// all from within this destructor. ouch!
|
// all from within this destructor. ouch!
|
||||||
&& mPtr.getRefData().getCustomData() && mPtr.getClass().getInventoryStore(mPtr).getListener() == this)
|
&& mPtr.getRefData().getCustomData() && mPtr.getClass().getInventoryStore(mPtr).getInvListener() == this)
|
||||||
mPtr.getClass().getInventoryStore(mPtr).setListener(NULL, mPtr);
|
mPtr.getClass().getInventoryStore(mPtr).setInvListener(NULL, mPtr);
|
||||||
|
|
||||||
// do not detach (delete) parts yet, this is done so the background thread can handle the deletion
|
// do not detach (delete) parts yet, this is done so the background thread can handle the deletion
|
||||||
for(size_t i = 0;i < ESM::PRT_Count;i++)
|
for(size_t i = 0;i < ESM::PRT_Count;i++)
|
||||||
@ -285,7 +286,7 @@ NpcAnimation::~NpcAnimation()
|
|||||||
|
|
||||||
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||||
bool disableListener, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView)
|
bool disableListener, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView)
|
||||||
: Animation(ptr, parentNode, resourceSystem),
|
: ActorAnimation(ptr, parentNode, resourceSystem, disableListener),
|
||||||
mListenerDisabled(disableListener),
|
mListenerDisabled(disableListener),
|
||||||
mViewMode(viewMode),
|
mViewMode(viewMode),
|
||||||
mShowWeapons(false),
|
mShowWeapons(false),
|
||||||
@ -310,7 +311,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> par
|
|||||||
updateNpcBase();
|
updateNpcBase();
|
||||||
|
|
||||||
if (!disableListener)
|
if (!disableListener)
|
||||||
mPtr.getClass().getInventoryStore(mPtr).setListener(this, mPtr);
|
mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
|
void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
#include "actoranimation.hpp"
|
||||||
#include "weaponanimation.hpp"
|
#include "weaponanimation.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
@ -19,7 +20,7 @@ namespace MWRender
|
|||||||
class NeckController;
|
class NeckController;
|
||||||
class HeadAnimationTime;
|
class HeadAnimationTime;
|
||||||
|
|
||||||
class NpcAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void equipmentChanged();
|
virtual void equipmentChanged();
|
||||||
|
@ -136,6 +136,17 @@ int MWWorld::ContainerStore::count(const std::string &id)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::ContainerStoreListener* MWWorld::ContainerStore::getContListener() const
|
||||||
|
{
|
||||||
|
return mListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::setContListener(MWWorld::ContainerStoreListener* listener)
|
||||||
|
{
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container, int count)
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container, int count)
|
||||||
{
|
{
|
||||||
if (ptr.getRefData().getCount() <= count)
|
if (ptr.getRefData().getCount() <= count)
|
||||||
@ -292,6 +303,9 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
|||||||
item.getRefData().getLocals().setVarByInt(script, "onpcadd", 1);
|
item.getRefData().getLocals().setVarByInt(script, "onpcadd", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mListener)
|
||||||
|
mListener->itemAdded(item, count);
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +412,9 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor
|
|||||||
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
|
|
||||||
|
if (mListener)
|
||||||
|
mListener->itemRemoved(item, count - toRemove);
|
||||||
|
|
||||||
// number of removed items
|
// number of removed items
|
||||||
return count - toRemove;
|
return count - toRemove;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,13 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
class ContainerStoreIterator;
|
class ContainerStoreIterator;
|
||||||
|
|
||||||
|
class ContainerStoreListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void itemAdded(const ConstPtr& item, int count) {}
|
||||||
|
virtual void itemRemoved(const ConstPtr& item, int count) {}
|
||||||
|
};
|
||||||
|
|
||||||
class ContainerStore
|
class ContainerStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -73,6 +80,8 @@ namespace MWWorld
|
|||||||
///< Stores result of levelled item spawns. <(refId, spawningGroup), count>
|
///< Stores result of levelled item spawns. <(refId, spawningGroup), count>
|
||||||
/// This is used to restock levelled items(s) if the old item was sold.
|
/// This is used to restock levelled items(s) if the old item was sold.
|
||||||
|
|
||||||
|
ContainerStoreListener* mListener;
|
||||||
|
|
||||||
mutable float mCachedWeight;
|
mutable float mCachedWeight;
|
||||||
mutable bool mWeightUpToDate;
|
mutable bool mWeightUpToDate;
|
||||||
ContainerStoreIterator addImp (const Ptr& ptr, int count);
|
ContainerStoreIterator addImp (const Ptr& ptr, int count);
|
||||||
@ -143,6 +152,9 @@ namespace MWWorld
|
|||||||
/// @return How many items with refID \a id are in this container?
|
/// @return How many items with refID \a id are in this container?
|
||||||
int count (const std::string& id);
|
int count (const std::string& id);
|
||||||
|
|
||||||
|
ContainerStoreListener* getContListener() const;
|
||||||
|
void setContListener(ContainerStoreListener* listener);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ContainerStoreIterator addNewStack (const ConstPtr& ptr, int count);
|
ContainerStoreIterator addNewStack (const ConstPtr& ptr, int count);
|
||||||
///< Add the item to this container (do not try to stack it onto existing items)
|
///< Add the item to this container (do not try to stack it onto existing items)
|
||||||
|
@ -606,12 +606,12 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipItemQuantity(con
|
|||||||
return unstack(item, actor, item.getRefData().getCount() - count);
|
return unstack(item, actor, item.getRefData().getCount() - count);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStoreListener* MWWorld::InventoryStore::getListener()
|
MWWorld::InventoryStoreListener* MWWorld::InventoryStore::getInvListener()
|
||||||
{
|
{
|
||||||
return mListener;
|
return mListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::InventoryStore::setListener(InventoryStoreListener *listener, const Ptr& actor)
|
void MWWorld::InventoryStore::setInvListener(InventoryStoreListener *listener, const Ptr& actor)
|
||||||
{
|
{
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
updateMagicEffects(actor);
|
updateMagicEffects(actor);
|
||||||
|
@ -197,10 +197,10 @@ namespace MWWorld
|
|||||||
/// in the slot (they can be re-stacked so its count may be different
|
/// in the slot (they can be re-stacked so its count may be different
|
||||||
/// than the requested count).
|
/// than the requested count).
|
||||||
|
|
||||||
void setListener (InventoryStoreListener* listener, const Ptr& actor);
|
void setInvListener (InventoryStoreListener* listener, const Ptr& actor);
|
||||||
///< Set a listener for various events, see \a InventoryStoreListener
|
///< Set a listener for various events, see \a InventoryStoreListener
|
||||||
|
|
||||||
InventoryStoreListener* getListener();
|
InventoryStoreListener* getInvListener();
|
||||||
|
|
||||||
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor);
|
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor);
|
||||||
|
|
||||||
|
@ -359,6 +359,10 @@ namespace SceneUtil
|
|||||||
for (unsigned int i=0; i<lights.size(); ++i)
|
for (unsigned int i=0; i<lights.size(); ++i)
|
||||||
{
|
{
|
||||||
const LightManager::LightSourceViewBound& l = lights[i];
|
const LightManager::LightSourceViewBound& l = lights[i];
|
||||||
|
|
||||||
|
if (mIgnoredLightSources.count(l.mLightSource))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (l.mViewBound.intersects(nodeBound))
|
if (l.mViewBound.intersects(nodeBound))
|
||||||
mLightList.push_back(&l);
|
mLightList.push_back(&l);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
|
#ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
|
||||||
#define OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
|
#define OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <osg/Light>
|
#include <osg/Light>
|
||||||
|
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
@ -157,16 +159,20 @@ namespace SceneUtil
|
|||||||
: osg::Object(copy, copyop), osg::NodeCallback(copy, copyop)
|
: osg::Object(copy, copyop), osg::NodeCallback(copy, copyop)
|
||||||
, mLightManager(copy.mLightManager)
|
, mLightManager(copy.mLightManager)
|
||||||
, mLastFrameNumber(0)
|
, mLastFrameNumber(0)
|
||||||
|
, mIgnoredLightSources(copy.mIgnoredLightSources)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
META_Object(SceneUtil, LightListCallback)
|
META_Object(SceneUtil, LightListCallback)
|
||||||
|
|
||||||
void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
|
|
||||||
|
std::set<SceneUtil::LightSource*>& getIgnoredLightSources() { return mIgnoredLightSources; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LightManager* mLightManager;
|
LightManager* mLightManager;
|
||||||
unsigned int mLastFrameNumber;
|
unsigned int mLastFrameNumber;
|
||||||
LightManager::LightList mLightList;
|
LightManager::LightList mLightList;
|
||||||
|
std::set<SceneUtil::LightSource*> mIgnoredLightSources;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ namespace SceneUtil
|
|||||||
light->setLinearAttenuation(linearAttenuation);
|
light->setLinearAttenuation(linearAttenuation);
|
||||||
light->setQuadraticAttenuation(quadraticAttenuation);
|
light->setQuadraticAttenuation(quadraticAttenuation);
|
||||||
light->setConstantAttenuation(0.f);
|
light->setConstantAttenuation(0.f);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic,
|
void addLight (osg::Group* node, const ESM::Light* esmLight, unsigned int partsysMask, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic,
|
||||||
@ -68,6 +67,14 @@ namespace SceneUtil
|
|||||||
attachTo = trans;
|
attachTo = trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<LightSource> lightSource = createLightSource(esmLight, lightMask, isExterior, outQuadInLin, useQuadratic, quadraticValue,
|
||||||
|
quadraticRadiusMult, useLinear, linearRadiusMult, linearValue);
|
||||||
|
attachTo->addChild(lightSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<LightSource> createLightSource(const ESM::Light* esmLight, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic, float quadraticValue,
|
||||||
|
float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue, const osg::Vec4f& ambient)
|
||||||
|
{
|
||||||
osg::ref_ptr<SceneUtil::LightSource> lightSource (new SceneUtil::LightSource);
|
osg::ref_ptr<SceneUtil::LightSource> lightSource (new SceneUtil::LightSource);
|
||||||
osg::ref_ptr<osg::Light> light (new osg::Light);
|
osg::ref_ptr<osg::Light> light (new osg::Light);
|
||||||
lightSource->setNodeMask(lightMask);
|
lightSource->setNodeMask(lightMask);
|
||||||
@ -85,7 +92,7 @@ namespace SceneUtil
|
|||||||
diffuse.a() = 1;
|
diffuse.a() = 1;
|
||||||
}
|
}
|
||||||
light->setDiffuse(diffuse);
|
light->setDiffuse(diffuse);
|
||||||
light->setAmbient(osg::Vec4f(0,0,0,1));
|
light->setAmbient(ambient);
|
||||||
light->setSpecular(osg::Vec4f(0,0,0,0));
|
light->setSpecular(osg::Vec4f(0,0,0,0));
|
||||||
|
|
||||||
lightSource->setLight(light);
|
lightSource->setLight(light);
|
||||||
@ -103,7 +110,6 @@ namespace SceneUtil
|
|||||||
|
|
||||||
lightSource->addUpdateCallback(ctrl);
|
lightSource->addUpdateCallback(ctrl);
|
||||||
|
|
||||||
attachTo->addChild(lightSource);
|
return lightSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef OPENMW_COMPONENTS_LIGHTUTIL_H
|
#ifndef OPENMW_COMPONENTS_LIGHTUTIL_H
|
||||||
#define OPENMW_COMPONENTS_LIGHTUTIL_H
|
#define OPENMW_COMPONENTS_LIGHTUTIL_H
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osg/Vec4f>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
@ -13,6 +16,7 @@ namespace ESM
|
|||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
class LightSource;
|
||||||
|
|
||||||
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and add it to a sub graph.
|
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and add it to a sub graph.
|
||||||
/// @note If the sub graph contains a node named "AttachLight" (case insensitive), then the light is added to that.
|
/// @note If the sub graph contains a node named "AttachLight" (case insensitive), then the light is added to that.
|
||||||
@ -27,6 +31,15 @@ namespace SceneUtil
|
|||||||
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult,
|
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult,
|
||||||
float linearValue);
|
float linearValue);
|
||||||
|
|
||||||
|
/// @brief Convert an ESM::Light to a SceneUtil::LightSource, and return it.
|
||||||
|
/// @param esmLight The light definition coming from the game files containing radius, color, flicker, etc.
|
||||||
|
/// @param lightMask Mask to assign to the newly created LightSource.
|
||||||
|
/// @param isExterior Is the light outside? May be used for deciding which attenuation settings to use.
|
||||||
|
/// @param ambient Ambient component of the light.
|
||||||
|
/// @par Attenuation parameters come from the game INI file.
|
||||||
|
osg::ref_ptr<LightSource> createLightSource (const ESM::Light* esmLight, unsigned int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic,
|
||||||
|
float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue, const osg::Vec4f& ambient=osg::Vec4f(0,0,0,1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user