1 // Created on: 2015-06-18
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2015 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 #ifndef _Graphic3d_TransformPers_HeaderFile
17 #define _Graphic3d_TransformPers_HeaderFile
19 #include <Aspect_TypeOfTriedronPosition.hxx>
20 #include <Bnd_Box.hxx>
21 #include <BVH_Box.hxx>
22 #include <Graphic3d_Camera.hxx>
23 #include <Graphic3d_TransformUtils.hxx>
24 #include <Graphic3d_TransModeFlags.hxx>
25 #include <Graphic3d_Vec.hxx>
26 #include <NCollection_Mat4.hxx>
28 DEFINE_STANDARD_HANDLE(Graphic3d_TransformPers, Standard_Transient)
30 //! Transformation Persistence definition.
32 //! Transformation Persistence defines a mutable Local Coordinate system which depends on camera position,
33 //! so that visual appearance of the object becomes partially immutable while camera moves.
34 //! Object visually preserves particular property such as size, placement, rotation or their combination.
36 //! Graphic3d_TMF_ZoomPers, Graphic3d_TMF_RotatePers and Graphic3d_TMF_ZoomRotatePers define Local Coordinate system
37 //! having origin in specified anchor point defined in World Coordinate system,
38 //! while Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d define origin as 2D offset from screen corner in pixels.
40 //! Graphic3d_TMF_2d, Graphic3d_TMF_TriedronPers and Graphic3d_TMF_ZoomPers defines Local Coordinate system where length units are pixels.
41 //! Beware that Graphic3d_RenderingParams::ResolutionRatio() will be ignored!
42 //! For other Persistence flags, normal (world) length units will apply.
44 //! WARNING: Graphic3d_TMF_None is not permitted for defining instance of this class - NULL handle should be used for this purpose!
45 class Graphic3d_TransformPers : public Standard_Transient
47 DEFINE_STANDARD_RTTIEXT(Graphic3d_TransformPers, Standard_Transient)
50 //! Return true if specified mode is zoom/rotate transformation persistence.
51 static Standard_Boolean IsZoomOrRotate (Graphic3d_TransModeFlags theMode)
53 return (theMode & (Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers)) != 0;
56 //! Return true if specified mode is 2d/trihedron transformation persistence.
57 static Standard_Boolean IsTrihedronOr2d (Graphic3d_TransModeFlags theMode)
59 return (theMode & (Graphic3d_TMF_TriedronPers | Graphic3d_TMF_2d)) != 0;
64 //! Set transformation persistence.
65 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode)
68 if (IsZoomOrRotate (theMode))
70 SetPersistence (theMode, gp_Pnt(0.0, 0.0, 0.0));
72 else if (IsTrihedronOr2d (theMode))
74 SetPersistence (theMode, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (0, 0));
76 else if (theMode == Graphic3d_TMF_CameraPers)
82 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
86 //! Set Zoom/Rotate transformation persistence with an anchor 3D point.
87 //! Anchor point defines the origin of Local Coordinate system within World Coordinate system.
88 //! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
89 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
91 : myMode (Graphic3d_TMF_None)
93 SetPersistence (theMode, thePnt);
96 //! Set 2d/trihedron transformation persistence with a corner and 2D offset.
97 //! 2D offset defines the origin of Local Coordinate system as projection of 2D point on screen plane into World Coordinate system.
98 //! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
99 //! The offset is a positive displacement from the view corner in pixels.
100 Graphic3d_TransformPers (const Graphic3d_TransModeFlags theMode,
101 const Aspect_TypeOfTriedronPosition theCorner,
102 const Graphic3d_Vec2i& theOffset = Graphic3d_Vec2i (0, 0))
103 : myMode (Graphic3d_TMF_None)
105 SetPersistence (theMode, theCorner, theOffset);
108 //! Return true for Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers modes.
109 Standard_Boolean IsZoomOrRotate() const { return IsZoomOrRotate (myMode); }
111 //! Return true for Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d modes.
112 Standard_Boolean IsTrihedronOr2d() const { return IsTrihedronOr2d (myMode); }
114 //! Transformation persistence mode flags.
115 Graphic3d_TransModeFlags Mode() const { return myMode; }
117 //! Transformation persistence mode flags.
118 Graphic3d_TransModeFlags Flags() const { return myMode; }
120 //! Set Zoom/Rotate transformation persistence with an anchor 3D point.
121 //! Throws an exception if persistence mode is not Graphic3d_TMF_ZoomPers, Graphic3d_TMF_ZoomRotatePers or Graphic3d_TMF_RotatePers.
122 void SetPersistence (const Graphic3d_TransModeFlags theMode,
123 const gp_Pnt& thePnt)
125 if (!IsZoomOrRotate (theMode))
127 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
131 myParams.Params3d.PntX = thePnt.X();
132 myParams.Params3d.PntY = thePnt.Y();
133 myParams.Params3d.PntZ = thePnt.Z();
136 //! Set 2d/trihedron transformation persistence with a corner and 2D offset.
137 //! Throws an exception if persistence mode is not Graphic3d_TMF_TriedronPers or Graphic3d_TMF_2d.
138 void SetPersistence (const Graphic3d_TransModeFlags theMode,
139 const Aspect_TypeOfTriedronPosition theCorner,
140 const Graphic3d_Vec2i& theOffset)
142 if (!IsTrihedronOr2d (theMode))
144 throw Standard_ProgramError("Graphic3d_TransformPers::SetPersistence(), wrong persistence mode.");
148 myParams.Params2d.Corner = theCorner;
149 myParams.Params2d.OffsetX = theOffset.x();
150 myParams.Params2d.OffsetY = theOffset.y();
155 //! Return the anchor point for zoom/rotate transformation persistence.
156 gp_Pnt AnchorPoint() const
158 if (!IsZoomOrRotate())
160 throw Standard_ProgramError("Graphic3d_TransformPers::AnchorPoint(), wrong persistence mode.");
163 return gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
166 //! Set the anchor point for zoom/rotate transformation persistence.
167 void SetAnchorPoint (const gp_Pnt& thePnt)
169 if (!IsZoomOrRotate())
171 throw Standard_ProgramError("Graphic3d_TransformPers::SetAnchorPoint(), wrong persistence mode.");
174 myParams.Params3d.PntX = thePnt.X();
175 myParams.Params3d.PntY = thePnt.Y();
176 myParams.Params3d.PntZ = thePnt.Z();
179 //! Return the corner for 2d/trihedron transformation persistence.
180 Aspect_TypeOfTriedronPosition Corner2d() const
182 if (!IsTrihedronOr2d())
184 throw Standard_ProgramError("Graphic3d_TransformPers::Corner2d(), wrong persistence mode.");
187 return myParams.Params2d.Corner;
190 //! Set the corner for 2d/trihedron transformation persistence.
191 void SetCorner2d (const Aspect_TypeOfTriedronPosition thePos)
193 if (!IsTrihedronOr2d())
195 throw Standard_ProgramError("Graphic3d_TransformPers::SetCorner2d(), wrong persistence mode.");
198 myParams.Params2d.Corner = thePos;
201 //! Return the offset from the corner for 2d/trihedron transformation persistence.
202 Graphic3d_Vec2i Offset2d() const
204 if (!IsTrihedronOr2d())
206 throw Standard_ProgramError("Graphic3d_TransformPers::Offset2d(), wrong persistence mode.");
209 return Graphic3d_Vec2i (myParams.Params2d.OffsetX, myParams.Params2d.OffsetY);
212 //! Set the offset from the corner for 2d/trihedron transformation persistence.
213 void SetOffset2d (const Graphic3d_Vec2i& theOffset)
215 if (!IsTrihedronOr2d())
217 throw Standard_ProgramError("Graphic3d_TransformPers::SetOffset2d(), wrong persistence mode.");
220 myParams.Params2d.OffsetX = theOffset.x();
221 myParams.Params2d.OffsetY = theOffset.y();
226 //! Find scale value based on the camera position and view dimensions
227 //! @param theCamera [in] camera definition
228 //! @param theViewportWidth [in] the width of viewport.
229 //! @param theViewportHeight [in] the height of viewport.
230 virtual Standard_Real persistentScale (const Handle(Graphic3d_Camera)& theCamera,
231 const Standard_Integer theViewportWidth,
232 const Standard_Integer theViewportHeight) const
234 (void )theViewportWidth;
235 // use total size when tiling is active
236 const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
238 gp_Vec aVecToEye (theCamera->Direction());
239 gp_Vec aVecToObj (theCamera->Eye(), gp_Pnt (myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ));
240 const Standard_Real aFocus = aVecToObj.Dot (aVecToEye);
241 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
242 return Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
245 //! Apply transformation to bounding box of presentation.
246 //! @param theCamera [in] camera definition
247 //! @param theProjection [in] the projection transformation matrix.
248 //! @param theWorldView [in] the world view transformation matrix.
249 //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
250 //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
251 //! @param theBoundingBox [in/out] the bounding box to transform.
253 void Apply (const Handle(Graphic3d_Camera)& theCamera,
254 const NCollection_Mat4<T>& theProjection,
255 const NCollection_Mat4<T>& theWorldView,
256 const Standard_Integer theViewportWidth,
257 const Standard_Integer theViewportHeight,
258 Bnd_Box& theBoundingBox) const;
260 //! Apply transformation to bounding box of presentation
261 //! @param theCamera [in] camera definition
262 //! @param theProjection [in] the projection transformation matrix.
263 //! @param theWorldView [in] the world view transformation matrix.
264 //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
265 //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
266 //! @param theBoundingBox [in/out] the bounding box to transform.
268 void Apply (const Handle(Graphic3d_Camera)& theCamera,
269 const NCollection_Mat4<T>& theProjection,
270 const NCollection_Mat4<T>& theWorldView,
271 const Standard_Integer theViewportWidth,
272 const Standard_Integer theViewportHeight,
273 BVH_Box<T, 3>& theBoundingBox) const;
275 //! Compute transformation.
276 //! Computed matrix can be applied to model world transformation
277 //! of an object to implement effect of transformation persistence.
278 //! @param theCamera [in] camera definition
279 //! @param theProjection [in] the projection transformation matrix.
280 //! @param theWorldView [in] the world view transformation matrix.
281 //! @param theViewportWidth [in] the width of viewport (for 2d persistence).
282 //! @param theViewportHeight [in] the height of viewport (for 2d persistence).
283 //! @return transformation matrix to be applied to model world transformation of an object.
285 NCollection_Mat4<T> Compute (const Handle(Graphic3d_Camera)& theCamera,
286 const NCollection_Mat4<T>& theProjection,
287 const NCollection_Mat4<T>& theWorldView,
288 const Standard_Integer theViewportWidth,
289 const Standard_Integer theViewportHeight) const;
291 //! Apply transformation persistence on specified matrices.
292 //! @param theCamera camera definition
293 //! @param theProjection projection matrix to modify
294 //! @param theWorldView world-view matrix to modify
295 //! @param theViewportWidth viewport width
296 //! @param theViewportHeight viewport height
297 //! @param theAnchor if not NULL, overrides anchor point
299 void Apply (const Handle(Graphic3d_Camera)& theCamera,
300 const NCollection_Mat4<T>& theProjection,
301 NCollection_Mat4<T>& theWorldView,
302 const Standard_Integer theViewportWidth,
303 const Standard_Integer theViewportHeight,
304 const gp_Pnt* theAnchor = NULL) const;
306 //! Dumps the content of me into the stream
307 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
311 //! 3D anchor point for zoom/rotate transformation persistence.
318 //! Dumps the content of me into the stream
319 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
322 //! 2d/trihedron transformation persistence parameters.
325 Standard_Integer OffsetX;
326 Standard_Integer OffsetY;
327 Aspect_TypeOfTriedronPosition Corner;
329 //! Dumps the content of me into the stream
330 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
335 Graphic3d_TransModeFlags myMode; //!< Transformation persistence mode flags
338 PersParams3d Params3d;
339 PersParams2d Params2d;
344 // =======================================================================
346 // purpose : Apply transformation to world view and projection matrices.
347 // =======================================================================
349 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
350 const NCollection_Mat4<T>& theProjection,
351 NCollection_Mat4<T>& theWorldView,
352 const Standard_Integer theViewportWidth,
353 const Standard_Integer theViewportHeight,
354 const gp_Pnt* theAnchor) const
356 (void )theViewportWidth;
357 (void )theProjection;
358 if (myMode == Graphic3d_TMF_None
359 || theViewportHeight == 0)
364 // use total size when tiling is active
365 const Standard_Integer aVPSizeY = theCamera->Tile().IsValid() ? theCamera->Tile().TotalSize.y() : theViewportHeight;
367 // a small enough jitter compensation offset
368 // to avoid image dragging within single pixel in corner cases
369 const Standard_Real aJitterComp = 0.001;
370 if (myMode == Graphic3d_TMF_TriedronPers)
372 // reset Z focus for trihedron persistence
373 const Standard_Real aFocus = theCamera->IsOrthographic()
374 ? theCamera->Distance()
375 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
376 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
377 : Standard_Real(theCamera->ZFocus()));
379 // scale factor to pixels
380 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
381 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
382 const gp_Dir aForward = theCamera->Direction();
383 gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance());
384 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
386 const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
387 const gp_Dir aSide = aForward.Crossed (theCamera->Up());
388 const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * theCamera->NDC2dOffsetX() - anOffsetX);
389 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
398 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
400 const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
401 const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * theCamera->NDC2dOffsetY() - anOffsetY);
402 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
412 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
413 Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z());
414 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
415 theWorldView.ConvertFrom (aWorldView);
418 else if (myMode == Graphic3d_TMF_2d)
420 const Standard_Real aFocus = theCamera->IsOrthographic()
421 ? theCamera->Distance()
422 : (theCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
423 ? Standard_Real(theCamera->ZFocus() * theCamera->Distance())
424 : Standard_Real(theCamera->ZFocus()));
426 // scale factor to pixels
427 const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus);
428 const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY);
429 gp_XYZ aCenter (0.0, 0.0, -aFocus);
430 if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
432 aCenter.SetX (-aViewDim.X() * theCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
433 if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
435 aCenter.SetX (-aCenter.X());
438 if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
440 aCenter.SetY (-aViewDim.Y() * theCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
441 if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
443 aCenter.SetY (-aCenter.Y());
447 theWorldView.InitIdentity();
448 Graphic3d_TransformUtils::Translate (theWorldView, T(aCenter.X()), T(aCenter.Y()), T(aCenter.Z()));
449 Graphic3d_TransformUtils::Scale (theWorldView, T(aScale), T(aScale), T(aScale));
452 else if ((myMode & Graphic3d_TMF_CameraPers) != 0)
454 theWorldView.InitIdentity();
458 // Compute reference point for transformation in untransformed projection space.
459 NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
460 if (theAnchor != NULL)
462 Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z());
466 Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
469 if ((myMode & Graphic3d_TMF_RotatePers) != 0)
471 // lock rotation by nullifying rotation component
472 aWorldView.SetValue (0, 0, 1.0);
473 aWorldView.SetValue (1, 0, 0.0);
474 aWorldView.SetValue (2, 0, 0.0);
476 aWorldView.SetValue (0, 1, 0.0);
477 aWorldView.SetValue (1, 1, 1.0);
478 aWorldView.SetValue (2, 1, 0.0);
480 aWorldView.SetValue (0, 2, 0.0);
481 aWorldView.SetValue (1, 2, 0.0);
482 aWorldView.SetValue (2, 2, 1.0);
485 if ((myMode & Graphic3d_TMF_ZoomPers) != 0)
488 Standard_Real aScale = persistentScale (theCamera, theViewportWidth, theViewportHeight);
489 Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale);
491 theWorldView.ConvertFrom (aWorldView);
496 // =======================================================================
498 // purpose : Apply transformation to bounding box of presentation.
499 // =======================================================================
501 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
502 const NCollection_Mat4<T>& theProjection,
503 const NCollection_Mat4<T>& theWorldView,
504 const Standard_Integer theViewportWidth,
505 const Standard_Integer theViewportHeight,
506 Bnd_Box& theBoundingBox) const
508 if (theBoundingBox.IsVoid())
513 T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
515 theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
517 typename BVH_Box<T, 3>::BVH_VecNt aMin (aXmin, aYmin, aZmin);
518 typename BVH_Box<T, 3>::BVH_VecNt aMax (aXmax, aYmax, aZmax);
519 BVH_Box<T, 3> aBBox (aMin, aMax);
521 Apply (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
523 theBoundingBox = Bnd_Box();
524 theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
525 aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
528 // =======================================================================
530 // purpose : Apply transformation to bounding box of presentation.
531 // =======================================================================
533 void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
534 const NCollection_Mat4<T>& theProjection,
535 const NCollection_Mat4<T>& theWorldView,
536 const Standard_Integer theViewportWidth,
537 const Standard_Integer theViewportHeight,
538 BVH_Box<T, 3>& theBoundingBox) const
540 NCollection_Mat4<T> aTPers = Compute (theCamera, theProjection, theWorldView, theViewportWidth, theViewportHeight);
541 if (aTPers.IsIdentity()
542 || !theBoundingBox.IsValid())
547 const typename BVH_Box<T, 3>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
548 const typename BVH_Box<T, 3>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
550 typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
551 anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
552 anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
553 anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
554 anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
555 anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
556 anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
557 anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
558 anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
560 theBoundingBox.Clear();
561 for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
563 typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
564 aCorner = aTPers * aCorner;
565 aCorner = aCorner / aCorner.w();
566 theBoundingBox.Add (typename BVH_Box<T, 3>::BVH_VecNt (aCorner.x(), aCorner.y(), aCorner.z()));
570 // =======================================================================
571 // function : Compute
572 // purpose : Compute transformation.
573 // =======================================================================
575 NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Camera)& theCamera,
576 const NCollection_Mat4<T>& theProjection,
577 const NCollection_Mat4<T>& theWorldView,
578 const Standard_Integer theViewportWidth,
579 const Standard_Integer theViewportHeight) const
581 if (myMode == Graphic3d_TMF_None)
583 return NCollection_Mat4<T>();
586 NCollection_Mat4<T> aWorldView (theWorldView);
587 NCollection_Mat4<T> anUnviewMat;
588 if (!theWorldView.Inverted (anUnviewMat))
590 return NCollection_Mat4<T>();
593 // compute only world-view matrix difference to avoid floating point instability
594 // caused by projection matrix modifications outside of this algorithm (e.g. by Z-fit)
595 Apply (theCamera, theProjection, aWorldView, theViewportWidth, theViewportHeight);
596 return anUnviewMat * aWorldView;
599 #endif // _Graphic3d_TransformPers_HeaderFile