]> OCCT Git - occt.git/commitdiff
0029602: Visualization, TKOpenGl - Size Culling is not properly handled within Perspe...
authorkgv <kgv@opencascade.com>
Thu, 22 Mar 2018 10:05:06 +0000 (13:05 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 22 Mar 2018 16:51:37 +0000 (19:51 +0300)
OpenGl_BVHTreeSelector::isTooSmall() now takes into account distance
the distance between camera Eye and object Center
within perspective projection.

src/OpenGl/OpenGl_BVHTreeSelector.cxx
src/OpenGl/OpenGl_BVHTreeSelector.hxx
tests/v3d/glsl/cullsize

index b6d994213ac349e482b47cd772d0870e549e0e64..b696305e265c35d14460e937ac702d132a431e32 100644 (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;
   }
 }
index 902e1941416e8bdec1a4fba1205aa5a78102627c..c659e8bebd3cb79e3f6260c3edfc2187d9175692 100644 (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
 
 };
index 892bceae6dd65b5cb6842e81aa64e99c950a0dc2..28990ff9bd1b8ba15b5fef7c61b628310bfd6339 100644 (file)
@@ -9,6 +9,7 @@ set THE_PICK_PNTS1O { {  10 165 } { 100 200 } { 170 250 } { 250 250 } { 350 300
 set THE_PICK_PNTS1P { {  40 170 } { 100 200 } { 170 250 } { 250 250 } { 380 350 } }
 set THE_PICK_PNTS2O { { 148 192 } { 175 200 } { 190 200 } { 200 220 } { 250 230 } }
 set THE_PICK_PNTS2P { { 152 192 } { 175 200 } { 190 200 } { 220 220 } { 250 230 } }
+set THE_PICK_PNTS3P { {  90 155 } { 105 160 } { 125 170 } { 140 175 } { 160 180 } }
 
 pload MODELING VISUALIZATION
 vclear
@@ -49,3 +50,8 @@ vcamera -persp
 for { set x 2 } { $x < $THE_NB_BOXES } { incr x } { if { [vreadpixel {*}[lindex $THE_PICK_PNTS2P $x] rgb name] == "BLACK" } { puts "Error: object $x is culled" } }
 for { set x 0 } { $x < 2 }             { incr x } { if { [vreadpixel {*}[lindex $THE_PICK_PNTS2P $x] rgb name] != "BLACK" } { puts "Error: object $x is NOT culled" } }
 vdump $::imagedir/${::casename}_30p.png
+
+vviewparams -eye 16.8333 -9.08333 10.0833 -at 7.5 0.25 0.75
+for { set x 3 } { $x < $THE_NB_BOXES } { incr x } { if { [vreadpixel {*}[lindex $THE_PICK_PNTS3P $x] rgb name] == "BLACK" } { puts "Error: object $x is culled" } }
+for { set x 0 } { $x < 3 }             { incr x } { if { [vreadpixel {*}[lindex $THE_PICK_PNTS3P $x] rgb name] != "BLACK" } { puts "Error: object $x is NOT culled" } }
+vdump $::imagedir/${::casename}_30p2.png