1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-02 07:21:07 +00:00

Add helper class for safer mask handling

This commit is contained in:
Nelsson Huotari 2020-03-18 11:16:21 +02:00
parent af434cffba
commit 41aa90bfa7
2 changed files with 71 additions and 55 deletions

View File

@ -791,31 +791,8 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman
CSMWorld::CommandMacro macro (undoStack, commandMsg); CSMWorld::CommandMacro macro (undoStack, commandMsg);
std::vector<osg::Node::NodeMask> oldMasks; DropObjectDataHandler dropObjectDataHandler(&getWorldspaceWidget());
std::vector<float> objectHeights;
for(osg::ref_ptr<TagBase> tag: selection)
{
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{
osg::ref_ptr<osg::Group> objectNodeWithGUI = objectTag->mObject->getRootNode();
osg::ref_ptr<osg::Group> objectNodeWithoutGUI = objectTag->mObject->getBaseNode();
osg::ComputeBoundsVisitor computeBounds;
computeBounds.setTraversalMask(SceneUtil::Mask_EditorReference);
objectNodeWithoutGUI->accept(computeBounds);
osg::BoundingBox bounds = computeBounds.getBoundingBox();
float boundingBoxOffset = 0.0f;
if (bounds.valid()) boundingBoxOffset = bounds.zMin();
objectHeights.emplace_back(boundingBoxOffset);
oldMasks.emplace_back(objectNodeWithGUI->getNodeMask());
objectNodeWithGUI->setNodeMask(SceneUtil::Mask_Disabled);
}
}
try
{
switch (dropMode) switch (dropMode)
{ {
case Terrain: case Terrain:
@ -826,7 +803,7 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman
for(osg::ref_ptr<TagBase> tag: selection) for(osg::ref_ptr<TagBase> tag: selection)
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{ {
float thisDrop = getDropHeight(dropMode, objectTag->mObject, objectHeights[counter]); float thisDrop = getDropHeight(dropMode, objectTag->mObject, dropObjectDataHandler.mObjectHeights[counter]);
if (thisDrop < smallestDropHeight) smallestDropHeight = thisDrop; if (thisDrop < smallestDropHeight) smallestDropHeight = thisDrop;
counter++; counter++;
} }
@ -849,28 +826,54 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman
for(osg::ref_ptr<TagBase> tag: selection) for(osg::ref_ptr<TagBase> tag: selection)
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{ {
dropInstance(dropMode, objectTag->mObject, objectHeights[counter]); dropInstance(dropMode, objectTag->mObject, dropObjectDataHandler.mObjectHeights[counter]);
objectTag->mObject->apply (macro); objectTag->mObject->apply (macro);
counter++; counter++;
} }
} }
break; break;
default: default:
break; break;
} }
} }
catch (const std::exception& e)
CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worldspacewidget)
: mWorldspaceWidget(worldspacewidget)
{ {
Log(Debug::Error) << "Error in dropping instance: " << e.what(); std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (SceneUtil::Mask_EditorReference);
for(osg::ref_ptr<TagBase> tag: selection)
{
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{
osg::ref_ptr<osg::Group> objectNodeWithGUI = objectTag->mObject->getRootNode();
osg::ref_ptr<osg::Group> objectNodeWithoutGUI = objectTag->mObject->getBaseNode();
osg::ComputeBoundsVisitor computeBounds;
computeBounds.setTraversalMask(SceneUtil::Mask_EditorReference);
objectNodeWithoutGUI->accept(computeBounds);
osg::BoundingBox bounds = computeBounds.getBoundingBox();
float boundingBoxOffset = 0.0f;
if (bounds.valid()) boundingBoxOffset = bounds.zMin();
mObjectHeights.emplace_back(boundingBoxOffset);
mOldMasks.emplace_back(objectNodeWithGUI->getNodeMask());
objectNodeWithGUI->setNodeMask(SceneUtil::Mask_Disabled);
}
}
} }
CSVRender::DropObjectDataHandler::~DropObjectDataHandler()
{
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (SceneUtil::Mask_EditorReference);
int counter = 0; int counter = 0;
for(osg::ref_ptr<TagBase> tag: selection) for(osg::ref_ptr<TagBase> tag: selection)
{ {
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{ {
osg::ref_ptr<osg::Group> objectNodeWithGUI = objectTag->mObject->getRootNode(); osg::ref_ptr<osg::Group> objectNodeWithGUI = objectTag->mObject->getRootNode();
objectNodeWithGUI->setNodeMask(oldMasks[counter]); objectNodeWithGUI->setNodeMask(mOldMasks[counter]);
counter++; counter++;
} }
} }

View File

@ -114,6 +114,19 @@ namespace CSVRender
void dropSelectedInstancesToTerrainSeparately(); void dropSelectedInstancesToTerrainSeparately();
void handleDropMethod(DropMode dropMode, QString commandMsg); void handleDropMethod(DropMode dropMode, QString commandMsg);
}; };
/// \brief Helper class to handle object mask data in safe way
class DropObjectDataHandler
{
public:
DropObjectDataHandler(WorldspaceWidget* worldspacewidget);
~DropObjectDataHandler();
std::vector<float> mObjectHeights;
private:
WorldspaceWidget* mWorldspaceWidget;
std::vector<osg::Node::NodeMask> mOldMasks;
};
} }
#endif #endif