1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0029602: Visualization, TKOpenGl - Size Culling is not properly handled within Perspective projection

OpenGl_BVHTreeSelector::isTooSmall() now takes into account distance
the distance between camera Eye and object Center
within perspective projection.
This commit is contained in:
kgv
2018-03-22 13:05:06 +03:00
committed by bugmaster
parent 6ca66a7dea
commit f29de68237
3 changed files with 28 additions and 5 deletions

View File

@@ -25,7 +25,7 @@
// =======================================================================
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
: myIsProjectionParallel (Standard_True),
myCamScaleInv (1.0),
myCamScale (1.0),
myPixelSize (1.0)
{
//
@@ -41,13 +41,17 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
return;
myIsProjectionParallel = theCamera->IsOrthographic();
const gp_Dir aCamDir = theCamera->Direction();
myCamera = theCamera;
myProjectionMat = theCamera->ProjectionMatrix();
myWorldViewMat = theCamera->OrientationMatrix();
myWorldViewProjState = theCamera->WorldViewProjState();
myCamEye.SetValues (theCamera->Eye().X(), theCamera->Eye().Y(), theCamera->Eye().Z());
myCamScaleInv = 1.0 / myCamera->Scale();
myCamDir.SetValues (aCamDir.X(), aCamDir.Y(), aCamDir.Z());
myCamScale = theCamera->IsOrthographic()
? theCamera->Scale()
: 2.0 * Tan (theCamera->FOVy() * M_PI / 360.0); // same as theCamera->Scale()/theCamera->Distance()
Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
@@ -186,7 +190,8 @@ void OpenGl_BVHTreeSelector::SetCullingSize (CullingContext& theCtx,
theCtx.SizeCull2 = -1.0;
if (theSize > 0.0 && !Precision::IsInfinite (theSize))
{
theCtx.SizeCull2 = (myPixelSize * theSize) / myCamScaleInv;
theCtx.SizeCull2 = myPixelSize * theSize;
theCtx.SizeCull2 *= myCamScale;
theCtx.SizeCull2 *= theCtx.SizeCull2;
}
}

View File

@@ -196,7 +196,18 @@ protected:
{
return false;
}
return (theMaxPt - theMinPt).SquareModulus() < theCtx.SizeCull2;
const Standard_Real aBoxDiag2 = (theMaxPt - theMinPt).SquareModulus();
if (myIsProjectionParallel)
{
return aBoxDiag2 < theCtx.SizeCull2;
}
// note that distances behind the Eye (aBndDist < 0) are not scaled correctly here,
// but majority of such objects should be culled by frustum
const OpenGl_Vec3d aBndCenter = (theMinPt + theMaxPt) * 0.5;
const Standard_Real aBndDist = (aBndCenter - myCamEye).Dot (myCamDir);
return aBoxDiag2 < theCtx.SizeCull2 * aBndDist * aBndDist;
}
protected:
@@ -255,7 +266,8 @@ protected:
Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices.
Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling
Standard_Real myCamScaleInv; //!< inverted camera scale for size culling
Graphic3d_Vec3d myCamDir; //!< camera direction for size culling
Standard_Real myCamScale; //!< camera scale for size culling
Standard_Real myPixelSize; //!< pixel size for size culling
};