1
0
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:
kgv
2016-10-27 17:20:38 +03:00
committed by apn
parent f204ec4c37
commit 1beb58d745
38 changed files with 2908 additions and 611 deletions

View File

@@ -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);
}
}

View File

@@ -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