1 // Created on: 2013-05-29
2 // Created by: Anton POLETAEV
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Graphic3d_Camera.hxx>
19 #include <gp_QuaternionNLerp.hxx>
20 #include <gp_QuaternionSLerp.hxx>
21 #include <Graphic3d_Vec4.hxx>
22 #include <Graphic3d_WorldViewProjState.hxx>
23 #include <NCollection_Sequence.hxx>
24 #include <Standard_ShortReal.hxx>
25 #include <Standard_Atomic.hxx>
26 #include <Standard_Assert.hxx>
28 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Camera,Standard_Transient)
32 // (degrees -> radians) * 0.5
33 static const Standard_Real DTR_HALF = 0.5 * 0.0174532925;
35 // default property values
36 static const Standard_Real DEFAULT_ZNEAR = 0.001;
37 static const Standard_Real DEFAULT_ZFAR = 3000.0;
39 // atomic state counter
40 static volatile Standard_Integer THE_STATE_COUNTER = 0;
42 // z-range tolerance compatible with for floating point.
43 static Standard_Real zEpsilon()
48 // relative z-range tolerance compatible with for floating point.
49 static Standard_Real zEpsilon (const Standard_Real theValue)
51 Standard_Real anAbsValue = Abs (theValue);
52 if (anAbsValue <= (double)FLT_MIN)
56 Standard_Real aLogRadix = Log10 (anAbsValue) / Log10 (FLT_RADIX);
57 Standard_Real aExp = Floor (aLogRadix);
58 return FLT_EPSILON * Pow (FLT_RADIX, aExp);
61 //! Convert camera definition to Ax3
62 gp_Ax3 cameraToAx3 (const Graphic3d_Camera& theCamera)
64 const gp_Dir aBackDir = -theCamera.Direction();
65 const gp_Dir anXAxis (theCamera.Up().Crossed (aBackDir));
66 const gp_Dir anYAxis (aBackDir .Crossed (anXAxis));
67 const gp_Dir aZAxis (anXAxis .Crossed (anYAxis));
68 return gp_Ax3 (gp_Pnt (0.0, 0.0, 0.0), aZAxis, anXAxis);
72 // =======================================================================
73 // function : Graphic3d_Camera
75 // =======================================================================
76 Graphic3d_Camera::Graphic3d_Camera()
77 : myUp (0.0, 1.0, 0.0),
78 myDirection (0.0, 0.0, 1.0),
79 myEye (0.0, 0.0, -1500.0),
81 myAxialScale (1.0, 1.0, 1.0),
82 myProjType (Projection_Orthographic),
86 myFOVyTan (Tan (DTR_HALF * 45.0)),
87 myZNear (DEFAULT_ZNEAR),
88 myZFar (DEFAULT_ZFAR),
90 myIsZeroToOneDepth (false),
93 myZFocusType (FocusType_Relative),
95 myIODType (IODType_Relative),
96 myIsCustomProjMatM (false),
97 myIsCustomProjMatLR(false),
98 myIsCustomFrustomLR(false)
100 myWorldViewProjState.Initialize ((Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
101 (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
105 // =======================================================================
106 // function : Graphic3d_Camera
108 // =======================================================================
109 Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
110 : myUp (0.0, 1.0, 0.0),
111 myDirection (0.0, 0.0, 1.0),
112 myEye (0.0, 0.0, -1500.0),
114 myAxialScale (1.0, 1.0, 1.0),
115 myProjType (Projection_Orthographic),
119 myFOVyTan (Tan (DTR_HALF * 45.0)),
120 myZNear (DEFAULT_ZNEAR),
121 myZFar (DEFAULT_ZFAR),
123 myIsZeroToOneDepth (false),
126 myZFocusType (FocusType_Relative),
128 myIODType (IODType_Relative),
129 myIsCustomProjMatM (false),
130 myIsCustomProjMatLR(false),
131 myIsCustomFrustomLR(false)
133 myWorldViewProjState.Initialize (this);
138 // =======================================================================
139 // function : CopyMappingData
141 // =======================================================================
142 void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera)
144 SetZeroToOneDepth (theOtherCamera->IsZeroToOneDepth());
145 SetProjectionType (theOtherCamera->ProjectionType());
146 SetFOVy (theOtherCamera->FOVy());
147 SetFOV2d (theOtherCamera->FOV2d());
148 SetZRange (theOtherCamera->ZNear(), theOtherCamera->ZFar());
149 SetAspect (theOtherCamera->Aspect());
150 SetScale (theOtherCamera->Scale());
151 SetZFocus (theOtherCamera->ZFocusType(), theOtherCamera->ZFocus());
152 SetIOD (theOtherCamera->GetIODType(), theOtherCamera->IOD());
153 SetTile (theOtherCamera->myTile);
155 ResetCustomProjection();
156 if (theOtherCamera->IsCustomStereoProjection())
158 SetCustomStereoProjection (theOtherCamera->myCustomProjMatL,
159 theOtherCamera->myCustomHeadToEyeMatL,
160 theOtherCamera->myCustomProjMatR,
161 theOtherCamera->myCustomHeadToEyeMatR);
163 else if (theOtherCamera->IsCustomStereoFrustum())
165 SetCustomStereoFrustums (theOtherCamera->myCustomFrustumL, theOtherCamera->myCustomFrustumR);
167 if (theOtherCamera->IsCustomMonoProjection())
169 SetCustomMonoProjection (theOtherCamera->myCustomProjMatM);
173 // =======================================================================
174 // function : CopyOrientationData
176 // =======================================================================
177 void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera)
179 if (!myEye.IsEqual (theOtherCamera->Eye(), 0.0)
180 || !myUp.IsEqual (theOtherCamera->Up(), 0.0)
181 || !myDirection.IsEqual (theOtherCamera->Direction(), 0.0)
182 || myDistance != theOtherCamera->Distance())
184 myEye = theOtherCamera->Eye();
185 myUp = theOtherCamera->Up();
186 myDirection = theOtherCamera->Direction();
187 myDistance = theOtherCamera->Distance();
188 InvalidateOrientation();
190 SetAxialScale (theOtherCamera->AxialScale());
193 // =======================================================================
196 // =======================================================================
197 void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther)
199 CopyMappingData (theOther);
200 CopyOrientationData (theOther);
203 // =======================================================================
204 // function : SetIdentityOrientation
206 // =======================================================================
207 void Graphic3d_Camera::SetIdentityOrientation()
209 SetEyeAndCenter (gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(0.0, 0.0, -1.0));
210 SetUp (gp_Dir(0.0, 1.0, 0.0));
213 // =======================================================================
214 // function : MoveEyeTo
216 // =======================================================================
217 void Graphic3d_Camera::MoveEyeTo (const gp_Pnt& theEye)
219 if (myEye.IsEqual (theEye, 0.0))
225 InvalidateOrientation();
228 // =======================================================================
229 // function : SetEyeAndCenter
231 // =======================================================================
232 void Graphic3d_Camera::SetEyeAndCenter (const gp_Pnt& theEye,
233 const gp_Pnt& theCenter)
235 if (Eye() .IsEqual (theEye, 0.0)
236 && Center().IsEqual (theCenter, 0.0))
242 myDistance = theEye.Distance (theCenter);
243 if (myDistance > gp::Resolution())
245 myDirection = gp_Dir (theCenter.XYZ() - theEye.XYZ());
247 InvalidateOrientation();
250 // =======================================================================
253 // =======================================================================
254 void Graphic3d_Camera::SetEye (const gp_Pnt& theEye)
256 if (Eye().IsEqual (theEye, 0.0))
261 const gp_Pnt aCenter = Center();
263 myDistance = myEye.Distance (aCenter);
264 if (myDistance > gp::Resolution())
266 myDirection = gp_Dir (aCenter.XYZ() - myEye.XYZ());
268 InvalidateOrientation();
271 // =======================================================================
272 // function : SetCenter
274 // =======================================================================
275 void Graphic3d_Camera::SetCenter (const gp_Pnt& theCenter)
277 const Standard_Real aDistance = myEye.Distance (theCenter);
278 if (myDistance == aDistance)
283 myDistance = aDistance;
284 if (myDistance > gp::Resolution())
286 myDirection = gp_Dir (theCenter.XYZ() - myEye.XYZ());
288 InvalidateOrientation();
291 // =======================================================================
294 // =======================================================================
295 void Graphic3d_Camera::SetUp (const gp_Dir& theUp)
297 if (Up().IsEqual (theUp, 0.0))
303 InvalidateOrientation();
306 // =======================================================================
307 // function : SetAxialScale
309 // =======================================================================
310 void Graphic3d_Camera::SetAxialScale (const gp_XYZ& theAxialScale)
312 if (AxialScale().IsEqual (theAxialScale, 0.0))
317 myAxialScale = theAxialScale;
318 InvalidateOrientation();
321 // =======================================================================
322 // function : SetDistance
324 // =======================================================================
325 void Graphic3d_Camera::SetDistance (const Standard_Real theDistance)
327 if (myDistance == theDistance)
332 const gp_Pnt aCenter = Center();
333 myDistance = theDistance;
334 myEye = aCenter.XYZ() - myDirection.XYZ() * myDistance;
335 InvalidateOrientation();
338 // =======================================================================
339 // function : SetDirectionFromEye
341 // =======================================================================
342 void Graphic3d_Camera::SetDirectionFromEye (const gp_Dir& theDir)
344 if (myDirection.IsEqual (theDir, 0.0))
349 myDirection = theDir;
350 InvalidateOrientation();
353 // =======================================================================
354 // function : SetDirection
356 // =======================================================================
357 void Graphic3d_Camera::SetDirection (const gp_Dir& theDir)
359 if (myDirection.IsEqual (theDir, 0.0))
364 const gp_Pnt aCenter = Center();
365 myDirection = theDir;
366 myEye = aCenter.XYZ() - theDir.XYZ() * myDistance;
367 InvalidateOrientation();
370 // =======================================================================
371 // function : SetScale
373 // =======================================================================
374 void Graphic3d_Camera::SetScale (const Standard_Real theScale)
376 if (Scale() == theScale)
385 case Projection_Perspective :
386 case Projection_Stereo :
387 case Projection_MonoLeftEye :
388 case Projection_MonoRightEye :
390 Standard_Real aDistance = theScale * 0.5 / myFOVyTan;
391 SetDistance (aDistance);
398 InvalidateProjection();
401 // =======================================================================
404 // =======================================================================
405 Standard_Real Graphic3d_Camera::Scale() const
409 case Projection_Orthographic :
412 // case Projection_Perspective :
413 // case Projection_Stereo :
414 // case Projection_MonoLeftEye :
415 // case Projection_MonoRightEye :
417 return Distance() * 2.0 * myFOVyTan;
421 // =======================================================================
422 // function : SetProjectionType
424 // =======================================================================
425 void Graphic3d_Camera::SetProjectionType (const Projection theProjectionType)
427 Projection anOldType = ProjectionType();
429 if (anOldType == theProjectionType)
434 if (anOldType == Projection_Orthographic)
436 if (myZNear <= RealEpsilon())
438 myZNear = DEFAULT_ZNEAR;
440 if (myZFar <= RealEpsilon())
442 myZFar = DEFAULT_ZFAR;
446 myProjType = theProjectionType;
448 InvalidateProjection();
451 // =======================================================================
452 // function : SetFOVy
454 // =======================================================================
455 void Graphic3d_Camera::SetFOVy (const Standard_Real theFOVy)
457 if (FOVy() == theFOVy)
463 myFOVx = theFOVy * myAspect;
464 myFOVyTan = Tan(DTR_HALF * myFOVy);
466 InvalidateProjection();
469 // =======================================================================
470 // function : SetFOV2d
472 // =======================================================================
473 void Graphic3d_Camera::SetFOV2d (const Standard_Real theFOV)
475 if (FOV2d() == theFOV)
481 InvalidateProjection();
484 // =======================================================================
485 // function : SetZRange
487 // =======================================================================
488 void Graphic3d_Camera::SetZRange (const Standard_Real theZNear,
489 const Standard_Real theZFar)
491 Standard_ASSERT_RAISE (theZFar > theZNear, "ZFar should be greater than ZNear");
492 if (!IsOrthographic())
494 Standard_ASSERT_RAISE (theZNear > 0.0, "Only positive Z-Near is allowed for perspective camera");
495 Standard_ASSERT_RAISE (theZFar > 0.0, "Only positive Z-Far is allowed for perspective camera");
498 if (ZNear() == theZNear
499 && ZFar () == theZFar)
507 InvalidateProjection();
510 // =======================================================================
511 // function : SetAspect
513 // =======================================================================
514 void Graphic3d_Camera::SetAspect (const Standard_Real theAspect)
516 if (Aspect() == theAspect)
521 myAspect = theAspect;
522 myFOVx = myFOVy * theAspect;
524 InvalidateProjection();
527 // =======================================================================
528 // function : SetZFocus
530 // =======================================================================
531 void Graphic3d_Camera::SetZFocus(const FocusType theType, const Standard_Real theZFocus)
533 if (ZFocusType() == theType
534 && ZFocus () == theZFocus)
539 myZFocusType = theType;
540 myZFocus = theZFocus;
542 InvalidateProjection();
545 // =======================================================================
548 // =======================================================================
549 void Graphic3d_Camera::SetIOD (const IODType theType, const Standard_Real theIOD)
551 if (GetIODType() == theType
560 InvalidateProjection();
563 // =======================================================================
564 // function : SetTile
566 // =======================================================================
567 void Graphic3d_Camera::SetTile (const Graphic3d_CameraTile& theTile)
569 if (myTile == theTile)
575 InvalidateProjection();
578 // =======================================================================
579 // function : OrthogonalizeUp
581 // =======================================================================
582 void Graphic3d_Camera::OrthogonalizeUp()
584 SetUp (OrthogonalizedUp());
587 // =======================================================================
588 // function : OrthogonalizedUp
590 // =======================================================================
591 gp_Dir Graphic3d_Camera::OrthogonalizedUp() const
593 gp_Dir aDir = Direction();
594 gp_Dir aLeft = aDir.Crossed (Up());
596 // recompute up as: up = left x direction
597 return aLeft.Crossed (aDir);
600 // =======================================================================
601 // function : Transform
603 // =======================================================================
604 void Graphic3d_Camera::Transform (const gp_Trsf& theTrsf)
606 if (theTrsf.Form() == gp_Identity)
611 myUp .Transform (theTrsf);
612 myDirection.Transform (theTrsf);
613 myEye.Transform (theTrsf);
614 InvalidateOrientation();
617 // =======================================================================
618 // function : safePointCast
620 // =======================================================================
621 static Graphic3d_Vec4d safePointCast (const gp_Pnt& thePnt)
623 Standard_Real aLim = 1e15f;
625 // have to deal with values greater then max float
626 gp_Pnt aSafePoint = thePnt;
627 const Standard_Real aBigFloat = aLim * 0.1f;
628 if (Abs (aSafePoint.X()) > aLim)
629 aSafePoint.SetX (aSafePoint.X() >= 0 ? aBigFloat : -aBigFloat);
630 if (Abs (aSafePoint.Y()) > aLim)
631 aSafePoint.SetY (aSafePoint.Y() >= 0 ? aBigFloat : -aBigFloat);
632 if (Abs (aSafePoint.Z()) > aLim)
633 aSafePoint.SetZ (aSafePoint.Z() >= 0 ? aBigFloat : -aBigFloat);
636 Graphic3d_Vec4d aPnt (aSafePoint.X(), aSafePoint.Y(), aSafePoint.Z(), 1.0);
641 // =======================================================================
642 // function : Project
644 // =======================================================================
645 gp_Pnt Graphic3d_Camera::Project (const gp_Pnt& thePnt) const
647 const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
648 const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
650 // use compatible type of point
651 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
653 aPnt = aViewMx * aPnt; // convert to view coordinate space
654 aPnt = aProjMx * aPnt; // convert to projection coordinate space
656 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
658 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
661 // =======================================================================
662 // function : UnProject
664 // =======================================================================
665 gp_Pnt Graphic3d_Camera::UnProject (const gp_Pnt& thePnt) const
667 const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
668 const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
670 Graphic3d_Mat4d aInvView;
671 Graphic3d_Mat4d aInvProj;
673 // this case should never happen
674 if (!aViewMx.Inverted (aInvView) || !aProjMx.Inverted (aInvProj))
676 return gp_Pnt (0.0, 0.0, 0.0);
679 // use compatible type of point
680 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
682 aPnt = aInvProj * aPnt; // convert to view coordinate space
683 aPnt = aInvView * aPnt; // convert to world coordinate space
685 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
687 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
690 // =======================================================================
691 // function : ConvertView2Proj
693 // =======================================================================
694 gp_Pnt Graphic3d_Camera::ConvertView2Proj (const gp_Pnt& thePnt) const
696 const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
698 // use compatible type of point
699 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
701 aPnt = aProjMx * aPnt; // convert to projection coordinate space
703 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
705 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
708 // =======================================================================
709 // function : ConvertProj2View
711 // =======================================================================
712 gp_Pnt Graphic3d_Camera::ConvertProj2View (const gp_Pnt& thePnt) const
714 const Graphic3d_Mat4d& aProjMx = ProjectionMatrix();
716 Graphic3d_Mat4d aInvProj;
718 // this case should never happen, but...
719 if (!aProjMx.Inverted (aInvProj))
721 return gp_Pnt (0, 0, 0);
724 // use compatible type of point
725 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
727 aPnt = aInvProj * aPnt; // convert to view coordinate space
729 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
731 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
734 // =======================================================================
735 // function : ConvertWorld2View
737 // =======================================================================
738 gp_Pnt Graphic3d_Camera::ConvertWorld2View (const gp_Pnt& thePnt) const
740 const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
742 // use compatible type of point
743 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
745 aPnt = aViewMx * aPnt; // convert to view coordinate space
747 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
749 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
752 // =======================================================================
753 // function : ConvertView2World
755 // =======================================================================
756 gp_Pnt Graphic3d_Camera::ConvertView2World (const gp_Pnt& thePnt) const
758 const Graphic3d_Mat4d& aViewMx = OrientationMatrix();
760 Graphic3d_Mat4d aInvView;
762 if (!aViewMx.Inverted (aInvView))
764 return gp_Pnt(0, 0, 0);
767 // use compatible type of point
768 Graphic3d_Vec4d aPnt = safePointCast (thePnt);
770 aPnt = aInvView * aPnt; // convert to world coordinate space
772 const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
774 return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
777 // =======================================================================
778 // function : ViewDimensions
780 // =======================================================================
781 gp_XYZ Graphic3d_Camera::ViewDimensions (const Standard_Real theZValue) const
783 // view plane dimensions
784 Standard_Real aSize = IsOrthographic() ? myScale : (2.0 * theZValue * myFOVyTan);
785 Standard_Real aSizeX, aSizeY;
788 aSizeX = aSize * myAspect;
794 aSizeY = aSize / myAspect;
798 return gp_XYZ (aSizeX, aSizeY, myZFar - myZNear);
801 // =======================================================================
802 // function : Frustum
804 // =======================================================================
805 void Graphic3d_Camera::Frustum (gp_Pln& theLeft,
810 gp_Pln& theFar) const
812 gp_Vec aProjection = gp_Vec (Direction());
813 gp_Vec anUp = OrthogonalizedUp();
814 gp_Vec aSide = aProjection ^ anUp;
816 Standard_ASSERT_RAISE (
817 !aProjection.IsParallel (anUp, Precision::Angular()),
818 "Can not derive SIDE = PROJ x UP - directions are parallel");
820 theNear = gp_Pln (Eye().Translated (aProjection * ZNear()), aProjection);
821 theFar = gp_Pln (Eye().Translated (aProjection * ZFar()), -aProjection);
823 Standard_Real aHScaleHor = 0.0, aHScaleVer = 0.0;
826 aHScaleHor = Scale() * 0.5 * Aspect();
827 aHScaleVer = Scale() * 0.5;
831 aHScaleHor = Scale() * 0.5;
832 aHScaleVer = Scale() * 0.5 / Aspect();
835 gp_Pnt aPntLeft = Center().Translated (aHScaleHor * -aSide);
836 gp_Pnt aPntRight = Center().Translated (aHScaleHor * aSide);
837 gp_Pnt aPntBottom = Center().Translated (aHScaleVer * -anUp);
838 gp_Pnt aPntTop = Center().Translated (aHScaleVer * anUp);
840 gp_Vec aDirLeft = aSide;
841 gp_Vec aDirRight = -aSide;
842 gp_Vec aDirBottom = anUp;
843 gp_Vec aDirTop = -anUp;
844 if (!IsOrthographic())
846 Standard_Real aHFOVHor = ATan (Tan (DTR_HALF * FOVy()) * Aspect());
847 Standard_Real aHFOVVer = DTR_HALF * FOVy();
848 aDirLeft.Rotate (gp_Ax1 (gp::Origin(), anUp), aHFOVHor);
849 aDirRight.Rotate (gp_Ax1 (gp::Origin(), anUp), -aHFOVHor);
850 aDirBottom.Rotate (gp_Ax1 (gp::Origin(), aSide), -aHFOVVer);
851 aDirTop.Rotate (gp_Ax1 (gp::Origin(), aSide), aHFOVVer);
854 theLeft = gp_Pln (aPntLeft, aDirLeft);
855 theRight = gp_Pln (aPntRight, aDirRight);
856 theBottom = gp_Pln (aPntBottom, aDirBottom);
857 theTop = gp_Pln (aPntTop, aDirTop);
860 // =======================================================================
861 // function : OrientationMatrix
863 // =======================================================================
864 const Graphic3d_Mat4d& Graphic3d_Camera::OrientationMatrix() const
866 return UpdateOrientation (myMatricesD).Orientation;
869 // =======================================================================
870 // function : OrientationMatrixF
872 // =======================================================================
873 const Graphic3d_Mat4& Graphic3d_Camera::OrientationMatrixF() const
875 return UpdateOrientation (myMatricesF).Orientation;
878 // =======================================================================
879 // function : ProjectionMatrix
881 // =======================================================================
882 const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionMatrix() const
884 return UpdateProjection (myMatricesD).MProjection;
887 // =======================================================================
888 // function : ProjectionMatrixF
890 // =======================================================================
891 const Graphic3d_Mat4& Graphic3d_Camera::ProjectionMatrixF() const
893 return UpdateProjection (myMatricesF).MProjection;
896 // =======================================================================
897 // function : ProjectionStereoLeft
899 // =======================================================================
900 const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoLeft() const
902 return UpdateProjection (myMatricesD).LProjection;
905 // =======================================================================
906 // function : ProjectionStereoLeftF
908 // =======================================================================
909 const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoLeftF() const
911 return UpdateProjection (myMatricesF).LProjection;
914 // =======================================================================
915 // function : ProjectionStereoRight
917 // =======================================================================
918 const Graphic3d_Mat4d& Graphic3d_Camera::ProjectionStereoRight() const
920 return UpdateProjection (myMatricesD).RProjection;
923 // =======================================================================
924 // function : ProjectionStereoRightF
926 // =======================================================================
927 const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoRightF() const
929 return UpdateProjection (myMatricesF).RProjection;
932 // =======================================================================
933 // function : ResetCustomProjection
935 // =======================================================================
936 void Graphic3d_Camera::ResetCustomProjection()
938 if (myIsCustomFrustomLR
939 || myIsCustomProjMatLR
940 || myIsCustomProjMatM)
942 myIsCustomFrustomLR = false;
943 myIsCustomProjMatLR = false;
944 myIsCustomProjMatM = false;
945 InvalidateProjection();
949 // =======================================================================
950 // function : StereoProjection
952 // =======================================================================
953 void Graphic3d_Camera::StereoProjection (Graphic3d_Mat4d& theProjL,
954 Graphic3d_Mat4d& theHeadToEyeL,
955 Graphic3d_Mat4d& theProjR,
956 Graphic3d_Mat4d& theHeadToEyeR) const
958 stereoProjection (theProjL, theHeadToEyeL, theProjR, theHeadToEyeR);
961 // =======================================================================
962 // function : StereoProjectionF
964 // =======================================================================
965 void Graphic3d_Camera::StereoProjectionF (Graphic3d_Mat4& theProjL,
966 Graphic3d_Mat4& theHeadToEyeL,
967 Graphic3d_Mat4& theProjR,
968 Graphic3d_Mat4& theHeadToEyeR) const
970 stereoProjection (theProjL, theHeadToEyeL, theProjR, theHeadToEyeR);
973 // =======================================================================
974 // function : stereoProjection
976 // =======================================================================
977 template <typename Elem_t>
978 void Graphic3d_Camera::stereoProjection (NCollection_Mat4<Elem_t>& theProjL,
979 NCollection_Mat4<Elem_t>& theHeadToEyeL,
980 NCollection_Mat4<Elem_t>& theProjR,
981 NCollection_Mat4<Elem_t>& theHeadToEyeR) const
983 if (myIsCustomProjMatLR)
985 theProjL .ConvertFrom (myCustomProjMatL);
986 theHeadToEyeL.ConvertFrom (myCustomHeadToEyeMatL);
987 theProjR .ConvertFrom (myCustomProjMatR);
988 theHeadToEyeR.ConvertFrom (myCustomHeadToEyeMatR);
992 NCollection_Mat4<Elem_t> aDummy;
993 computeProjection (aDummy, theProjL, theProjR, false);
995 const Standard_Real aIOD = myIODType == IODType_Relative
1000 // X translation to cancel parallax
1001 theHeadToEyeL.InitIdentity();
1002 theHeadToEyeL.SetColumn (3, NCollection_Vec3<Elem_t> (Elem_t ( 0.5 * aIOD), Elem_t (0.0), Elem_t (0.0)));
1003 theHeadToEyeR.InitIdentity();
1004 theHeadToEyeR.SetColumn (3, NCollection_Vec3<Elem_t> (Elem_t (-0.5 * aIOD), Elem_t (0.0), Elem_t (0.0)));
1008 // =======================================================================
1009 // function : SetCustomStereoFrustums
1011 // =======================================================================
1012 void Graphic3d_Camera::SetCustomStereoFrustums (const Aspect_FrustumLRBT<Standard_Real>& theFrustumL,
1013 const Aspect_FrustumLRBT<Standard_Real>& theFrustumR)
1015 myCustomFrustumL = theFrustumL;
1016 myCustomFrustumR = theFrustumR;
1017 myIsCustomFrustomLR = true;
1018 myIsCustomProjMatLR = false;
1019 InvalidateProjection();
1022 // =======================================================================
1023 // function : SetCustomStereoProjection
1025 // =======================================================================
1026 void Graphic3d_Camera::SetCustomStereoProjection (const Graphic3d_Mat4d& theProjL,
1027 const Graphic3d_Mat4d& theHeadToEyeL,
1028 const Graphic3d_Mat4d& theProjR,
1029 const Graphic3d_Mat4d& theHeadToEyeR)
1031 myCustomProjMatL = theProjL;
1032 myCustomProjMatR = theProjR;
1033 myCustomHeadToEyeMatL = theHeadToEyeL;
1034 myCustomHeadToEyeMatR = theHeadToEyeR;
1035 myIsCustomProjMatLR = true;
1036 myIsCustomFrustomLR = false;
1037 InvalidateProjection();
1040 // =======================================================================
1041 // function : SetCustomMonoProjection
1043 // =======================================================================
1044 void Graphic3d_Camera::SetCustomMonoProjection (const Graphic3d_Mat4d& theProj)
1046 myCustomProjMatM = theProj;
1047 myIsCustomProjMatM = true;
1048 InvalidateProjection();
1051 // =======================================================================
1052 // function : computeProjection
1054 // =======================================================================
1055 template <typename Elem_t>
1056 void Graphic3d_Camera::computeProjection (NCollection_Mat4<Elem_t>& theProjM,
1057 NCollection_Mat4<Elem_t>& theProjL,
1058 NCollection_Mat4<Elem_t>& theProjR,
1059 bool theToAddHeadToEye) const
1061 theProjM.InitIdentity();
1062 theProjL.InitIdentity();
1063 theProjR.InitIdentity();
1065 // sets top of frustum based on FOVy and near clipping plane
1066 Elem_t aScale = static_cast<Elem_t> (myScale);
1067 Elem_t aZNear = static_cast<Elem_t> (myZNear);
1068 Elem_t aZFar = static_cast<Elem_t> (myZFar);
1069 Elem_t anAspect = static_cast<Elem_t> (myAspect);
1070 Elem_t aDXHalf = 0.0, aDYHalf = 0.0;
1071 if (IsOrthographic())
1073 aDXHalf = aDYHalf = aScale * Elem_t (0.5);
1077 aDXHalf = aDYHalf = aZNear * Elem_t (myFOVyTan);
1082 aDXHalf *= anAspect;
1086 aDYHalf /= anAspect;
1089 // sets right of frustum based on aspect ratio
1090 Aspect_FrustumLRBT<Elem_t> anLRBT;
1091 anLRBT.Left = -aDXHalf;
1092 anLRBT.Right = aDXHalf;
1093 anLRBT.Bottom = -aDYHalf;
1094 anLRBT.Top = aDYHalf;
1096 Elem_t aIOD = myIODType == IODType_Relative
1097 ? static_cast<Elem_t> (myIOD * Distance())
1098 : static_cast<Elem_t> (myIOD);
1100 Elem_t aFocus = myZFocusType == FocusType_Relative
1101 ? static_cast<Elem_t> (myZFocus * Distance())
1102 : static_cast<Elem_t> (myZFocus);
1104 if (myTile.IsValid())
1106 const Elem_t aDXFull = Elem_t(2) * aDXHalf;
1107 const Elem_t aDYFull = Elem_t(2) * aDYHalf;
1108 const Graphic3d_Vec2i anOffset = myTile.OffsetLowerLeft();
1109 anLRBT.Left = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
1110 anLRBT.Right = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x() + myTile.TileSize.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
1111 anLRBT.Bottom = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
1112 anLRBT.Top = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y() + myTile.TileSize.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
1115 if (myIsCustomProjMatM)
1117 theProjM.ConvertFrom (myCustomProjMatM);
1121 case Projection_Orthographic:
1123 if (!myIsCustomProjMatM)
1125 orthoProj (theProjM, anLRBT, aZNear, aZFar);
1129 case Projection_Perspective:
1131 if (!myIsCustomProjMatM)
1133 perspectiveProj (theProjM, anLRBT, aZNear, aZFar);
1137 case Projection_MonoLeftEye:
1138 case Projection_MonoRightEye:
1139 case Projection_Stereo:
1141 if (!myIsCustomProjMatM)
1143 perspectiveProj (theProjM, anLRBT, aZNear, aZFar);
1145 if (myIsCustomProjMatLR)
1147 if (theToAddHeadToEye)
1149 theProjL.ConvertFrom (myCustomProjMatL * myCustomHeadToEyeMatL);
1150 theProjR.ConvertFrom (myCustomProjMatR * myCustomHeadToEyeMatR);
1154 theProjL.ConvertFrom (myCustomProjMatL);
1155 theProjR.ConvertFrom (myCustomProjMatR);
1158 else if (myIsCustomFrustomLR)
1160 anLRBT = Aspect_FrustumLRBT<Elem_t> (myCustomFrustumL).Multiplied (aZNear);
1161 perspectiveProj (theProjL, anLRBT, aZNear, aZFar);
1163 anLRBT = Aspect_FrustumLRBT<Elem_t> (myCustomFrustumR).Multiplied (aZNear);
1164 perspectiveProj (theProjR, anLRBT, aZNear, aZFar);
1168 stereoEyeProj (theProjL,
1169 anLRBT, aZNear, aZFar, aIOD, aFocus,
1171 stereoEyeProj (theProjR,
1172 anLRBT, aZNear, aZFar, aIOD, aFocus,
1176 if (theToAddHeadToEye
1177 && !myIsCustomProjMatLR
1178 && aIOD != Elem_t (0.0))
1180 // X translation to cancel parallax
1181 theProjL.Translate (NCollection_Vec3<Elem_t> (Elem_t ( 0.5) * aIOD, Elem_t (0.0), Elem_t (0.0)));
1182 theProjR.Translate (NCollection_Vec3<Elem_t> (Elem_t (-0.5) * aIOD, Elem_t (0.0), Elem_t (0.0)));
1187 if (myProjType == Projection_MonoLeftEye)
1189 theProjM = theProjL;
1191 else if (myProjType == Projection_MonoRightEye)
1193 theProjM = theProjR;
1197 // =======================================================================
1198 // function : UpdateOrientation
1200 // =======================================================================
1201 template <typename Elem_t>
1202 Graphic3d_Camera::TransformMatrices<Elem_t>&
1203 Graphic3d_Camera::UpdateOrientation (TransformMatrices<Elem_t>& theMatrices) const
1205 if (theMatrices.IsOrientationValid())
1207 return theMatrices; // for inline accessors
1210 theMatrices.InitOrientation();
1212 NCollection_Vec3<Elem_t> anEye (static_cast<Elem_t> (myEye.X()),
1213 static_cast<Elem_t> (myEye.Y()),
1214 static_cast<Elem_t> (myEye.Z()));
1216 NCollection_Vec3<Elem_t> aViewDir (static_cast<Elem_t> (myDirection.X()),
1217 static_cast<Elem_t> (myDirection.Y()),
1218 static_cast<Elem_t> (myDirection.Z()));
1220 NCollection_Vec3<Elem_t> anUp (static_cast<Elem_t> (myUp.X()),
1221 static_cast<Elem_t> (myUp.Y()),
1222 static_cast<Elem_t> (myUp.Z()));
1224 NCollection_Vec3<Elem_t> anAxialScale (static_cast<Elem_t> (myAxialScale.X()),
1225 static_cast<Elem_t> (myAxialScale.Y()),
1226 static_cast<Elem_t> (myAxialScale.Z()));
1228 LookOrientation (anEye, aViewDir, anUp, anAxialScale, theMatrices.Orientation);
1230 return theMatrices; // for inline accessors
1233 // =======================================================================
1234 // function : InvalidateProjection
1236 // =======================================================================
1237 void Graphic3d_Camera::InvalidateProjection()
1239 myMatricesD.ResetProjection();
1240 myMatricesF.ResetProjection();
1241 myWorldViewProjState.ProjectionState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
1244 // =======================================================================
1245 // function : InvalidateOrientation
1247 // =======================================================================
1248 void Graphic3d_Camera::InvalidateOrientation()
1250 myMatricesD.ResetOrientation();
1251 myMatricesF.ResetOrientation();
1252 myWorldViewProjState.WorldViewState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
1255 // =======================================================================
1256 // function : orthoProj
1258 // =======================================================================
1259 template <typename Elem_t>
1260 void Graphic3d_Camera::orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
1261 const Aspect_FrustumLRBT<Elem_t>& theLRBT,
1262 const Elem_t theNear,
1263 const Elem_t theFar) const
1266 theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theLRBT.Right - theLRBT.Left);
1267 theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
1268 theOutMx.ChangeValue (0, 2) = Elem_t (0.0);
1269 theOutMx.ChangeValue (0, 3) = - (theLRBT.Right + theLRBT.Left) / (theLRBT.Right - theLRBT.Left);
1272 theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
1273 theOutMx.ChangeValue (1, 1) = Elem_t (2.0) / (theLRBT.Top - theLRBT.Bottom);
1274 theOutMx.ChangeValue (1, 2) = Elem_t (0.0);
1275 theOutMx.ChangeValue (1, 3) = - (theLRBT.Top + theLRBT.Bottom) / (theLRBT.Top - theLRBT.Bottom);
1278 theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
1279 theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
1280 if (myIsZeroToOneDepth)
1282 theOutMx.ChangeValue (2, 2) = Elem_t (-1.0) / (theFar - theNear);
1283 theOutMx.ChangeValue (2, 3) = -theNear / (theFar - theNear);
1287 theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
1288 theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
1292 theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
1293 theOutMx.ChangeValue (3, 1) = Elem_t (0.0);
1294 theOutMx.ChangeValue (3, 2) = Elem_t (0.0);
1295 theOutMx.ChangeValue (3, 3) = Elem_t (1.0);
1298 // =======================================================================
1299 // function : PerspectiveProj
1301 // =======================================================================
1302 template <typename Elem_t>
1303 void Graphic3d_Camera::perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
1304 const Aspect_FrustumLRBT<Elem_t>& theLRBT,
1305 const Elem_t theNear,
1306 const Elem_t theFar) const
1309 theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theLRBT.Right - theLRBT.Left);
1310 theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
1311 theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
1312 theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
1315 theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
1316 theOutMx.ChangeValue (1, 1) = (Elem_t (2.0) * theNear) / (theLRBT.Top - theLRBT.Bottom);
1317 theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
1318 theOutMx.ChangeValue (3, 1) = Elem_t (0.0);
1321 theOutMx.ChangeValue (0, 2) = (theLRBT.Right + theLRBT.Left) / (theLRBT.Right - theLRBT.Left);
1322 theOutMx.ChangeValue (1, 2) = (theLRBT.Top + theLRBT.Bottom) / (theLRBT.Top - theLRBT.Bottom);
1323 if (myIsZeroToOneDepth)
1325 theOutMx.ChangeValue (2, 2) = theFar / (theNear - theFar);
1329 theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
1331 theOutMx.ChangeValue (3, 2) = Elem_t (-1.0);
1334 theOutMx.ChangeValue (0, 3) = Elem_t (0.0);
1335 theOutMx.ChangeValue (1, 3) = Elem_t (0.0);
1336 if (myIsZeroToOneDepth)
1338 theOutMx.ChangeValue (2, 3) = -(theFar * theNear) / (theFar - theNear);
1342 theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
1344 theOutMx.ChangeValue (3, 3) = Elem_t (0.0);
1347 // =======================================================================
1348 // function : StereoEyeProj
1350 // =======================================================================
1351 template <typename Elem_t>
1352 void Graphic3d_Camera::stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
1353 const Aspect_FrustumLRBT<Elem_t>& theLRBT,
1354 const Elem_t theNear,
1355 const Elem_t theFar,
1356 const Elem_t theIOD,
1357 const Elem_t theZFocus,
1358 const Aspect_Eye theEyeIndex) const
1360 Elem_t aDx = theEyeIndex == Aspect_Eye_Left ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
1361 Elem_t aDXStereoShift = aDx * theNear / theZFocus;
1363 // construct eye projection matrix
1364 Aspect_FrustumLRBT<Elem_t> aLRBT = theLRBT;
1365 aLRBT.Left = theLRBT.Left + aDXStereoShift;
1366 aLRBT.Right = theLRBT.Right + aDXStereoShift;
1367 perspectiveProj (theOutMx, aLRBT, theNear, theFar);
1370 // =======================================================================
1371 // function : LookOrientation
1373 // =======================================================================
1374 template <typename Elem_t>
1375 void Graphic3d_Camera::LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
1376 const NCollection_Vec3<Elem_t>& theFwdDir,
1377 const NCollection_Vec3<Elem_t>& theUpDir,
1378 const NCollection_Vec3<Elem_t>& theAxialScale,
1379 NCollection_Mat4<Elem_t>& theOutMx)
1381 NCollection_Vec3<Elem_t> aForward = theFwdDir;
1382 aForward.Normalize();
1384 // side = forward x up
1385 NCollection_Vec3<Elem_t> aSide = NCollection_Vec3<Elem_t>::Cross (aForward, theUpDir);
1388 // recompute up as: up = side x forward
1389 NCollection_Vec3<Elem_t> anUp = NCollection_Vec3<Elem_t>::Cross (aSide, aForward);
1391 NCollection_Mat4<Elem_t> aLookMx;
1392 aLookMx.SetRow (0, aSide);
1393 aLookMx.SetRow (1, anUp);
1394 aLookMx.SetRow (2, -aForward);
1396 theOutMx.InitIdentity();
1397 theOutMx.Multiply (aLookMx);
1398 theOutMx.Translate (-theEye);
1400 NCollection_Mat4<Elem_t> anAxialScaleMx;
1401 anAxialScaleMx.ChangeValue (0, 0) = theAxialScale.x();
1402 anAxialScaleMx.ChangeValue (1, 1) = theAxialScale.y();
1403 anAxialScaleMx.ChangeValue (2, 2) = theAxialScale.z();
1405 theOutMx.Multiply (anAxialScaleMx);
1408 // =======================================================================
1409 // function : FitMinMax
1411 // =======================================================================
1412 bool Graphic3d_Camera::FitMinMax (const Bnd_Box& theBox,
1413 const Standard_Real theResolution,
1414 const bool theToEnlargeIfLine)
1416 // Check bounding box for validness
1417 if (theBox.IsVoid())
1419 return false; // bounding box is out of bounds...
1422 // Apply "axial scaling" to the bounding points.
1423 // It is not the best approach to make this scaling as a part of fit all operation,
1424 // but the axial scale is integrated into camera orientation matrix and the other
1425 // option is to perform frustum plane adjustment algorithm in view camera space,
1426 // which will lead to a number of additional world-view space conversions and
1427 // loosing precision as well.
1428 const gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (myAxialScale);
1429 const gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (myAxialScale);
1430 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
1432 return false; // nothing to fit all
1435 // Prepare camera frustum planes.
1436 gp_Pln aFrustumPlaneArray[6];
1437 NCollection_Array1<gp_Pln> aFrustumPlane (aFrustumPlaneArray[0], 1, 6);
1438 Frustum (aFrustumPlane[1], aFrustumPlane[2], aFrustumPlane[3],
1439 aFrustumPlane[4], aFrustumPlane[5], aFrustumPlane[6]);
1441 // Prepare camera up, side, direction vectors.
1442 const gp_Dir aCamUp = OrthogonalizedUp();
1443 const gp_Dir aCamDir = Direction();
1444 const gp_Dir aCamSide = aCamDir ^ aCamUp;
1446 // Prepare scene bounding box parameters.
1447 const gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
1449 gp_Pnt aBndCornerArray[8];
1450 NCollection_Array1<gp_Pnt> aBndCorner (aBndCornerArray[0], 1, 8);
1451 aBndCorner[1].SetCoord (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
1452 aBndCorner[2].SetCoord (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
1453 aBndCorner[3].SetCoord (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
1454 aBndCorner[4].SetCoord (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
1455 aBndCorner[5].SetCoord (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
1456 aBndCorner[6].SetCoord (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
1457 aBndCorner[7].SetCoord (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
1458 aBndCorner[8].SetCoord (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
1460 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
1461 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
1462 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
1463 // set up perspective-correct camera projection matching the bounding box.
1464 // These steps support non-asymmetric transformations of view-projection space provided by camera.
1465 // The zooming can be done by calculating view plane size matching the bounding box at center of
1466 // the bounding box. The only limitation here is that the scale of camera should define size of
1467 // its view plane passing through the camera center, and the center of camera should be on the
1468 // same line with the center of bounding box.
1470 // The following method is applied:
1471 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
1472 // 2) Determine new location of frustum planes, "matching" the bounding box.
1473 // 3) Determine new camera projection vector using the normalized asymmetry.
1474 // 4) Determine new zooming in view space.
1476 // 1. Determine normalized projection asymmetry (if any).
1477 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane[1].Axis().Direction()))
1478 - Tan ((-aCamSide).Angle (aFrustumPlane[2].Axis().Direction()));
1479 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane[3].Axis().Direction()))
1480 - Tan ((-aCamUp) .Angle (aFrustumPlane[4].Axis().Direction()));
1482 // 2. Determine how far should be the frustum planes placed from center
1483 // of bounding box, in order to match the bounding box closely.
1484 Standard_Real aFitDistanceArray[6];
1485 NCollection_Array1<Standard_Real> aFitDistance (aFitDistanceArray[0], 1, 6);
1486 aFitDistance.Init (0.0);
1487 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
1489 // Measure distances from center of bounding box to its corners towards the frustum plane.
1490 const gp_Dir& aPlaneN = aFrustumPlane[anI].Axis().Direction();
1492 Standard_Real& aFitDist = aFitDistance[anI];
1493 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
1495 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner[aJ]).Dot (aPlaneN));
1498 // The center of camera is placed on the same line with center of bounding box.
1499 // The view plane section crosses the bounding box at its center.
1500 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
1501 // into view section size between the point and the frustum plane.
1503 // /|\ right half of frame //
1505 // point o<-- distance * coeff -->//---- (view plane section)
1514 aFitDistance[1] *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane[1].Axis().Direction())), 2.0));
1515 aFitDistance[2] *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane[2].Axis().Direction())), 2.0));
1516 aFitDistance[3] *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane[3].Axis().Direction())), 2.0));
1517 aFitDistance[4] *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane[4].Axis().Direction())), 2.0));
1518 aFitDistance[5] *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane[5].Axis().Direction())), 2.0));
1519 aFitDistance[6] *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane[6].Axis().Direction())), 2.0));
1521 Standard_Real aViewSizeXv = aFitDistance[1] + aFitDistance[2];
1522 Standard_Real aViewSizeYv = aFitDistance[3] + aFitDistance[4];
1523 Standard_Real aViewSizeZv = aFitDistance[5] + aFitDistance[6];
1525 // 3. Place center of camera on the same line with center of bounding
1526 // box applying corresponding projection asymmetry (if any).
1527 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
1528 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
1529 Standard_Real anOffsetXv = (aFitDistance[2] - aFitDistance[1]) * 0.5 + anAssymXv;
1530 Standard_Real anOffsetYv = (aFitDistance[4] - aFitDistance[3]) * 0.5 + anAssymYv;
1531 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
1532 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
1533 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
1535 gp_Trsf aCenterTrsf;
1536 aCenterTrsf.SetTranslation (Center(), aCamNewCenter);
1537 Transform (aCenterTrsf);
1538 SetDistance (aFitDistance[6] + aFitDistance[5]);
1540 if (aViewSizeXv < theResolution
1541 && aViewSizeYv < theResolution)
1543 // Bounding box collapses to a point or thin line going in depth of the screen
1544 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
1546 return false; // This is just one point or line and zooming has no effect.
1549 // Looking along line and "theToEnlargeIfLine" is requested.
1550 // Fit view to see whole scene on rotation.
1551 aViewSizeXv = aViewSizeZv;
1552 aViewSizeYv = aViewSizeZv;
1555 const Standard_Real anAspect = Aspect();
1558 SetScale (Max (aViewSizeXv / anAspect, aViewSizeYv));
1562 SetScale (Max (aViewSizeXv, aViewSizeYv * anAspect));
1567 //=============================================================================
1568 //function : ZFitAll
1570 //=============================================================================
1571 bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor,
1572 const Bnd_Box& theMinMax,
1573 const Bnd_Box& theGraphicBB,
1574 Standard_Real& theZNear,
1575 Standard_Real& theZFar) const
1577 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1579 // Method changes zNear and zFar parameters of camera so as to fit graphical structures
1580 // by their graphical boundaries. It precisely fits min max boundaries of primary application
1581 // objects (second argument), while it can sacrifice the real graphical boundaries of the
1582 // scene with infinite or helper objects (third argument) for the sake of perspective projection.
1583 if (theGraphicBB.IsVoid())
1585 theZNear = DEFAULT_ZNEAR;
1586 theZFar = DEFAULT_ZFAR;
1590 // Measure depth of boundary points from camera eye.
1591 NCollection_Sequence<gp_Pnt> aPntsToMeasure;
1593 Standard_Real aGraphicBB[6];
1594 theGraphicBB.Get (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2], aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]);
1596 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]));
1597 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]));
1598 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]));
1599 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]));
1600 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]));
1601 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]));
1602 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]));
1603 aPntsToMeasure.Append (gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]));
1605 Standard_Boolean isFiniteMinMax = !theMinMax.IsVoid() && !theMinMax.IsWhole();
1609 Standard_Real aMinMax[6];
1610 theMinMax.Get (aMinMax[0], aMinMax[1], aMinMax[2], aMinMax[3], aMinMax[4], aMinMax[5]);
1612 aPntsToMeasure.Append (gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]));
1613 aPntsToMeasure.Append (gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]));
1614 aPntsToMeasure.Append (gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]));
1615 aPntsToMeasure.Append (gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]));
1616 aPntsToMeasure.Append (gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]));
1617 aPntsToMeasure.Append (gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]));
1618 aPntsToMeasure.Append (gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]));
1619 aPntsToMeasure.Append (gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]));
1622 // Camera eye plane.
1623 gp_Dir aCamDir = Direction();
1624 gp_Pnt aCamEye = myEye;
1625 gp_Pln aCamPln (aCamEye, aCamDir);
1627 Standard_Real aModelMinDist = RealLast();
1628 Standard_Real aModelMaxDist = RealFirst();
1629 Standard_Real aGraphMinDist = RealLast();
1630 Standard_Real aGraphMaxDist = RealFirst();
1632 const gp_XYZ& anAxialScale = myAxialScale;
1634 // Get minimum and maximum distances to the eye plane.
1635 Standard_Integer aCounter = 0;
1636 NCollection_Sequence<gp_Pnt>::Iterator aPntIt(aPntsToMeasure);
1637 for (; aPntIt.More(); aPntIt.Next())
1639 gp_Pnt aMeasurePnt = aPntIt.Value();
1641 aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
1642 aMeasurePnt.Y() * anAxialScale.Y(),
1643 aMeasurePnt.Z() * anAxialScale.Z());
1645 Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
1647 // Check if the camera is intruded into the scene.
1648 gp_Vec aVecToMeasurePnt (aCamEye, aMeasurePnt);
1649 if (aVecToMeasurePnt.Magnitude() > gp::Resolution()
1650 && aCamDir.IsOpposite (aVecToMeasurePnt, M_PI * 0.5))
1655 // The first eight points are from theGraphicBB, the last eight points are from theMinMax (can be absent).
1656 Standard_Real& aChangeMinDist = aCounter >= 8 ? aModelMinDist : aGraphMinDist;
1657 Standard_Real& aChangeMaxDist = aCounter >= 8 ? aModelMaxDist : aGraphMaxDist;
1658 aChangeMinDist = Min (aDistance, aChangeMinDist);
1659 aChangeMaxDist = Max (aDistance, aChangeMaxDist);
1663 // Compute depth of bounding box center.
1664 Standard_Real aMidDepth = (aGraphMinDist + aGraphMaxDist) * 0.5;
1665 Standard_Real aHalfDepth = (aGraphMaxDist - aGraphMinDist) * 0.5;
1667 // Compute enlarged or shrank near and far z ranges.
1668 Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
1669 Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
1671 if (!IsOrthographic())
1673 // Everything is behind the perspective camera.
1674 if (aZFar < zEpsilon())
1676 theZNear = DEFAULT_ZNEAR;
1677 theZFar = DEFAULT_ZFAR;
1683 // Consider clipping errors due to double to single precision floating-point conversion.
1686 // Model to view transformation performs translation of points against eye position
1687 // in three dimensions. Both point coordinate and eye position values are converted from
1688 // double to single precision floating point numbers producing conversion errors.
1689 // Epsilon (Mod) * 3.0 should safely compensate precision error for z coordinate after
1690 // translation assuming that the:
1691 // Epsilon (Eye.Mod()) * 3.0 > Epsilon (Eye.X()) + Epsilon (Eye.Y()) + Epsilon (Eye.Z()).
1692 Standard_Real aEyeConf = 3.0 * zEpsilon (myEye.XYZ().Modulus());
1694 // Model to view transformation performs rotation of points according to view direction.
1695 // New z coordinate is computed as a multiplication of point's x, y, z coordinates by the
1696 // "forward" direction vector's x, y, z coordinates. Both point's and "z" direction vector's
1697 // values are converted from double to single precision floating point numbers producing
1698 // conversion errors.
1699 // Epsilon (Mod) * 6.0 should safely compensate the precision errors for the multiplication
1700 // of point coordinates by direction vector.
1701 gp_Pnt aGraphicMin = theGraphicBB.CornerMin();
1702 gp_Pnt aGraphicMax = theGraphicBB.CornerMax();
1704 Standard_Real aModelConf = 6.0 * zEpsilon (aGraphicMin.XYZ().Modulus()) +
1705 6.0 * zEpsilon (aGraphicMax.XYZ().Modulus());
1707 // Compensate floating point conversion errors by increasing zNear, zFar to avoid clipping.
1708 aZNear -= zEpsilon (aZNear) + aEyeConf + aModelConf;
1709 aZFar += zEpsilon (aZFar) + aEyeConf + aModelConf;
1711 if (!IsOrthographic())
1713 // For perspective projection, the value of z in normalized device coordinates is non-linear
1714 // function of eye z coordinate. For fixed-point depth representation resolution of z in
1715 // model-view space will grow towards zFar plane and its scale depends mostly on how far is zNear
1716 // against camera's eye. The purpose of the code below is to select most appropriate zNear distance
1717 // to balance between clipping (less zNear, more chances to observe closely small models without clipping)
1718 // and resolution of depth. A well applicable criteria to this is a ratio between resolution of z at center
1719 // of model boundaries and the distance to that center point. The ratio is chosen empirically and validated
1720 // by tests database. It is considered to be ~0.001 (0.1%) for 24 bit depth buffer, for less depth bitness
1721 // the zNear will be placed similarly giving lower resolution.
1722 // Approximation of the formula for respectively large z range is:
1723 // zNear = [z * (1 + k) / (k * c)],
1725 // z - distance to center of model boundaries;
1726 // k - chosen ratio, c - capacity of depth buffer;
1727 // k = 0.001, k * c = 1677.216, (1 + k) / (k * c) ~ 5.97E-4
1729 // The function uses center of model boundaries computed from "theMinMax" boundaries (instead of using real
1730 // graphical boundaries of all displayed objects). That means that it can sacrifice resolution of presentation
1731 // of non primary ("infinite") application graphical objects in favor of better perspective projection of the
1732 // small applicative objects measured with "theMinMax" values.
1733 Standard_Real aZRange = isFiniteMinMax ? aModelMaxDist - aModelMinDist : aGraphMaxDist - aGraphMinDist;
1734 Standard_Real aZMin = isFiniteMinMax ? aModelMinDist : aGraphMinDist;
1735 Standard_Real aZ = aZMin < 0 ? aZRange / 2.0 : aZRange / 2.0 + aZMin;
1736 Standard_Real aZNearMin = aZ * 5.97E-4;
1737 if (aZNear < aZNearMin)
1739 // Clip zNear according to the minimum value matching the quality.
1748 // Compensate zNear conversion errors for perspective projection.
1749 aZNear -= aZFar * zEpsilon (aZNear) / (aZFar - zEpsilon (aZNear));
1752 // Compensate zFar conversion errors for perspective projection.
1753 aZFar += zEpsilon (aZFar);
1755 // Ensure that after all the zNear is not a negative value.
1756 if (aZNear < zEpsilon())
1758 aZNear = zEpsilon();
1760 Standard_ASSERT_RAISE (aZFar > aZNear, "ZFar should be greater than ZNear");
1765 Standard_ASSERT_RAISE (aZFar > aZNear, "ZFar should be greater than ZNear");
1769 //=============================================================================
1770 //function : Interpolate
1772 //=============================================================================
1773 void Graphic3d_Camera::Interpolate (const Handle(Graphic3d_Camera)& theStart,
1774 const Handle(Graphic3d_Camera)& theEnd,
1776 Handle(Graphic3d_Camera)& theCamera)
1778 if (Abs (theT - 1.0) < Precision::Confusion())
1780 // just copy end-point transformation
1781 theCamera->Copy (theEnd);
1785 theCamera->Copy (theStart);
1786 if (Abs (theT - 0.0) < Precision::Confusion())
1793 gp_Ax3 aCamStart = cameraToAx3 (*theStart);
1794 gp_Ax3 aCamEnd = cameraToAx3 (*theEnd);
1795 gp_Trsf aTrsfStart, aTrsfEnd;
1796 aTrsfStart.SetTransformation (aCamStart, gp::XOY());
1797 aTrsfEnd .SetTransformation (aCamEnd, gp::XOY());
1799 gp_Quaternion aRotStart = aTrsfStart.GetRotation();
1800 gp_Quaternion aRotEnd = aTrsfEnd .GetRotation();
1801 gp_Quaternion aRotDelta = aRotEnd * aRotStart.Inverted();
1802 gp_Quaternion aRot = gp_QuaternionNLerp::Interpolate (gp_Quaternion(), aRotDelta, theT);
1804 aTrsfRot.SetRotation (aRot);
1805 theCamera->Transform (aTrsfRot);
1808 // apply translation
1810 gp_XYZ aCenter = NCollection_Lerp<gp_XYZ>::Interpolate (theStart->Center().XYZ(), theEnd->Center().XYZ(), theT);
1811 gp_XYZ anEye = NCollection_Lerp<gp_XYZ>::Interpolate (theStart->Eye().XYZ(), theEnd->Eye().XYZ(), theT);
1812 gp_XYZ anAnchor = aCenter;
1813 Standard_Real aKc = 0.0;
1815 const Standard_Real aDeltaCenter = theStart->Center().Distance (theEnd->Center());
1816 const Standard_Real aDeltaEye = theStart->Eye() .Distance (theEnd->Eye());
1817 if (aDeltaEye <= gp::Resolution())
1822 else if (aDeltaCenter > gp::Resolution())
1824 aKc = aDeltaCenter / (aDeltaCenter + aDeltaEye);
1826 const gp_XYZ anAnchorStart = NCollection_Lerp<gp_XYZ>::Interpolate (theStart->Center().XYZ(), theStart->Eye().XYZ(), aKc);
1827 const gp_XYZ anAnchorEnd = NCollection_Lerp<gp_XYZ>::Interpolate (theEnd ->Center().XYZ(), theEnd ->Eye().XYZ(), aKc);
1828 anAnchor = NCollection_Lerp<gp_XYZ>::Interpolate (anAnchorStart, anAnchorEnd, theT);
1831 const gp_Vec aDirEyeToCenter = theCamera->Direction();
1832 const Standard_Real aDistEyeCenterStart = theStart->Eye().Distance (theStart->Center());
1833 const Standard_Real aDistEyeCenterEnd = theEnd ->Eye().Distance (theEnd ->Center());
1834 const Standard_Real aDistEyeCenter = NCollection_Lerp<Standard_Real>::Interpolate (aDistEyeCenterStart, aDistEyeCenterEnd, theT);
1835 aCenter = anAnchor + aDirEyeToCenter.XYZ() * aDistEyeCenter * aKc;
1836 anEye = anAnchor - aDirEyeToCenter.XYZ() * aDistEyeCenter * (1.0 - aKc);
1838 theCamera->SetEyeAndCenter (anEye, aCenter);
1842 if (Abs(theStart->Scale() - theEnd->Scale()) > Precision::Confusion()
1843 && theStart->IsOrthographic())
1845 const Standard_Real aScale = NCollection_Lerp<Standard_Real>::Interpolate (theStart->Scale(), theEnd->Scale(), theT);
1846 theCamera->SetScale (aScale);
1850 //=======================================================================
1851 //function : FrustumPoints
1853 //=======================================================================
1854 void Graphic3d_Camera::FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePoints,
1855 const Graphic3d_Mat4d& theModelWorld) const
1857 if (thePoints.Length() != FrustumVerticesNB)
1859 thePoints.Resize (0, FrustumVerticesNB, Standard_False);
1862 const Graphic3d_Mat4d& aProjectionMat = ProjectionMatrix();
1863 const Graphic3d_Mat4d aWorldViewMat = OrientationMatrix() * theModelWorld;
1865 Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
1866 Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
1867 Standard_Real aNear = myZNear, aFar = myZFar;
1868 if (!IsOrthographic())
1870 // handle perspective projection
1872 nLeft = aNear * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
1873 nRight = aNear * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
1874 nTop = aNear * (aProjectionMat.GetValue (1, 2) + 1.0) / aProjectionMat.GetValue (1, 1);
1875 nBottom = aNear * (aProjectionMat.GetValue (1, 2) - 1.0) / aProjectionMat.GetValue (1, 1);
1877 fLeft = aFar * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
1878 fRight = aFar * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
1879 fTop = aFar * (aProjectionMat.GetValue (1, 2) + 1.0) / aProjectionMat.GetValue (1, 1);
1880 fBottom = aFar * (aProjectionMat.GetValue (1, 2) - 1.0) / aProjectionMat.GetValue (1, 1);
1884 // handle orthographic projection
1886 nLeft = ( 1.0 + aProjectionMat.GetValue (0, 3)) / (-aProjectionMat.GetValue (0, 0));
1888 nRight = ( 1.0 - aProjectionMat.GetValue (0, 3)) / aProjectionMat.GetValue (0, 0);
1890 nTop = ( 1.0 - aProjectionMat.GetValue (1, 3)) / aProjectionMat.GetValue (1, 1);
1892 nBottom = (-1.0 - aProjectionMat.GetValue (1, 3)) / aProjectionMat.GetValue (1, 1);
1896 Graphic3d_Vec4d aLeftTopNear (nLeft, nTop, -aNear, 1.0), aRightBottomFar (fRight, fBottom, -aFar, 1.0);
1897 Graphic3d_Vec4d aLeftBottomNear (nLeft, nBottom, -aNear, 1.0), aRightTopFar (fRight, fTop, -aFar, 1.0);
1898 Graphic3d_Vec4d aRightBottomNear (nRight, nBottom, -aNear, 1.0), aLeftTopFar (fLeft, fTop, -aFar, 1.0);
1899 Graphic3d_Vec4d aRightTopNear (nRight, nTop, -aNear, 1.0), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0);
1901 Graphic3d_Mat4d anInvWorldView;
1902 aWorldViewMat.Inverted (anInvWorldView);
1904 Graphic3d_Vec4d aTmpPnt;
1905 aTmpPnt = anInvWorldView * aLeftTopNear;
1906 thePoints.SetValue (FrustumVert_LeftTopNear, aTmpPnt.xyz() / aTmpPnt.w());
1907 aTmpPnt = anInvWorldView * aRightBottomFar;
1908 thePoints.SetValue (FrustumVert_RightBottomFar, aTmpPnt.xyz() / aTmpPnt.w());
1909 aTmpPnt = anInvWorldView * aLeftBottomNear;
1910 thePoints.SetValue (FrustumVert_LeftBottomNear, aTmpPnt.xyz() / aTmpPnt.w());
1911 aTmpPnt = anInvWorldView * aRightTopFar;
1912 thePoints.SetValue (FrustumVert_RightTopFar, aTmpPnt.xyz() / aTmpPnt.w());
1913 aTmpPnt = anInvWorldView * aRightBottomNear;
1914 thePoints.SetValue (FrustumVert_RightBottomNear, aTmpPnt.xyz() / aTmpPnt.w());
1915 aTmpPnt = anInvWorldView * aLeftTopFar;
1916 thePoints.SetValue (FrustumVert_LeftTopFar, aTmpPnt.xyz() / aTmpPnt.w());
1917 aTmpPnt = anInvWorldView * aRightTopNear;
1918 thePoints.SetValue (FrustumVert_RightTopNear, aTmpPnt.xyz() / aTmpPnt.w());
1919 aTmpPnt = anInvWorldView * aLeftBottomFar;
1920 thePoints.SetValue (FrustumVert_LeftBottomFar, aTmpPnt.xyz() / aTmpPnt.w());
1923 //=======================================================================
1924 //function : DumpJson
1926 //=======================================================================
1927 void Graphic3d_Camera::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1929 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1931 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myUp)
1932 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myDirection)
1933 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myEye)
1935 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDistance)
1937 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myAxialScale)
1938 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myProjType)
1939 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFOVy)
1940 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZNear)
1941 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZFar)
1942 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAspect)
1944 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myScale)
1945 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZFocus)
1946 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZFocusType)
1948 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIOD)
1949 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIODType)
1951 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myTile)
1952 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myMatricesD)
1953 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myMatricesF)
1954 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myWorldViewProjState)