diff --git a/src/Graphic3d/Graphic3d_Camera.cxx b/src/Graphic3d/Graphic3d_Camera.cxx index e1056d6a58..0392b3ec0c 100644 --- a/src/Graphic3d/Graphic3d_Camera.cxx +++ b/src/Graphic3d/Graphic3d_Camera.cxx @@ -1576,18 +1576,19 @@ bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, //function : Interpolate //purpose : //============================================================================= -template<> -Standard_EXPORT void NCollection_Lerp::Interpolate (const double theT, - Handle(Graphic3d_Camera)& theCamera) const +void Graphic3d_Camera::Interpolate (const Handle(Graphic3d_Camera)& theStart, + const Handle(Graphic3d_Camera)& theEnd, + const double theT, + Handle(Graphic3d_Camera)& theCamera) { if (Abs (theT - 1.0) < Precision::Confusion()) { // just copy end-point transformation - theCamera->Copy (myEnd); + theCamera->Copy (theEnd); return; } - theCamera->Copy (myStart); + theCamera->Copy (theStart); if (Abs (theT - 0.0) < Precision::Confusion()) { return; @@ -1595,8 +1596,8 @@ Standard_EXPORT void NCollection_Lerp::Interpolate (co // apply rotation { - gp_Ax3 aCamStart = cameraToAx3 (*myStart); - gp_Ax3 aCamEnd = cameraToAx3 (*myEnd); + gp_Ax3 aCamStart = cameraToAx3 (*theStart); + gp_Ax3 aCamEnd = cameraToAx3 (*theEnd); gp_Trsf aTrsfStart, aTrsfEnd; aTrsfStart.SetTransformation (aCamStart, gp::XOY()); aTrsfEnd .SetTransformation (aCamEnd, gp::XOY()); @@ -1612,13 +1613,13 @@ Standard_EXPORT void NCollection_Lerp::Interpolate (co // apply translation { - gp_XYZ aCenter = NCollection_Lerp::Interpolate (myStart->Center().XYZ(), myEnd->Center().XYZ(), theT); - gp_XYZ anEye = NCollection_Lerp::Interpolate (myStart->Eye().XYZ(), myEnd->Eye().XYZ(), theT); + gp_XYZ aCenter = NCollection_Lerp::Interpolate (theStart->Center().XYZ(), theEnd->Center().XYZ(), theT); + gp_XYZ anEye = NCollection_Lerp::Interpolate (theStart->Eye().XYZ(), theEnd->Eye().XYZ(), theT); gp_XYZ anAnchor = aCenter; Standard_Real aKc = 0.0; - const Standard_Real aDeltaCenter = myStart->Center().Distance (myEnd->Center()); - const Standard_Real aDeltaEye = myStart->Eye() .Distance (myEnd->Eye()); + const Standard_Real aDeltaCenter = theStart->Center().Distance (theEnd->Center()); + const Standard_Real aDeltaEye = theStart->Eye() .Distance (theEnd->Eye()); if (aDeltaEye <= gp::Resolution()) { anAnchor = anEye; @@ -1628,14 +1629,14 @@ Standard_EXPORT void NCollection_Lerp::Interpolate (co { aKc = aDeltaCenter / (aDeltaCenter + aDeltaEye); - const gp_XYZ anAnchorStart = NCollection_Lerp::Interpolate (myStart->Center().XYZ(), myStart->Eye().XYZ(), aKc); - const gp_XYZ anAnchorEnd = NCollection_Lerp::Interpolate (myEnd ->Center().XYZ(), myEnd ->Eye().XYZ(), aKc); + const gp_XYZ anAnchorStart = NCollection_Lerp::Interpolate (theStart->Center().XYZ(), theStart->Eye().XYZ(), aKc); + const gp_XYZ anAnchorEnd = NCollection_Lerp::Interpolate (theEnd ->Center().XYZ(), theEnd ->Eye().XYZ(), aKc); anAnchor = NCollection_Lerp::Interpolate (anAnchorStart, anAnchorEnd, theT); } const gp_Vec aDirEyeToCenter = theCamera->Direction(); - const Standard_Real aDistEyeCenterStart = myStart->Eye().Distance (myStart->Center()); - const Standard_Real aDistEyeCenterEnd = myEnd ->Eye().Distance (myEnd ->Center()); + const Standard_Real aDistEyeCenterStart = theStart->Eye().Distance (theStart->Center()); + const Standard_Real aDistEyeCenterEnd = theEnd ->Eye().Distance (theEnd ->Center()); const Standard_Real aDistEyeCenter = NCollection_Lerp::Interpolate (aDistEyeCenterStart, aDistEyeCenterEnd, theT); aCenter = anAnchor + aDirEyeToCenter.XYZ() * aDistEyeCenter * aKc; anEye = anAnchor - aDirEyeToCenter.XYZ() * aDistEyeCenter * (1.0 - aKc); @@ -1644,10 +1645,10 @@ Standard_EXPORT void NCollection_Lerp::Interpolate (co } // apply scaling - if (Abs(myStart->Scale() - myEnd->Scale()) > Precision::Confusion() - && myStart->IsOrthographic()) + if (Abs(theStart->Scale() - theEnd->Scale()) > Precision::Confusion() + && theStart->IsOrthographic()) { - const Standard_Real aScale = NCollection_Lerp::Interpolate (myStart->Scale(), myEnd->Scale(), theT); + const Standard_Real aScale = NCollection_Lerp::Interpolate (theStart->Scale(), theEnd->Scale(), theT); theCamera->SetScale (aScale); } } diff --git a/src/Graphic3d/Graphic3d_Camera.hxx b/src/Graphic3d/Graphic3d_Camera.hxx index 5a819622fc..57b382d930 100644 --- a/src/Graphic3d/Graphic3d_Camera.hxx +++ b/src/Graphic3d/Graphic3d_Camera.hxx @@ -147,6 +147,35 @@ public: IODType_Relative }; +public: + + //! Linear interpolation tool for camera orientation and position. + //! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently. + //! @sa Graphic3d_CameraLerp + //! + //! Eye/Center interpolation is performed through defining an anchor point in-between Center and Eye. + //! The anchor position is defined as point near to the camera point which has smaller translation part. + //! The main idea is to keep the distance between Center and Eye + //! (which will change if Center and Eye translation will be interpolated independently). + //! E.g.: + //! - When both Center and Eye are moved at the same vector -> both will be just translated by straight line; + //! - When Center is not moved -> camera Eye will move around Center through arc; + //! - When Eye is not moved -> camera Center will move around Eye through arc; + //! - When both Center and Eye are move by different vectors -> transformation will be something in between, + //! and will try interpolate linearly the distance between Center and Eye. + //! + //! This transformation might be not in line with user expectations. + //! In this case, application might define intermediate camera positions for interpolation or implement own interpolation logic. + //! + //! @param theStart [in] initial camera position + //! @param theEnd [in] final camera position + //! @param theT [in] step between initial and final positions within [0,1] range + //! @param theCamera [out] interpolation result + Standard_EXPORT static void Interpolate (const Handle(Graphic3d_Camera)& theStart, + const Handle(Graphic3d_Camera)& theEnd, + const double theT, + Handle(Graphic3d_Camera)& theCamera); + public: //! Default constructor. @@ -836,24 +865,17 @@ DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient) //! Linear interpolation tool for camera orientation and position. //! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently. -//! -//! Eye/Center interpolation is performed through defining an anchor point in-between Center and Eye. -//! The anchor position is defined as point near to the camera point which has smaller translation part. -//! The main idea is to keep the distance between Center and Eye -//! (which will change if Center and Eye translation will be interpolated independently). -//! E.g.: -//! - When both Center and Eye are moved at the same vector -> both will be just translated by straight line -//! - When Center is not moved -> camera Eye will move around Center through arc -//! - When Eye is not moved -> camera Center will move around Eye through arc -//! - When both Center and Eye are move by different vectors -> transformation will be something in between, -//! and will try interpolate linearly the distance between Center and Eye. -//! -//! This transformation might be not in line with user expectations. -//! In this case, application might define intermediate camera positions for interpolation -//! or implement own interpolation logic. +//! @sa Graphic3d_Camera::Interpolate() template<> -Standard_EXPORT void NCollection_Lerp::Interpolate (const double theT, - Handle(Graphic3d_Camera)& theResult) const; +inline void NCollection_Lerp::Interpolate (const double theT, + Handle(Graphic3d_Camera)& theResult) const +{ + Graphic3d_Camera::Interpolate (myStart, myEnd, theT, theResult); +} + +//! Linear interpolation tool for camera orientation and position. +//! This tool interpolates camera parameters scale, eye, center, rotation (up and direction vectors) independently. +//! @sa Graphic3d_Camera::Interpolate() typedef NCollection_Lerp Graphic3d_CameraLerp; #endif