1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 21:35:24 +00:00
OpenMW/apps/openmw/mwrender/objects.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

242 lines
7.8 KiB
C++
Raw Normal View History

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