1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-15 23:49:55 +00:00
openmw-tes3mp/apps/openmw/mwrender/objects.cpp

233 lines
6.6 KiB
C++
Raw Normal View History

2011-11-01 03:59:16 +00:00
#include "objects.hpp"
2012-02-06 09:41:13 +00:00
#include <osg/Group>
#include <osg/UserDataContainer>
2012-02-06 09:41:13 +00:00
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/sceneutil/unrefqueue.hpp>
#include "../mwworld/ptr.hpp"
2012-07-30 19:28:14 +00:00
#include "../mwworld/class.hpp"
#include "animation.hpp"
2015-04-15 20:11:38 +00:00
#include "npcanimation.hpp"
2015-04-19 01:05:47 +00:00
#include "creatureanimation.hpp"
#include "vismask.hpp"
namespace MWRender
{
Objects::Objects(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> rootNode, SceneUtil::UnrefQueue* unrefQueue)
2015-05-23 20:44:00 +00:00
: mRootNode(rootNode)
, mResourceSystem(resourceSystem)
, mUnrefQueue(unrefQueue)
2012-02-06 09:41:13 +00:00
{
}
Objects::~Objects()
{
mObjects.clear();
for (CellMap::iterator iter = mCellSceneNodes.begin(); iter != mCellSceneNodes.end(); ++iter)
iter->second->getParent(0)->removeChild(iter->second);
mCellSceneNodes.clear();
2011-11-17 22:10:27 +00:00
}
2012-02-06 09:41:13 +00:00
2013-08-07 10:51:57 +00:00
void Objects::insertBegin(const MWWorld::Ptr& ptr)
2012-02-06 09:41:13 +00:00
{
assert(mObjects.find(ptr) == mObjects.end());
osg::ref_ptr<osg::Group> cellnode;
CellMap::iterator found = mCellSceneNodes.find(ptr.getCell());
if (found == mCellSceneNodes.end())
2011-11-05 01:57:39 +00:00
{
cellnode = new osg::Group;
cellnode->setName("Cell Root");
mRootNode->addChild(cellnode);
2011-11-05 01:57:39 +00:00
mCellSceneNodes[ptr.getCell()] = cellnode;
}
else
cellnode = found->second;
2011-11-05 01:48:52 +00:00
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> insert (new SceneUtil::PositionAttitudeTransform);
cellnode->addChild(insert);
2012-03-25 02:03:08 +00:00
insert->getOrCreateUserDataContainer()->addUserObject(new PtrHolder(ptr));
const float *f = ptr.getRefData().getPosition().pos;
insert->setPosition(osg::Vec3(f[0], f[1], f[2]));
const float scale = ptr.getCellRef().getScale();
osg::Vec3f scaleVec(scale, scale, scale);
ptr.getClass().adjustScale(ptr, scaleVec, true);
insert->setScale(scaleVec);
2011-11-03 02:41:48 +00:00
ptr.getRefData().setBaseNode(insert);
2011-11-01 03:59:16 +00:00
}
2012-02-06 09:41:13 +00:00
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool animated, bool allowLight)
2012-02-06 09:41:13 +00:00
{
2013-08-07 10:51:57 +00:00
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object);
osg::ref_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight));
mObjects.insert(std::make_pair(ptr, anim));
}
void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields)
{
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
// CreatureAnimation
osg::ref_ptr<Animation> anim;
2015-04-19 01:05:47 +00:00
if (weaponsShields)
anim = new CreatureWeaponAnimation(ptr, mesh, mResourceSystem);
2015-04-19 01:05:47 +00:00
else
anim = new CreatureAnimation(ptr, mesh, mResourceSystem);
2015-04-19 01:05:47 +00:00
if (mObjects.insert(std::make_pair(ptr, anim)).second)
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));
}
void Objects::insertNPC(const MWWorld::Ptr &ptr)
{
2015-04-15 20:11:38 +00:00
insertBegin(ptr);
ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor);
osg::ref_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem));
2015-04-19 13:03:08 +00:00
if (mObjects.insert(std::make_pair(ptr, anim)).second)
{
ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr);
ptr.getClass().getInventoryStore(ptr).setContListener(anim.get());
}
2011-11-01 03:59:16 +00:00
}
2012-02-06 09:41:13 +00:00
2015-05-21 22:55:43 +00:00
bool Objects::removeObject (const MWWorld::Ptr& ptr)
2012-02-06 09:41:13 +00:00
{
if(!ptr.getRefData().getBaseNode())
return true;
2012-04-28 18:42:53 +00:00
PtrAnimationMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
2012-02-06 09:41:13 +00:00
{
2016-10-08 14:41:17 +00:00
if (mUnrefQueue.get())
mUnrefQueue->push(iter->second);
2016-10-08 14:41:17 +00:00
mObjects.erase(iter);
2012-02-06 09:41:13 +00:00
if (ptr.getClass().isActor())
{
if (ptr.getClass().hasInventoryStore(ptr))
2018-10-09 06:21:12 +00:00
ptr.getClass().getInventoryStore(ptr).setInvListener(nullptr, ptr);
2018-10-09 06:21:12 +00:00
ptr.getClass().getContainerStore(ptr).setContListener(nullptr);
}
ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode());
2018-10-09 06:21:12 +00:00
ptr.getRefData().setBaseNode(nullptr);
return true;
}
return false;
2011-11-01 03:59:16 +00:00
}
2011-11-02 04:13:33 +00:00
2011-11-05 01:48:52 +00:00
void Objects::removeCell(const MWWorld::CellStore* store)
2012-02-06 09:41:13 +00:00
{
for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();)
2011-11-05 01:48:52 +00:00
{
MWWorld::Ptr ptr = iter->second->getPtr();
if(ptr.getCell() == store)
{
if (mUnrefQueue.get())
mUnrefQueue->push(iter->second);
if (ptr.getClass().isNpc() && ptr.getRefData().getCustomData())
{
2017-03-26 18:47:17 +00:00
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
2018-10-09 06:21:12 +00:00
invStore.setInvListener(nullptr, ptr);
invStore.setContListener(nullptr);
}
mObjects.erase(iter++);
}
else
++iter;
2011-11-05 01:48:52 +00:00
}
CellMap::iterator cell = mCellSceneNodes.find(store);
if(cell != mCellSceneNodes.end())
{
cell->second->getParent(0)->removeChild(cell->second);
if (mUnrefQueue.get())
mUnrefQueue->push(cell->second);
mCellSceneNodes.erase(cell);
}
}
2012-04-02 17:37:24 +00:00
2015-05-14 15:34:55 +00:00
void Objects::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
2012-07-30 19:28:14 +00:00
{
2015-05-26 14:40:44 +00:00
osg::Node* objectNode = cur.getRefData().getBaseNode();
if (!objectNode)
return;
MWWorld::CellStore *newCell = cur.getCell();
2012-07-30 19:28:14 +00:00
2015-05-14 15:34:55 +00:00
osg::Group* cellnode;
2012-07-30 19:28:14 +00:00
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
2015-05-14 15:34:55 +00:00
cellnode = new osg::Group;
mRootNode->addChild(cellnode);
mCellSceneNodes[newCell] = cellnode;
2012-07-30 19:28:14 +00:00
} else {
2015-05-14 15:34:55 +00:00
cellnode = mCellSceneNodes[newCell];
2012-07-30 19:28:14 +00:00
}
osg::UserDataContainer* userDataContainer = objectNode->getUserDataContainer();
if (userDataContainer)
for (unsigned int i=0; i<userDataContainer->getNumUserObjects(); ++i)
{
if (dynamic_cast<PtrHolder*>(userDataContainer->getUserObject(i)))
userDataContainer->setUserObject(i, new PtrHolder(cur));
}
2015-05-14 15:34:55 +00:00
if (objectNode->getNumParents())
objectNode->getParent(0)->removeChild(objectNode);
cellnode->addChild(objectNode);
PtrAnimationMap::iterator iter = mObjects.find(old);
if(iter != mObjects.end())
{
2017-02-22 20:02:34 +00:00
osg::ref_ptr<Animation> anim = iter->second;
mObjects.erase(iter);
anim->updatePtr(cur);
mObjects[cur] = anim;
}
2012-07-30 19:28:14 +00:00
}
Animation* Objects::getAnimation(const MWWorld::Ptr &ptr)
{
PtrAnimationMap::const_iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
return iter->second;
2018-10-09 06:21:12 +00:00
return nullptr;
2012-07-30 19:28:14 +00:00
}
2015-12-18 16:21:51 +00:00
const Animation* Objects::getAnimation(const MWWorld::ConstPtr &ptr) const
{
PtrAnimationMap::const_iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
return iter->second;
2018-10-09 06:21:12 +00:00
return nullptr;
2015-12-18 16:21:51 +00:00
}
}