From 035d5205d97faa8cc75341f77b14b67d057a20d2 Mon Sep 17 00:00:00 2001 From: Nelsson Huotari Date: Tue, 3 Mar 2020 21:18:09 +0200 Subject: [PATCH] Use collision boxes to calculate dropping height, variable naming --- apps/opencs/view/render/instancemode.cpp | 37 +++++++++++++++--------- apps/opencs/view/render/instancemode.hpp | 2 +- apps/opencs/view/render/object.cpp | 5 ++++ apps/opencs/view/render/object.hpp | 5 +++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 12f14b48da..6f0ed01a06 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -7,6 +7,7 @@ #include "../../model/prefs/state.hpp" +#include #include #include #include @@ -704,7 +705,6 @@ void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object* osg::Vec3d start = point; osg::Vec3d end = point; - start.z() += 1.0f; end.z() = std::numeric_limits::min(); osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( @@ -730,14 +730,12 @@ void CSVRender::InstanceMode::dropInstance(DropMode dropMode, CSVRender::Object* } } -float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Object* object) +float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight) { const osg::Vec3d& point = object->getPosition().asVec3(); - osg::ref_ptr objectNode = object->getRootNode(); osg::Vec3d start = point; osg::Vec3d end = point; - start.z() += 1.0f; end.z() = std::numeric_limits::min(); osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( @@ -754,9 +752,8 @@ float CSVRender::InstanceMode::getDropHeight(DropMode dropMode, CSVRender::Objec it != intersector->getIntersections().end(); ++it) { osgUtil::LineSegmentIntersector::Intersection intersection = *it; - ESM::Position position = object->getPosition(); - float dropHeight = intersection.getWorldIntersectPoint().z(); - return position.pos[2] - dropHeight; + float collisionLevel = intersection.getWorldIntersectPoint().z(); + return point.z() - collisionLevel + objectHeight; } return 0.0f; @@ -793,13 +790,25 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman CSMWorld::CommandMacro macro (undoStack, commandMsg); std::vector oldMasks; + std::vector objectHeights; for(osg::ref_ptr tag: selection) { if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) { - osg::ref_ptr objectNode = objectTag->mObject->getRootNode(); - oldMasks.emplace_back(objectNode->getNodeMask()); - objectNode->setNodeMask(SceneUtil::Mask_Disabled); + osg::ref_ptr objectNodeWithGUI = objectTag->mObject->getRootNode(); + osg::ref_ptr 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); } } @@ -811,11 +820,13 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman case Collision: { float smallestDropHeight = std::numeric_limits::max(); + int counter = 0; for(osg::ref_ptr tag: selection) if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) { - float thisDrop = getDropHeight(dropMode, objectTag->mObject); + float thisDrop = getDropHeight(dropMode, objectTag->mObject, objectHeights[counter]); if (thisDrop < smallestDropHeight) smallestDropHeight = thisDrop; + counter++; } for(osg::ref_ptr tag: selection) if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) @@ -852,8 +863,8 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman { if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) { - osg::ref_ptr objectNode = objectTag->mObject->getRootNode(); - objectNode->setNodeMask(oldMasks[counter]); + osg::ref_ptr objectNodeWithGUI = objectTag->mObject->getRootNode(); + objectNodeWithGUI->setNodeMask(oldMasks[counter]); counter++; } } diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 883dab4054..38280dd6ff 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -58,7 +58,7 @@ namespace CSVRender osg::Vec3f getSelectionCenter(const std::vector >& selection) const; osg::Vec3f getScreenCoords(const osg::Vec3f& pos); void dropInstance(DropMode dropMode, CSVRender::Object* object); - float getDropHeight(DropMode dropMode, CSVRender::Object* object); + float getDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight); public: diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 47754b4481..6b33cdeb2c 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -482,6 +482,11 @@ osg::ref_ptr CSVRender::Object::getRootNode() return mRootNode; } +osg::ref_ptr CSVRender::Object::getBaseNode() +{ + return mBaseNode; +} + bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index b2561d5850..4d1763f80f 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -146,9 +146,12 @@ namespace CSVRender bool getSelected() const; - /// For direct altering of object rendering + /// Get object node with GUI graphics osg::ref_ptr getRootNode(); + /// Get object node without GUI graphics + osg::ref_ptr getBaseNode(); + /// \return Did this call result in a modification of the visual representation of /// this object? bool referenceableDataChanged (const QModelIndex& topLeft,