mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 20:53:50 +00:00
Fix separate drop, refactor for code reuse
This commit is contained in:
parent
d984d13b1c
commit
36cd818155
2 changed files with 54 additions and 83 deletions
|
@ -802,39 +802,15 @@ void CSVRender::InstanceMode::deleteSelectedInstances(bool active)
|
||||||
getWorldspaceWidget().clearSelection (Mask_Reference);
|
getWorldspaceWidget().clearSelection (Mask_Reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object* object, float objectHeight)
|
void CSVRender::InstanceMode::dropInstance(CSVRender::Object* object, float dropHeight)
|
||||||
{
|
{
|
||||||
osg::Vec3d point = object->getPosition().asVec3();
|
object->setEdited(Object::Override_Position);
|
||||||
|
ESM::Position position = object->getPosition();
|
||||||
osg::Vec3d start = point;
|
position.pos[2] -= dropHeight;
|
||||||
start.z() += objectHeight;
|
object->setPosition(position.pos);
|
||||||
osg::Vec3d end = point;
|
|
||||||
end.z() = std::numeric_limits<float>::lowest();
|
|
||||||
|
|
||||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(
|
|
||||||
osgUtil::Intersector::MODEL, start, end) );
|
|
||||||
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
|
|
||||||
osgUtil::IntersectionVisitor visitor(intersector);
|
|
||||||
|
|
||||||
if (dropMode == TerrainSep)
|
|
||||||
visitor.setTraversalMask(Mask_Terrain);
|
|
||||||
if (dropMode == CollisionSep)
|
|
||||||
visitor.setTraversalMask(Mask_Terrain | Mask_Reference);
|
|
||||||
|
|
||||||
mParentNode->accept(visitor);
|
|
||||||
|
|
||||||
osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
|
|
||||||
if (it != intersector->getIntersections().end())
|
|
||||||
{
|
|
||||||
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
|
|
||||||
ESM::Position position = object->getPosition();
|
|
||||||
object->setEdited (Object::Override_Position);
|
|
||||||
position.pos[2] = intersection.getWorldIntersectPoint().z() + objectHeight;
|
|
||||||
object->setPosition(position.pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight)
|
float CSVRender::InstanceMode::calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight)
|
||||||
{
|
{
|
||||||
osg::Vec3d point = object->getPosition().asVec3();
|
osg::Vec3d point = object->getPosition().asVec3();
|
||||||
|
|
||||||
|
@ -848,9 +824,9 @@ float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Objec
|
||||||
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
|
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
|
||||||
osgUtil::IntersectionVisitor visitor(intersector);
|
osgUtil::IntersectionVisitor visitor(intersector);
|
||||||
|
|
||||||
if (dropMode == Terrain)
|
if (dropMode & Terrain)
|
||||||
visitor.setTraversalMask(Mask_Terrain);
|
visitor.setTraversalMask(Mask_Terrain);
|
||||||
if (dropMode == Collision)
|
if (dropMode & Collision)
|
||||||
visitor.setTraversalMask(Mask_Terrain | Mask_Reference);
|
visitor.setTraversalMask(Mask_Terrain | Mask_Reference);
|
||||||
|
|
||||||
mParentNode->accept(visitor);
|
mParentNode->accept(visitor);
|
||||||
|
@ -897,52 +873,44 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman
|
||||||
|
|
||||||
CSMWorld::CommandMacro macro (undoStack, commandMsg);
|
CSMWorld::CommandMacro macro (undoStack, commandMsg);
|
||||||
|
|
||||||
DropObjectDataHandler dropObjectDataHandler(&getWorldspaceWidget());
|
DropObjectHeightHandler dropObjectDataHandler(&getWorldspaceWidget());
|
||||||
|
|
||||||
switch (dropMode)
|
if(dropMode & Separate)
|
||||||
{
|
{
|
||||||
case Terrain:
|
int counter = 0;
|
||||||
case Collision:
|
for (osg::ref_ptr<TagBase> tag : selection)
|
||||||
{
|
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
|
||||||
float smallestDropHeight = std::numeric_limits<float>::max();
|
{
|
||||||
int counter = 0;
|
float objectHeight = dropObjectDataHandler.mObjectHeights[counter];
|
||||||
for(osg::ref_ptr<TagBase> tag: selection)
|
float dropHeight = calculateDropHeight(dropMode, objectTag->mObject, objectHeight);
|
||||||
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
|
dropInstance(objectTag->mObject, dropHeight);
|
||||||
{
|
objectTag->mObject->apply(macro);
|
||||||
float thisDrop = getDropHeight(dropMode, objectTag->mObject, dropObjectDataHandler.mObjectHeights[counter]);
|
counter++;
|
||||||
if (thisDrop < smallestDropHeight)
|
}
|
||||||
smallestDropHeight = thisDrop;
|
}
|
||||||
counter++;
|
else
|
||||||
}
|
{
|
||||||
for(osg::ref_ptr<TagBase> tag: selection)
|
float smallestDropHeight = std::numeric_limits<float>::max();
|
||||||
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
|
int counter = 0;
|
||||||
{
|
for (osg::ref_ptr<TagBase> tag : selection)
|
||||||
objectTag->mObject->setEdited (Object::Override_Position);
|
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
|
||||||
ESM::Position position = objectTag->mObject->getPosition();
|
{
|
||||||
position.pos[2] -= smallestDropHeight;
|
float objectHeight = dropObjectDataHandler.mObjectHeights[counter];
|
||||||
objectTag->mObject->setPosition(position.pos);
|
float thisDrop = calculateDropHeight(dropMode, objectTag->mObject, objectHeight);
|
||||||
objectTag->mObject->apply (macro);
|
if (thisDrop < smallestDropHeight)
|
||||||
}
|
smallestDropHeight = thisDrop;
|
||||||
}
|
counter++;
|
||||||
break;
|
}
|
||||||
|
for (osg::ref_ptr<TagBase> tag : selection)
|
||||||
case TerrainSep:
|
if (CSVRender::ObjectTag* objectTag = dynamic_cast<CSVRender::ObjectTag*>(tag.get()))
|
||||||
case CollisionSep:
|
{
|
||||||
{
|
dropInstance(objectTag->mObject, smallestDropHeight);
|
||||||
int counter = 0;
|
objectTag->mObject->apply(macro);
|
||||||
for(osg::ref_ptr<TagBase> tag: selection)
|
}
|
||||||
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
|
|
||||||
{
|
|
||||||
dropInstance(dropMode, objectTag->mObject, dropObjectDataHandler.mObjectHeights[counter]);
|
|
||||||
objectTag->mObject->apply (macro);
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worldspacewidget)
|
CSVRender::DropObjectHeightHandler::DropObjectHeightHandler(WorldspaceWidget* worldspacewidget)
|
||||||
: mWorldspaceWidget(worldspacewidget)
|
: mWorldspaceWidget(worldspacewidget)
|
||||||
{
|
{
|
||||||
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
|
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
|
||||||
|
@ -969,7 +937,7 @@ CSVRender::DropObjectDataHandler::DropObjectDataHandler(WorldspaceWidget* worlds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::DropObjectDataHandler::~DropObjectDataHandler()
|
CSVRender::DropObjectHeightHandler::~DropObjectHeightHandler()
|
||||||
{
|
{
|
||||||
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
|
std::vector<osg::ref_ptr<TagBase> > selection = mWorldspaceWidget->getSelection (Mask_Reference);
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
|
@ -28,10 +28,13 @@ namespace CSVRender
|
||||||
|
|
||||||
enum DropMode
|
enum DropMode
|
||||||
{
|
{
|
||||||
Collision,
|
Separate = 0x1,
|
||||||
Terrain,
|
|
||||||
CollisionSep,
|
Collision = 0b10,
|
||||||
TerrainSep
|
Terrain = 0b100,
|
||||||
|
|
||||||
|
CollisionSep = Collision | Separate,
|
||||||
|
TerrainSep = Terrain | Separate,
|
||||||
};
|
};
|
||||||
|
|
||||||
CSVWidget::SceneToolMode *mSubMode;
|
CSVWidget::SceneToolMode *mSubMode;
|
||||||
|
@ -53,8 +56,8 @@ namespace CSVRender
|
||||||
osg::Vec3f getProjectionSpaceCoords(const osg::Vec3f& pos);
|
osg::Vec3f getProjectionSpaceCoords(const osg::Vec3f& pos);
|
||||||
osg::Vec3f getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart);
|
osg::Vec3f getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart);
|
||||||
void handleSelectDrag(const QPoint& pos);
|
void handleSelectDrag(const QPoint& pos);
|
||||||
void dropInstance(DropMode dropMode, CSVRender::Object* object, float objectHeight);
|
void dropInstance(CSVRender::Object* object, float objectHeight);
|
||||||
float getDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight);
|
float calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -116,11 +119,11 @@ namespace CSVRender
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Helper class to handle object mask data in safe way
|
/// \brief Helper class to handle object mask data in safe way
|
||||||
class DropObjectDataHandler
|
class DropObjectHeightHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DropObjectDataHandler(WorldspaceWidget* worldspacewidget);
|
DropObjectHeightHandler(WorldspaceWidget* worldspacewidget);
|
||||||
~DropObjectDataHandler();
|
~DropObjectHeightHandler();
|
||||||
std::vector<float> mObjectHeights;
|
std::vector<float> mObjectHeights;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue