Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-18 10:07:43

0001 // Created on: 2015-06-18
0002 // Created by: Anton POLETAEV
0003 // Copyright (c) 2015 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _Graphic3d_TransformPers_HeaderFile
0017 #define _Graphic3d_TransformPers_HeaderFile
0018 
0019 #include <Aspect_TypeOfTriedronPosition.hxx>
0020 #include <BVH_Box.hxx>
0021 #include <Graphic3d_Camera.hxx>
0022 #include <Graphic3d_TransformUtils.hxx>
0023 #include <Graphic3d_TransModeFlags.hxx>
0024 #include <Graphic3d_Vec.hxx>
0025 #include <NCollection_Mat4.hxx>
0026 
0027 DEFINE_STANDARD_HANDLE(Graphic3d_TransformPers, Standard_Transient)
0028 
0029 //! Transformation Persistence definition.
0030 //!
0031 //! Transformation Persistence defines a mutable Local Coordinate system which depends on camera position,
0032 //! so that visual appearance of the object becomes partially immutable while camera moves.
0033 //! Object visually preserves particular property such as size, placement, rotation or their combination.
0034 //!
0035 //! Graphic3d_TMF_ZoomPers, Graphic3d_TMF_RotatePers and Graphic3d_TMF_ZoomRotatePers define Local Coordinate system
0036 //! having origin in specified anchor point defined in World Coordinate system,
0037 //! while Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d define origin as 2D offset from screen corner in pixels.
0038 //!
0039 //! Graphic3d_TMF_2d, Graphic3d_TMF_TriedronPers and Graphic3d_TMF_ZoomPers defines Local Coordinate system where length units are pixels.
0040 //! Beware that Graphic3d_RenderingParams::ResolutionRatio() will be ignored!
0041 //! For other Persistence flags, normal (world) length units will apply.
0042 //!
0043 //! WARNING: Graphic3d_TMF_None is not permitted for defining instance of this class - NULL handle should be used for this purpose!
0044 class Graphic3d_TransformPers : public Standard_Transient
0045 {
0046   DEFINE_STANDARD_RTTIEXT(Graphic3d_TransformPers, Standard_Transient)
0047 public:
0048 
0049   //! Return true if specified mode is zoom/rotate transformation persistence.
0050   static Standard_Boolean IsZoomOrRotate (Graphic3d_TransModeFlags theMode)
0051   {
0052     return (theMode & (Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers)) != 0;
0053   }
0054 
0055   //! Return true if specified mode is 2d/trihedron transformation persistence.
0056   static Standard_Boolean IsTrihedronOr2d (Graphic3d_TransModeFlags theMode)
0057   {
0058     return (theMode & (Graphic3d_TMF_TriedronPers | Graphic3d_TMF_2d)) != 0;
0059   }
0060 
0061 public:
0062 
0063   //! Set transformation persistence.
0064   Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode)
0065   : myMode (theMode)
0066   {
0067     if (IsZoomOrRotate (theMode))
0068     {
0069       SetPersistence (theMode, gp_Pnt(0.0, 0.0, 0.0));
0070     }
0071     else if (IsTrihedronOr2d (theMode))
0072     {
0073       SetPersistence (theMode, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (0, 0));
0074     }
0075     else if (theMode == Graphic3d_TMF_CameraPers)
0076     {
0077       myMode = theMode;
0078     }
0079     else
0080     {
0081       throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0082     }
0083   }
0084 
0085   //! Set Zoom/Rotate transformation persistence with an anchor 3D point.
0086   //! Anchor point defines the origin of Local Coordinate system within World Coordinate system.
0087   //! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
0088   Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
0089                            const gp_Pnt& thePnt)
0090   : myMode (Graphic3d_TMF_None)
0091   {
0092     SetPersistence (theMode, thePnt);
0093   }
0094 
0095   //! Set 2d/trihedron transformation persistence with a corner and 2D offset.
0096   //! 2D offset defines the origin of Local Coordinate system as projection of 2D point on screen plane into World Coordinate system.
0097   //! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
0098   //! The offset is a positive displacement from the view corner in pixels.
0099   Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
0100                            const Aspect_TypeOfTriedronPosition theCorner,
0101                            const Graphic3d_Vec2i& theOffset = Graphic3d_Vec2i (0, 0))
0102   : myMode (Graphic3d_TMF_None)
0103   {
0104     SetPersistence (theMode, theCorner, theOffset);
0105   }
0106 
0107   //! Return true for Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers modes.
0108   Standard_Boolean IsZoomOrRotate() const { return IsZoomOrRotate (myMode); }
0109 
0110   //! Return true for Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d modes.
0111   Standard_Boolean IsTrihedronOr2d() const { return IsTrihedronOr2d (myMode); }
0112 
0113   //! Transformation persistence mode flags.
0114   Graphic3d_TransModeFlags Mode() const { return myMode; }
0115 
0116   //! Transformation persistence mode flags.
0117   Graphic3d_TransModeFlags Flags() const { return myMode; }
0118 
0119   //! Set Zoom/Rotate transformation persistence with an anchor 3D point.
0120   //! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
0121   void SetPersistence (const Graphic3d_TransModeFlags theMode,
0122                        const gp_Pnt& thePnt)
0123   {
0124     if (!IsZoomOrRotate (theMode))
0125     {
0126       throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0127     }
0128 
0129     myMode = theMode;
0130     myParams.Params3d.PntX = thePnt.X();
0131     myParams.Params3d.PntY = thePnt.Y();
0132     myParams.Params3d.PntZ = thePnt.Z();
0133   }
0134 
0135   //! Set 2d/trihedron transformation persistence with a corner and 2D offset.
0136   //! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
0137   void SetPersistence (const Graphic3d_TransModeFlags theMode,
0138                        const Aspect_TypeOfTriedronPosition theCorner,
0139                        const Graphic3d_Vec2i& theOffset)
0140   {
0141     if (!IsTrihedronOr2d (theMode))
0142     {
0143       throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
0144     }
0145 
0146     myMode = theMode;
0147     myParams.Params2d.Corner  = theCorner;
0148     myParams.Params2d.OffsetX = theOffset.x();
0149     myParams.Params2d.OffsetY = theOffset.y();
0150   }
0151 
0152 public:
0153 
0154   //! Return the anchor point for zoom/rotate transformation persistence.
0155   gp_Pnt AnchorPoint() const
0156   {
0157     if (!IsZoomOrRotate())
0158     {
0159       throw Standard_ProgramError("Graphic3d_TransformPers::AnchorPoint(), wrong persistence mode.");
0160     }
0161 
0162     return gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
0163   }
0164 
0165   //! Set the anchor point for zoom/rotate transformation persistence.
0166   void SetAnchorPoint (const gp_Pnt& thePnt)
0167   {
0168     if (!IsZoomOrRotate())
0169     {
0170       throw Standard_ProgramError("Graphic3d_TransformPers::SetAnchorPoint(), wrong persistence mode.");
0171     }
0172 
0173     myParams.Params3d.PntX = thePnt.X();
0174     myParams.Params3d.PntY = thePnt.Y();
0175     myParams.Params3d.PntZ = thePnt.Z();
0176   }
0177 
0178   //! Return the corner for 2d/trihedron transformation persistence.
0179   Aspect_TypeOfTriedronPosition Corner2d() const
0180   {
0181     if (!IsTrihedronOr2d())
0182     {
0183       throw Standard_ProgramError("Graphic3d_TransformPers::Corner2d(), wrong persistence mode.");
0184     }
0185 
0186     return myParams.Params2d.Corner;
0187   }
0188 
0189   //! Set the corner for 2d/trihedron transformation persistence.
0190   void SetCorner2d (const Aspect_TypeOfTriedronPosition thePos)
0191   {
0192     if (!IsTrihedronOr2d())
0193     {
0194       throw Standard_ProgramError("Graphic3d_TransformPers::SetCorner2d(), wrong persistence mode.");
0195     }
0196 
0197     myParams.Params2d.Corner = thePos;
0198   }
0199 
0200   //! Return the offset from the corner for 2d/trihedron transformation persistence.
0201   Graphic3d_Vec2i Offset2d() const
0202   {
0203     if (!IsTrihedronOr2d())
0204     {
0205       throw Standard_ProgramError("Graphic3d_TransformPers::Offset2d(), wrong persistence mode.");
0206     }
0207 
0208     return Graphic3d_Vec2i (myParams.Params2d.OffsetX, myParams.Params2d.OffsetY);
0209   }
0210 
0211   //! Set the offset from the corner for 2d/trihedron transformation persistence.
0212   void SetOffset2d (const Graphic3d_Vec2i& theOffset)
0213   {
0214     if (!IsTrihedronOr2d())
0215     {
0216       throw Standard_ProgramError("Graphic3d_TransformPers::SetOffset2d(), wrong persistence mode.");
0217     }
0218 
0219     myParams.Params2d.OffsetX = theOffset.x();
0220     myParams.Params2d.OffsetY = theOffset.y();
0221   }
0222 
0223 public:
0224 
0225   //! Find scale value based on the camera position and view dimensions
0226   //! @param theCamera [in] camera definition
0227   //! @param theViewportWidth [in] the width of viewport.
0228   //! @param theViewportHeight [in] the height of viewport.
0229   virtual Standard_Real persistentScale (const Handle(Graphic3d_Camera)& theCamera,
0230                                          const Standard_Integer theViewportWidth,
0231                                          const Standard_Integer theViewportHeight) const
0232   {
0233     (void )theViewportWidth;
0234     // use total size when tiling is active
0235     const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
0236 
0237     gp_Vec aVecToEye (theCamera->Direction());
0238     gp_Vec aVecToObj (theCamera->Eye(), gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ));
0239     const Standard_Real aFocus = aVecToObj.Dot (aVecToEye);
0240     const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0241     return Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0242   }
0243 
0244   //! Create orientation matrix based on camera and view dimensions.
0245   //! Default implementation locks rotation by nullifying rotation component.
0246   //! Camera and view dimensions are not used, by default.
0247   //! @param theCamera [in] camera definition
0248   //! @param theViewportWidth [in] the width of viewport
0249   //! @param theViewportHeight [in] the height of viewport
0250   virtual NCollection_Mat3<Standard_Real> persistentRotationMatrix (const Handle(Graphic3d_Camera)& theCamera,
0251                                                                     const Standard_Integer theViewportWidth,
0252                                                                     const Standard_Integer theViewportHeight) const
0253   {
0254     (void )theCamera;
0255     (void )theViewportWidth;
0256     (void )theViewportHeight;
0257 
0258     NCollection_Mat3<Standard_Real> aRotMat;
0259     return aRotMat;
0260   }
0261 
0262   //! Apply transformation to bounding box of presentation.
0263   //! @param theCamera [in] camera definition
0264   //! @param theProjection [in] the projection transformation matrix.
0265   //! @param theWorldView [in] the world view transformation matrix.
0266   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
0267   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
0268   //! @param theBoundingBox [in/out] the bounding box to transform.
0269   template<class T>
0270   void Apply (const Handle(Graphic3d_Camera)& theCamera,
0271               const NCollection_Mat4<T>& theProjection,
0272               const NCollection_Mat4<T>& theWorldView,
0273               const Standard_Integer theViewportWidth,
0274               const Standard_Integer theViewportHeight,
0275               Bnd_Box& theBoundingBox) const;
0276 
0277   //! Apply transformation to bounding box of presentation
0278   //! @param theCamera [in] camera definition
0279   //! @param theProjection [in] the projection transformation matrix.
0280   //! @param theWorldView [in] the world view transformation matrix.
0281   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
0282   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
0283   //! @param theBoundingBox [in/out] the bounding box to transform.
0284   template<class T>
0285   void Apply (const Handle(Graphic3d_Camera)& theCamera,
0286               const NCollection_Mat4<T>& theProjection,
0287               const NCollection_Mat4<T>& theWorldView,
0288               const Standard_Integer theViewportWidth,
0289               const Standard_Integer theViewportHeight,
0290               BVH_Box<T, 3>& theBoundingBox) const;
0291 
0292   //! Compute transformation.
0293   //! Computed matrix can be applied to model world transformation
0294   //! of an object to implement effect of transformation persistence.
0295   //! @param theCamera [in] camera definition
0296   //! @param theProjection [in] the projection transformation matrix.
0297   //! @param theWorldView [in] the world view transformation matrix.
0298   //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
0299   //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
0300   //! @return transformation matrix to be applied to model world transformation of an object.
0301   template<class T>
0302   NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
0303                                const NCollection_Mat4<T>& theProjection,
0304                                const NCollection_Mat4<T>& theWorldView,
0305                                const Standard_Integer theViewportWidth,
0306                                const Standard_Integer theViewportHeight) const;
0307 
0308   //! Apply transformation persistence on specified matrices.
0309   //! @param theCamera camera definition
0310   //! @param theProjection projection matrix to modify
0311   //! @param theWorldView  world-view matrix to modify
0312   //! @param theViewportWidth  viewport width
0313   //! @param theViewportHeight viewport height
0314   //! @param theAnchor if not NULL, overrides anchor point
0315   template<class T>
0316   void Apply (const Handle(Graphic3d_Camera)& theCamera,
0317               const NCollection_Mat4<T>& theProjection,
0318               NCollection_Mat4<T>& theWorldView,
0319               const Standard_Integer theViewportWidth,
0320               const Standard_Integer theViewportHeight,
0321               const gp_Pnt* theAnchor = NULL) const;
0322 
0323   //! Dumps the content of me into the stream
0324   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0325 
0326 private:
0327 
0328   //! 3D anchor point for zoom/rotate transformation persistence.
0329   struct PersParams3d
0330   {
0331     Standard_Real PntX;
0332     Standard_Real PntY;
0333     Standard_Real PntZ;
0334 
0335     //! Dumps the content of me into the stream
0336     Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0337   };
0338 
0339   //! 2d/trihedron transformation persistence parameters.
0340   struct PersParams2d
0341   {
0342     Standard_Integer OffsetX;
0343     Standard_Integer OffsetY;
0344     Aspect_TypeOfTriedronPosition Corner;
0345 
0346     //! Dumps the content of me into the stream
0347     Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0348   };
0349 
0350 private:
0351 
0352   Graphic3d_TransModeFlags myMode;  //!< Transformation persistence mode flags
0353   union
0354   {
0355     PersParams3d Params3d;
0356     PersParams2d Params2d;
0357   } myParams;
0358 
0359 };
0360 
0361 // =======================================================================
0362 // function : Apply
0363 // purpose  : Apply transformation to world view and projection matrices.
0364 // =======================================================================
0365 template<class T>
0366 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0367                                      const NCollection_Mat4<T>& theProjection,
0368                                      NCollection_Mat4<T>& theWorldView,
0369                                      const Standard_Integer theViewportWidth,
0370                                      const Standard_Integer theViewportHeight,
0371                                      const gp_Pnt* theAnchor) const
0372 {
0373   (void )theViewportWidth;
0374   (void )theProjection;
0375   if (myMode == Graphic3d_TMF_None
0376    || theViewportHeight == 0)
0377   {
0378     return;
0379   }
0380 
0381   // use total size when tiling is active
0382   const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
0383 
0384   // a small enough jitter compensation offset
0385   // to avoid image dragging within single pixel in corner cases
0386   const Standard_Real aJitterComp = 0.001;
0387   if (myMode == Graphic3d_TMF_TriedronPers)
0388   {
0389     // reset Z focus for trihedron persistence
0390     const Standard_Real aFocus = theCamera->IsOrthographic()
0391                                ? theCamera->Distance()
0392                                : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0393                                 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0394                                 : Standard_Real(theCamera->ZFocus()));
0395 
0396     // scale factor to pixels
0397     const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
0398     const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0399     const gp_Dir aForward = theCamera->Direction();
0400     gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
0401     if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0402     {
0403       const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
0404       const gp_Dir aSide   = aForward.Crossed (theCamera->Up());
0405       const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * theCamera->NDC2dOffsetX() - anOffsetX);
0406       if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0407       {
0408         aCenter += aDeltaX;
0409       }
0410       else
0411       {
0412         aCenter -= aDeltaX;
0413       }
0414     }
0415     if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0416     {
0417       const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
0418       const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * theCamera->NDC2dOffsetY() - anOffsetY);
0419       if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0420       {
0421         aCenter += aDeltaY;
0422       }
0423       else
0424       {
0425         aCenter -= aDeltaY;
0426       }
0427     }
0428 
0429     NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0430     Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
0431     Graphic3d_TransformUtils::Scale     (aWorldView, aScale,      aScale,      aScale);
0432     theWorldView.ConvertFrom (aWorldView);
0433     return;
0434   }
0435   else if (myMode == Graphic3d_TMF_2d)
0436   {
0437     const Standard_Real aFocus = theCamera->IsOrthographic()
0438                                ? theCamera->Distance()
0439                                : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
0440                                 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
0441                                 : Standard_Real(theCamera->ZFocus()));
0442 
0443     // scale factor to pixels
0444     const gp_XYZ        aViewDim = theCamera->ViewDimensions (aFocus);
0445     const Standard_Real aScale   = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
0446     gp_XYZ aCenter (0.0, 0.0, -aFocus);
0447     if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
0448     {
0449       aCenter.SetX (-aViewDim.X() * theCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
0450       if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
0451       {
0452         aCenter.SetX (-aCenter.X());
0453       }
0454     }
0455     if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
0456     {
0457       aCenter.SetY (-aViewDim.Y() * theCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
0458       if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
0459       {
0460         aCenter.SetY (-aCenter.Y());
0461       }
0462     }
0463 
0464     theWorldView.InitIdentity();
0465     Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
0466     Graphic3d_TransformUtils::Scale     (theWorldView, T(aScale),      T(aScale),      T(aScale));
0467     return;
0468   }
0469   else if ((myMode & Graphic3d_TMF_CameraPers) != 0)
0470   {
0471     theWorldView.InitIdentity();
0472   }
0473   else
0474   {
0475     // Compute reference point for transformation in untransformed projection space.
0476     NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
0477     if (theAnchor != NULL)
0478     {
0479       Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z());
0480     }
0481     else
0482     {
0483       Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
0484     }
0485 
0486     if ((myMode & Graphic3d_TMF_RotatePers) != 0)
0487     {
0488       NCollection_Mat3<Standard_Real> aRotMat = persistentRotationMatrix (theCamera, theViewportWidth, theViewportHeight);
0489 
0490       aWorldView.SetValue (0, 0, aRotMat.GetColumn (0).x());
0491       aWorldView.SetValue (1, 0, aRotMat.GetColumn (0).y());
0492       aWorldView.SetValue (2, 0, aRotMat.GetColumn (0).z());
0493 
0494       aWorldView.SetValue (0, 1, aRotMat.GetColumn (1).x());
0495       aWorldView.SetValue (1, 1, aRotMat.GetColumn (1).y());
0496       aWorldView.SetValue (2, 1, aRotMat.GetColumn (1).z());
0497 
0498       aWorldView.SetValue (0, 2, aRotMat.GetColumn (2).x());
0499       aWorldView.SetValue (1, 2, aRotMat.GetColumn (2).y());
0500       aWorldView.SetValue (2, 2, aRotMat.GetColumn (2).z());
0501     }
0502 
0503     if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
0504     {
0505       // lock zooming
0506       Standard_Real aScale = persistentScale (theCamera, theViewportWidth, theViewportHeight);
0507       Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
0508     }
0509     theWorldView.ConvertFrom (aWorldView);
0510     return;
0511   }
0512 }
0513 
0514 // =======================================================================
0515 // function : Apply
0516 // purpose  : Apply transformation to bounding box of presentation.
0517 // =======================================================================
0518 template<class T>
0519 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0520                                      const NCollection_Mat4<T>& theProjection,
0521                                      const NCollection_Mat4<T>& theWorldView,
0522                                      const Standard_Integer theViewportWidth,
0523                                      const Standard_Integer theViewportHeight,
0524                                      Bnd_Box& theBoundingBox) const
0525 {
0526   if (theBoundingBox.IsVoid())
0527   {
0528     return;
0529   }
0530 
0531   T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
0532 
0533   theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
0534 
0535   typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
0536   typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
0537   BVH_Box<T, 3> aBBox (aMin, aMax);
0538 
0539   Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
0540 
0541   theBoundingBox = Bnd_Box();
0542   theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
0543                          aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
0544 }
0545 
0546 // =======================================================================
0547 // function : Apply
0548 // purpose  : Apply transformation to bounding box of presentation.
0549 // =======================================================================
0550 template<class T>
0551 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
0552                                      const NCollection_Mat4<T>& theProjection,
0553                                      const NCollection_Mat4<T>& theWorldView,
0554                                      const Standard_Integer theViewportWidth,
0555                                      const Standard_Integer theViewportHeight,
0556                                      BVH_Box<T, 3>& theBoundingBox) const
0557 {
0558   NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
0559   if (aTPers.IsIdentity()
0560   || !theBoundingBox.IsValid())
0561   {
0562     return;
0563   }
0564 
0565   const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
0566   const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
0567 
0568   typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
0569   anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0570   anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0571   anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0572   anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0573   anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
0574   anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
0575   anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
0576   anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
0577 
0578   theBoundingBox.Clear();
0579   for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
0580   {
0581     typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
0582     aCorner  = aTPers * aCorner;
0583     aCorner = aCorner / aCorner.w();
0584     theBoundingBox.Add (typename BVH_Box<T, 3>::BVH_VecNt (aCorner.x(), aCorner.y(), aCorner.z()));
0585   }
0586 }
0587 
0588 // =======================================================================
0589 // function : Compute
0590 // purpose  : Compute transformation.
0591 // =======================================================================
0592 template<class T>
0593 NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
0594                                                       const NCollection_Mat4<T>& theProjection,
0595                                                       const NCollection_Mat4<T>& theWorldView,
0596                                                       const Standard_Integer theViewportWidth,
0597                                                       const Standard_Integer theViewportHeight) const
0598 {
0599   if (myMode == Graphic3d_TMF_None)
0600   {
0601     return NCollection_Mat4<T>();
0602   }
0603 
0604   NCollection_Mat4<T> aWorldView (theWorldView);
0605   NCollection_Mat4<T> anUnviewMat;
0606   if (!theWorldView.Inverted (anUnviewMat))
0607   {
0608     return NCollection_Mat4<T>();
0609   }
0610 
0611   // compute only world-view matrix difference to avoid floating point instability
0612   // caused by projection matrix modifications outside of this algorithm (e.g. by Z-fit)
0613   Apply (theCamera, theProjection, aWorldView, theViewportWidth, theViewportHeight);
0614   return anUnviewMat * aWorldView;
0615 }
0616 
0617 #endif // _Graphic3d_TransformPers_HeaderFile