mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0027764: Visualization - add functionality for animation of 3D camera and interactive objects
Added classes AIS_Animation, AIS_AnimationCamera, AIS_AnimationObjectLocatio. Draw Harness command vanimation has been modified to manage animation timeline. Command vfit has been extended with option -noupdate. Formatting of vviewparams command output has been improved. Functionality of commands vlocreset, vlocmove, vloctranslate, vlocrotate, vlocmirror, vlocscale has been merged into vlocation/vsetlocation. vlocation now can print the current local transformation of the object. v3d/ivtk test group does not call vfit anymore. Fixed misprint in test cases bugs/vis/bug24623_3 and bug25532.
This commit is contained in:
@@ -13,19 +13,18 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <gp_Pln.hxx>
|
||||
#include <Standard_ShortReal.hxx>
|
||||
|
||||
#include <Graphic3d_Camera.hxx>
|
||||
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_QuaternionNLerp.hxx>
|
||||
#include <gp_QuaternionSLerp.hxx>
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
#include <Graphic3d_WorldViewProjState.hxx>
|
||||
|
||||
#include <NCollection_Sequence.hxx>
|
||||
#include <Standard_ShortReal.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_Assert.hxx>
|
||||
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera,Standard_Transient)
|
||||
|
||||
namespace
|
||||
@@ -61,6 +60,16 @@ namespace
|
||||
Standard_Real aExp = Floor (aLogRadix);
|
||||
return FLT_EPSILON * Pow (FLT_RADIX, aExp);
|
||||
}
|
||||
|
||||
//! Convert camera definition to Ax3
|
||||
gp_Ax3 cameraToAx3 (const Graphic3d_Camera& theCamera)
|
||||
{
|
||||
const gp_Dir aBackDir(gp_Vec(theCamera.Center(), theCamera.Eye()));
|
||||
const gp_Dir anXAxis (theCamera.Up().Crossed (aBackDir));
|
||||
const gp_Dir anYAxis (aBackDir .Crossed (anXAxis));
|
||||
const gp_Dir aZAxis (anXAxis .Crossed (anYAxis));
|
||||
return gp_Ax3 (gp_Pnt (0.0, 0.0, 0.0), aZAxis, anXAxis);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -1298,3 +1307,84 @@ bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor,
|
||||
theZFar = aZFar;
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Interpolate
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
template<>
|
||||
Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
|
||||
Handle(Graphic3d_Camera)& theCamera) const
|
||||
{
|
||||
if (Abs (theT - 1.0) < Precision::Confusion())
|
||||
{
|
||||
// just copy end-point transformation
|
||||
theCamera->Copy (myEnd);
|
||||
return;
|
||||
}
|
||||
|
||||
theCamera->Copy (myStart);
|
||||
if (Abs (theT - 0.0) < Precision::Confusion())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// apply rotation
|
||||
{
|
||||
gp_Ax3 aCamStart = cameraToAx3 (*myStart);
|
||||
gp_Ax3 aCamEnd = cameraToAx3 (*myEnd);
|
||||
gp_Trsf aTrsfStart, aTrsfEnd;
|
||||
aTrsfStart.SetTransformation (aCamStart, gp::XOY());
|
||||
aTrsfEnd .SetTransformation (aCamEnd, gp::XOY());
|
||||
|
||||
gp_Quaternion aRotStart = aTrsfStart.GetRotation();
|
||||
gp_Quaternion aRotEnd = aTrsfEnd .GetRotation();
|
||||
gp_Quaternion aRotDelta = aRotEnd * aRotStart.Inverted();
|
||||
gp_Quaternion aRot = gp_QuaternionNLerp::Interpolate (gp_Quaternion(), aRotDelta, theT);
|
||||
gp_Trsf aTrsfRot;
|
||||
aTrsfRot.SetRotation (aRot);
|
||||
theCamera->Transform (aTrsfRot);
|
||||
}
|
||||
|
||||
// apply translation
|
||||
{
|
||||
gp_XYZ aCenter = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Center().XYZ(), myEnd->Center().XYZ(), theT);
|
||||
gp_XYZ anEye = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Eye().XYZ(), myEnd->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());
|
||||
if (aDeltaEye <= gp::Resolution())
|
||||
{
|
||||
anAnchor = anEye;
|
||||
aKc = 1.0;
|
||||
}
|
||||
else if (aDeltaCenter > gp::Resolution())
|
||||
{
|
||||
aKc = aDeltaCenter / (aDeltaCenter + aDeltaEye);
|
||||
|
||||
const gp_XYZ anAnchorStart = NCollection_Lerp<gp_XYZ>::Interpolate (myStart->Center().XYZ(), myStart->Eye().XYZ(), aKc);
|
||||
const gp_XYZ anAnchorEnd = NCollection_Lerp<gp_XYZ>::Interpolate (myEnd ->Center().XYZ(), myEnd ->Eye().XYZ(), aKc);
|
||||
anAnchor = NCollection_Lerp<gp_XYZ>::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 aDistEyeCenter = NCollection_Lerp<Standard_Real>::Interpolate (aDistEyeCenterStart, aDistEyeCenterEnd, theT);
|
||||
aCenter = anAnchor + aDirEyeToCenter.XYZ() * aDistEyeCenter * aKc;
|
||||
anEye = anAnchor - aDirEyeToCenter.XYZ() * aDistEyeCenter * (1.0 - aKc);
|
||||
|
||||
theCamera->SetCenter (aCenter);
|
||||
theCamera->SetEye (anEye);
|
||||
}
|
||||
|
||||
// apply scaling
|
||||
if (Abs(myStart->Scale() - myEnd->Scale()) > Precision::Confusion()
|
||||
&& myStart->IsOrthographic())
|
||||
{
|
||||
const Standard_Real aScale = NCollection_Lerp<Standard_Real>::Interpolate (myStart->Scale(), myEnd->Scale(), theT);
|
||||
theCamera->SetScale (aScale);
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
#include <Graphic3d_Vec3.hxx>
|
||||
#include <Graphic3d_WorldViewProjState.hxx>
|
||||
#include <NCollection_Lerp.hxx>
|
||||
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
@@ -665,4 +666,26 @@ public:
|
||||
|
||||
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.
|
||||
template<>
|
||||
Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (const double theT,
|
||||
Handle(Graphic3d_Camera)& theResult) const;
|
||||
typedef NCollection_Lerp<Handle(Graphic3d_Camera)> Graphic3d_CameraLerp;
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user