diff --git a/src/Gui/SoFCCSysDragger.cpp b/src/Gui/SoFCCSysDragger.cpp index f4c836469d..72d2b053ba 100644 --- a/src/Gui/SoFCCSysDragger.cpp +++ b/src/Gui/SoFCCSysDragger.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -638,6 +639,8 @@ void SoFCCSysDragger::initClass() } SoFCCSysDragger::SoFCCSysDragger() + :axisScale(1.0f,1.0f,1.0f) + ,scaleInited(false) { SO_KIT_CONSTRUCTOR(SoFCCSysDragger); @@ -939,6 +942,44 @@ void SoFCCSysDragger::cameraCB(void *data, SoSensor *) sudoThis->idleSensor.schedule(); } +void SoFCCSysDragger::GLRender(SoGLRenderAction * action) +{ + if(!scaleInited) { + scaleInited = true; + updateDraggerCache(action->getCurPath()); + updateAxisScale(); + } + + inherited::GLRender(action); +} + +void SoFCCSysDragger::updateAxisScale() { + SbMatrix localToWorld = getLocalToWorldMatrix(); + SbVec3f origin; + localToWorld.multVecMatrix(SbVec3f(0.0, 0.0, 0.0), origin); + SbVec3f vx,vy,vz; + localToWorld.multVecMatrix(SbVec3f(1.0f, 0.0f, 0.0f), vx); + localToWorld.multVecMatrix(SbVec3f(0.0f, 1.0f, 0.0f), vy); + localToWorld.multVecMatrix(SbVec3f(0.0f, 0.0f, 1.0f), vz); + float x = std::max((vx-origin).length(),1e-7f); + float y = std::max((vy-origin).length(),1e-7f); + float z = std::max((vz-origin).length(),1e-7f); + if(!axisScale.equals(SbVec3f(x,y,z),1e-7f)) { + axisScale.setValue(x,y,z); + idleCB(this,&idleSensor); + } +} + +void SoFCCSysDragger::handleEvent(SoHandleEventAction * action) +{ + this->ref(); + + inherited::handleEvent(action); + updateAxisScale(); + + this->unref(); +} + void SoFCCSysDragger::idleCB(void *data, SoSensor *) { SoFCCSysDragger *sudoThis = reinterpret_cast(data); @@ -953,7 +994,9 @@ void SoFCCSysDragger::idleCB(void *data, SoSensor *) SbViewVolume viewVolume = camera->getViewVolume(); float radius = sudoThis->draggerSize.getValue() / 2.0; float localScale = viewVolume.getWorldToScreenScale(origin, radius); - SbVec3f scaleVector(localScale, localScale, localScale); + float sx,sy,sz; + sudoThis->axisScale.getValue(sx,sy,sz); + SbVec3f scaleVector(localScale/sx, localScale/sy, localScale/sz); SoScale *localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale); localScaleNode->scaleFactor.setValue(scaleVector); sudoThis->autoScaleResult.setValue(localScale); diff --git a/src/Gui/SoFCCSysDragger.h b/src/Gui/SoFCCSysDragger.h index f78e68388c..c49c87c032 100644 --- a/src/Gui/SoFCCSysDragger.h +++ b/src/Gui/SoFCCSysDragger.h @@ -239,8 +239,11 @@ public: bool isHiddenRotationZ(); //!< is x rotation dragger hidden. //@} + virtual void GLRender(SoGLRenderAction * action); + protected: virtual SbBool setUpConnections(SbBool onoff, SbBool doitalways = FALSE) override; + virtual void handleEvent(SoHandleEventAction * action) override; static void translationSensorCB(void *f, SoSensor *); static void rotationSensorCB(void *f, SoSensor *); @@ -255,6 +258,14 @@ protected: SoFieldSensor cameraSensor; private: + // Used to compensate for axis scale in world transformation when doing + // auto scale. + SbVec3f axisScale; + + bool scaleInited; + + void updateAxisScale(); + typedef SoDragger inherited; }; diff --git a/src/Gui/ViewProviderLink.cpp b/src/Gui/ViewProviderLink.cpp index da105122d7..c5f3208a31 100644 --- a/src/Gui/ViewProviderLink.cpp +++ b/src/Gui/ViewProviderLink.cpp @@ -2572,15 +2572,7 @@ void ViewProviderLink::setEditViewer(Gui::View3DInventorViewer* viewer, int ModN viewer->setupEditingRoot(group,&dragCtx->preTransform); }else{ SoFCCSysDragger* dragger = static_cast(pcDragger.get()); - auto doc = Application::Instance->editDocument(); - if(doc) { - Base::Vector3d v0, v1(1,0,0); - doc->getEditingTransform().multVec(v0,v0); - doc->getEditingTransform().multVec(v1,v1); - // Compensate for possible scaling - dragger->draggerSize.setValue(0.05f / (v1-v0).Length()); - } else - dragger->draggerSize.setValue(0.05f); + dragger->draggerSize.setValue(0.05f); dragger->setUpAutoScale(viewer->getSoRenderManager()->getCamera()); viewer->setupEditingRoot(pcDragger,&dragCtx->preTransform);