mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-09 18:50:54 +03:00
0027836: Visualization, TKOpenGl - gradient background is lost at some camera positions
OpenGl_View::ZLayerBoundingBox() now adds screen background plane for proper Z-fit. Graphic3d_TransformPers::Compute() - projection matrix has been excluded from the math to eliminate floating point computation error.
This commit is contained in:
parent
1ae83f5727
commit
71d8ccc753
@ -90,12 +90,25 @@ public:
|
|||||||
const Standard_Integer theViewportWidth,
|
const Standard_Integer theViewportWidth,
|
||||||
const Standard_Integer theViewportHeight) const;
|
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>
|
template<class T>
|
||||||
void Apply (const Handle(Graphic3d_Camera)& theCamera,
|
void Apply (const Handle(Graphic3d_Camera)& theCamera,
|
||||||
NCollection_Mat4<T>& theProjection,
|
NCollection_Mat4<T>& theProjection,
|
||||||
NCollection_Mat4<T>& theWorldView,
|
NCollection_Mat4<T>& theWorldView,
|
||||||
const Standard_Integer theViewportWidth,
|
const Standard_Integer theViewportWidth,
|
||||||
const Standard_Integer theViewportHeight) const;
|
const Standard_Integer theViewportHeight) const;
|
||||||
|
|
||||||
|
//! Return true if transformation persistence alters projection matrix.
|
||||||
|
bool AltersProjectionMatrix() const
|
||||||
|
{
|
||||||
|
return (Flags & Graphic3d_TMF_PanPers) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -110,7 +123,8 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
|
|||||||
const Standard_Integer theViewportHeight) const
|
const Standard_Integer theViewportHeight) const
|
||||||
{
|
{
|
||||||
(void )theViewportWidth;
|
(void )theViewportWidth;
|
||||||
if (!Flags)
|
if (Flags == Graphic3d_TMF_None
|
||||||
|
|| theViewportHeight == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -375,19 +389,30 @@ NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const Handle(Graphic3d_Cam
|
|||||||
return NCollection_Mat4<T>();
|
return NCollection_Mat4<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NCollection_Mat4<T> aProjection (theProjection);
|
||||||
|
NCollection_Mat4<T> aWorldView (theWorldView);
|
||||||
NCollection_Mat4<T> anUnviewMat;
|
NCollection_Mat4<T> anUnviewMat;
|
||||||
|
if (AltersProjectionMatrix())
|
||||||
|
{
|
||||||
|
// destructive transformation persistence which directly modifies projection matrix
|
||||||
if (!(theProjection * theWorldView).Inverted (anUnviewMat))
|
if (!(theProjection * theWorldView).Inverted (anUnviewMat))
|
||||||
{
|
{
|
||||||
return NCollection_Mat4<T>();
|
return NCollection_Mat4<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
NCollection_Mat4<T> aProjection (theProjection);
|
|
||||||
NCollection_Mat4<T> aWorldView (theWorldView);
|
|
||||||
|
|
||||||
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
|
Apply (theCamera, aProjection, aWorldView, theViewportWidth, theViewportHeight);
|
||||||
|
|
||||||
return anUnviewMat * (aProjection * aWorldView);
|
return anUnviewMat * (aProjection * aWorldView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!theWorldView.Inverted (anUnviewMat))
|
||||||
|
{
|
||||||
|
return NCollection_Mat4<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 * aWorldView;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _Graphic3d_TransformPers_HeaderFile
|
#endif // _Graphic3d_TransformPers_HeaderFile
|
||||||
|
@ -550,16 +550,45 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
|
|||||||
const Standard_Integer theWindowHeight,
|
const Standard_Integer theWindowHeight,
|
||||||
const Standard_Boolean theToIncludeAuxiliary) const
|
const Standard_Boolean theToIncludeAuxiliary) const
|
||||||
{
|
{
|
||||||
|
Graphic3d_BndBox4f aBox;
|
||||||
if (myZLayers.LayerIDs().IsBound (theLayerId))
|
if (myZLayers.LayerIDs().IsBound (theLayerId))
|
||||||
{
|
{
|
||||||
return myZLayers.Layer (theLayerId).BoundingBox (Identification(),
|
aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
|
||||||
theCamera,
|
theCamera,
|
||||||
theWindowWidth,
|
theWindowWidth,
|
||||||
theWindowHeight,
|
theWindowHeight,
|
||||||
theToIncludeAuxiliary);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
24
tests/bugs/vis/bug27836
Normal file
24
tests/bugs/vis/bug27836
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user