const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const;
+ //! Apply transformation persistence on specified matrices.
+ //! @param theCamera camera definition
+ //! @param theProjection projection matrix to modify
+ //! @param theWorldView world-view matrix to modify
+ //! @param theViewportWidth viewport width
+ //! @param theViewportHeight viewport height
template<class T>
void Apply (const Handle(Graphic3d_Camera)& theCamera,
NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
const Standard_Integer theViewportHeight) const;
+
+ //! Return true if transformation persistence alters projection matrix.
+ bool AltersProjectionMatrix() const
+ {
+ return (Flags & Graphic3d_TMF_PanPers) != 0;
+ }
+
};
// =======================================================================
const Standard_Integer theViewportHeight) const
{
(void )theViewportWidth;
- if (!Flags)
+ if (Flags == Graphic3d_TMF_None
+ || theViewportHeight == 0)
{
return;
}
return NCollection_Mat4<T>();
}
+ NCollection_Mat4<T> aProjection (theProjection);
+ NCollection_Mat4<T> aWorldView (theWorldView);
NCollection_Mat4<T> anUnviewMat;
+ if (AltersProjectionMatrix())
+ {
+ // destructive transformation persistence which directly modifies projection matrix
+ if (!(theProjection * theWorldView).Inverted (anUnviewMat))
+ {
+ return NCollection_Mat4<T>();
+ }
+
+ Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
+ return anUnviewMat * (aProjection * aWorldView);
+ }
- if (!(theProjection * theWorldView).Inverted (anUnviewMat))
+ if (!theWorldView.Inverted (anUnviewMat))
{
return NCollection_Mat4<T>();
}
- NCollection_Mat4<T> aProjection (theProjection);
- NCollection_Mat4<T> aWorldView (theWorldView);
-
+ // compute only world-view matrix difference to avoid floating point instability
+ // caused by projection matrix modifications outside of this algorithm (e.g. by Z-fit)
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
-
- return anUnviewMat * (aProjection * aWorldView);
+ return anUnviewMat * aWorldView;
}
#endif // _Graphic3d_TransformPers_HeaderFile
const Standard_Integer theWindowHeight,
const Standard_Boolean theToIncludeAuxiliary) const
{
+ Graphic3d_BndBox4f aBox;
if (myZLayers.LayerIDs().IsBound (theLayerId))
{
- return myZLayers.Layer (theLayerId).BoundingBox (Identification(),
+ aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
theCamera,
theWindowWidth,
theWindowHeight,
theToIncludeAuxiliary);
}
- return Graphic3d_BndBox4f();
+ // add bounding box of gradient/texture background for proper Z-fit
+ if (theToIncludeAuxiliary
+ && theLayerId == Graphic3d_ZLayerId_BotOSD
+ && (myBgTextureArray->IsDefined()
+ || myBgGradientArray->IsDefined()))
+ {
+ // Background is drawn using 2D transformation persistence
+ // (e.g. it is actually placed in 3D coordinates within active camera position).
+ // We add here full-screen plane with 2D transformation persistence
+ // for simplicity (myBgTextureArray might define a little bit different options
+ // but it is updated within ::Render())
+ const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
+ const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
+ Graphic3d_BndBox4f aBox2d (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
+ Graphic3d_Vec4 (float(theWindowWidth), float(theWindowHeight), 0.0f, 0.0f));
+
+ Graphic3d_TransformPers aTrsfPers;
+ aTrsfPers.Flags = Graphic3d_TMF_2d;
+ aTrsfPers.Point = Graphic3d_Vec3d(-1.0, -1.0, 0.0);
+ aTrsfPers.Apply (theCamera,
+ aProjectionMat,
+ aWorldViewMat,
+ theWindowWidth,
+ theWindowHeight,
+ aBox2d);
+ aBox.Combine (aBox2d);
+ }
+
+ return aBox;
}
//=======================================================================
--- /dev/null
+puts "========"
+puts "Gradient background is lost at some camera positions"
+puts "========"
+
+# Test case setup the camera in such a position,
+# so that background plane will be clipped by Z-range if not handled by Z-fit.
+
+pload MODELING VISUALIZATION
+box b 0 0 -100 100 90 10
+
+vclear
+vinit View1
+vaxo
+vsetgradientbg 180 200 255 180 180 180 2
+vzbufftrihedron
+vdisplay -dispMode 1 b
+vsetlocation b 0 0 1000
+vfit
+
+vviewparams -scale 6.66 -eye 48 43 -210 -at 50 45 -95
+
+if { [vreadpixel 100 300 rgb name] != "GRAY74" } { puts "Error: gradient background is not displayed" }
+
+vdump $imagedir/${casename}.png