mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 07:56:37 +00:00 
			
		
		
		
	Merge branch 'cs_fix_separate_drop' into 'master'
OpenMW-CS: Fix separate drop, refactor for code reuse See merge request OpenMW/openmw!574
This commit is contained in:
		
						commit
						faa800464f
					
				
					 2 changed files with 56 additions and 85 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); | ||||||
|  | @ -878,12 +854,12 @@ void CSVRender::InstanceMode::dropSelectedInstancesToTerrain() | ||||||
| 
 | 
 | ||||||
| void CSVRender::InstanceMode::dropSelectedInstancesToCollisionSeparately() | void CSVRender::InstanceMode::dropSelectedInstancesToCollisionSeparately() | ||||||
| { | { | ||||||
|     handleDropMethod(TerrainSep, "Drop instances to next collision level separately"); |     handleDropMethod(CollisionSep, "Drop instances to next collision level separately"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CSVRender::InstanceMode::dropSelectedInstancesToTerrainSeparately() | void CSVRender::InstanceMode::dropSelectedInstancesToTerrainSeparately() | ||||||
| { | { | ||||||
|     handleDropMethod(CollisionSep, "Drop instances to terrain level separately"); |     handleDropMethod(TerrainSep, "Drop instances to terrain level separately"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString commandMsg) | void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString commandMsg) | ||||||
|  | @ -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 = 0b1, | ||||||
|                 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 dropHeight); | ||||||
|             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