diff --git a/OMEdit/OMEditLIB/Animation/Vector.cpp b/OMEdit/OMEditLIB/Animation/Vector.cpp index d1bb7cc3d77..8d07b33a42d 100644 --- a/OMEdit/OMEditLIB/Animation/Vector.cpp +++ b/OMEdit/OMEditLIB/Animation/Vector.cpp @@ -62,11 +62,13 @@ std::ostream& operator<<(std::ostream& os, const VectorQuantity quantity) VectorObject::VectorObject() : AbstractVisualizerObjectWithVisualProperties(VisualizerType::vector), - mScaleLength(1.0), - mScaleRadius(1.0), - mScaleTransf(1.0), + mLengthScale(1.0), + mRadiusScale(1.0), + mAutoLengthScaleCancellation(1.0), + mAutoRadiusScaleCancellation(1.0), mAutoScaleCancellationRequired(false), mOnlyShaftLengthCounted(false), + mHidden(false), _quantity(VisualizerAttribute(0.0)), _headAtOrigin(VisualizerAttribute(0.0)), _twoHeadedArrow(VisualizerAttribute(0.0)) diff --git a/OMEdit/OMEditLIB/Animation/Vector.h b/OMEdit/OMEditLIB/Animation/Vector.h index 922827b6aab..fd7a85dac36 100644 --- a/OMEdit/OMEditLIB/Animation/Vector.h +++ b/OMEdit/OMEditLIB/Animation/Vector.h @@ -53,28 +53,33 @@ class VectorObject final : public AbstractVisualizerObjectWithVisualProperties(_quantity.exp);} bool areCoordinatesConstant() const {return _coords[0].isConst && _coords[1].isConst && _coords[2].isConst;} bool hasHeadAtOrigin() const {return _headAtOrigin.exp;} bool isTwoHeadedArrow() const {return _twoHeadedArrow.exp;} - bool isAdjustableRadius() const {return getQuantity() != VectorQuantity::relativePosition;} - bool isAdjustableLength() const {return getQuantity() != VectorQuantity::relativePosition;} - bool isScaleInvariant () const {return getQuantity() != VectorQuantity::relativePosition;} - bool isDrawnOnTop () const {return getQuantity() != VectorQuantity::relativePosition;} + bool isDrawnOnTop () const {return getQuantity() != VectorQuantity::relativePosition;} + bool isLengthAdjustable () const {return getQuantity() != VectorQuantity::relativePosition;} + bool isRadiusAdjustable () const {return getQuantity() != VectorQuantity::relativePosition;} + bool isLengthScaleInvariant() const {return getQuantity() != VectorQuantity::relativePosition;} + bool isRadiusScaleInvariant() const {return getQuantity() != VectorQuantity::relativePosition;} public: static constexpr float kRadius = 0.0125; //!< Modelica.Mechanics.MultiBody.World.defaultArrowDiameter / 2 = 1 / 40 / 2 = 0.0125 static constexpr float kHeadLength = 0.1000; //!< Modelica.Mechanics.MultiBody.Types.Defaults.ArrowHeadLengthFraction * (2 * kRadius) = 4 * 0.025 = 0.1000 @@ -84,11 +89,13 @@ class VectorObject final : public AbstractVisualizerObjectWithVisualProperties::max(); //!< To be rendered last private: - float mScaleLength; - float mScaleRadius; - float mScaleTransf; + float mLengthScale; + float mRadiusScale; + float mAutoLengthScaleCancellation; + float mAutoRadiusScaleCancellation; bool mAutoScaleCancellationRequired; bool mOnlyShaftLengthCounted; + bool mHidden; public: VisualizerAttribute _coords[3]; VisualizerAttribute _quantity; diff --git a/OMEdit/OMEditLIB/Animation/Visualization.cpp b/OMEdit/OMEditLIB/Animation/Visualization.cpp index 5d800777983..6c075cfce0f 100644 --- a/OMEdit/OMEditLIB/Animation/Visualization.cpp +++ b/OMEdit/OMEditLIB/Animation/Visualization.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -57,9 +58,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -787,7 +790,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* std::vector> fixedRadiusVectors; std::vector> adjustableRadiusVectors; for (VectorObject& vector : _vectors) { - if (vector.isAdjustableRadius()) { + if (vector.isRadiusAdjustable()) { adjustableRadiusVectors.push_back(vector); } else { fixedRadiusVectors.push_back(vector); @@ -872,7 +875,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Apply the radius scale to all adjustable-radius vectors for (VectorObject& vector : adjustableRadiusVectors) { - vector.setScaleRadius(scale); + vector.setRadiusScale(scale); updateVisualizer(vector); } @@ -886,7 +889,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Initialize a container of adjustable-length vectors std::vector> adjustableLengthVectors; for (VectorObject& vector : _vectors) { - if (vector.isAdjustableLength()) { + if (vector.isLengthAdjustable()) { adjustableLengthVectors.push_back(vector); } } @@ -904,12 +907,6 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* numberOfSamples[vector] = timeSamples > 0 && (timeIncrement <= 0 || vector.areCoordinatesConstant()) ? 1 : timeSamples; } - // Initialize a map of actual transform scales, one for each adjustable-length vector - std::unordered_map, float> transformScales; - for (VectorObject& vector : adjustableLengthVectors) { - transformScales[vector] = vector.getScaleTransf(); - } - // Store whether only the shaft length is counted for all adjustable-length vectors for (VectorObject& vector : adjustableLengthVectors) { vector.setOnlyShaftLengthCounted(!countUpToApex); @@ -917,7 +914,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Update the bounds of the whole scene without any adjustable-length vectors for (VectorObject& vector : adjustableLengthVectors) { - vector.setScaleTransf(0); + vector.setInvisible(); updateVisualizer(vector); } @@ -956,7 +953,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Make the vectors of the current quantity visible again // (the update is not necessary here because it is done inside and after the while loop in any case) for (VectorObject& vector : vectors) { - vector.setScaleTransf(transformScales[vector]); + vector.setVisible(); } // Adjust the length scale for the current quantity as long as the criteria have not been met @@ -988,7 +985,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Apply the new length scale to the vectors of the current quantity for (VectorObject& vector : vectors) { - vector.setScaleLength(scale); + vector.setLengthScale(scale); updateVisualizer(vector); } @@ -1064,14 +1061,14 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Make the vectors of the current quantity invisible again // (until all length scales have been carefully adjusted) for (VectorObject& vector : vectors) { - vector.setScaleTransf(0); + vector.setInvisible(); updateVisualizer(vector); } } // Update the bounds of the whole scene with all adjustable-length vectors using their adjusted length scales for (VectorObject& vector : adjustableLengthVectors) { - vector.setScaleTransf(transformScales[vector]); + vector.setVisible(); updateVisualizer(vector); } @@ -1089,7 +1086,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Make all adjustable-length vectors invisible for (VectorObject& vector : adjustableLengthVectors) { - vector.setScaleTransf(0); + vector.setInvisible(); updateVisualizer(vector); } @@ -1098,7 +1095,7 @@ void OMVisualBase::chooseVectorScales(osgViewer::View* view, OpenThreads::Mutex* // Make all adjustable-length vectors visible for (VectorObject& vector : adjustableLengthVectors) { - vector.setScaleTransf(transformScales[vector]); + vector.setVisible(); updateVisualizer(vector); } } @@ -1154,9 +1151,25 @@ void AutoTransformCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv } if (visualizer && visualizer->isVector()) { VectorObject* vector = visualizer->asVector(); + const float scale = 1 / at->getScale().z(); // See osg::AutoTransform::accept(osg::NodeVisitor&) or in later versions osg::AutoTransform::computeMatrix(const osg::NodeVisitor*) (since OSG commit 92092a5) + bool update = false; if (vector->getAutoScaleCancellationRequired()) { vector->setAutoScaleCancellationRequired(false); - vector->setScaleTransf(1 / at->getScale().z()); // See osg::AutoTransform::accept(osg::NodeVisitor&) or in later versions osg::AutoTransform::computeMatrix(const osg::NodeVisitor*) (since OSG commit 92092a5) + vector->setAutoRadiusScaleCancellation(scale); + vector->setAutoLengthScaleCancellation(scale); + update = true; + } else if (vector->isLengthScaleInvariant() && !vector->isRadiusScaleInvariant()) { + if (vector->getAutoRadiusScaleCancellation() != scale) { + vector->setAutoRadiusScaleCancellation(scale); + update = true; + } + } else if (vector->isRadiusScaleInvariant() && !vector->isLengthScaleInvariant()) { + if (vector->getAutoLengthScaleCancellation() != scale) { + vector->setAutoLengthScaleCancellation(scale); + update = true; + } + } + if (update) { _visualization->getBaseData()->updateVisualizer(vector); } } @@ -1394,14 +1407,17 @@ void OSGScene::setUpScene(std::vector& vectors) { for (VectorObject& vector : vectors) { + const bool isScaleInvariant = vector.isLengthScaleInvariant() || vector.isRadiusScaleInvariant(); + const bool isDrawnOnTop = vector.isDrawnOnTop(); + osg::ref_ptr transf = new AutoTransformVisualizer(&vector); transf->setName(vector._id); transf->setAutoRotateMode(osg::AutoTransform::NO_ROTATION); transf->setAutoScaleTransitionWidthRatio(0); - transf->setAutoScaleToScreen(vector.isScaleInvariant()); - transf->setCullingActive(!vector.isScaleInvariant()); // Work-around for osg::AutoTransform::setAutoScaleToScreen(bool) (see OSG commit 5c48904) - transf->getOrCreateStateSet()->setMode(GL_NORMALIZE, vector.isScaleInvariant() ? osg::StateAttribute::ON : osg::StateAttribute::OFF); - transf->getOrCreateStateSet()->setRenderBinDetails(VectorObject::kAutoScaleRenderBinNum - !vector.isDrawnOnTop(), VectorObject::kAutoScaleRenderBinName); + transf->setAutoScaleToScreen(isScaleInvariant); + transf->setCullingActive(!isScaleInvariant); // Work-around for osg::AutoTransform::setAutoScaleToScreen(bool) (see OSG commit 5c48904) + transf->getOrCreateStateSet()->setMode(GL_NORMALIZE, isScaleInvariant ? osg::StateAttribute::ON : osg::StateAttribute::OFF); + transf->getOrCreateStateSet()->setRenderBinDetails(VectorObject::kAutoScaleRenderBinNum - !isDrawnOnTop, VectorObject::kAutoScaleRenderBinName); transf->addCullCallback(_atCullCallback.get()); osg::ref_ptr shapeDraw0 = new osg::ShapeDrawable(); // shaft cylinder diff --git a/OMEdit/OMEditLIB/Animation/Visualization.h b/OMEdit/OMEditLIB/Animation/Visualization.h index 5aec8fdec82..177722332a3 100644 --- a/OMEdit/OMEditLIB/Animation/Visualization.h +++ b/OMEdit/OMEditLIB/Animation/Visualization.h @@ -45,6 +45,7 @@ #include // must be included before OSG headers #include +#include #include #include #include