mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-08 14:17:06 +03:00
0029295: Visualization, TKOpenGl - provide distance culling option
Graphic3d_ZLayerSettings::CullingDistance() and ::CullingSize() - added new properties configuring culling of small and distant objects, disabled by default. OpenGl_BVHTreeSelector now handles size culling and distance culling in addition to frustom culling.
This commit is contained in:
@@ -33,7 +33,9 @@ struct Graphic3d_ZLayerSettings
|
||||
|
||||
//! Default settings.
|
||||
Graphic3d_ZLayerSettings()
|
||||
: myIsImmediate (Standard_False),
|
||||
: myCullingDistance (Precision::Infinite()),
|
||||
myCullingSize (Precision::Infinite()),
|
||||
myIsImmediate (Standard_False),
|
||||
myUseEnvironmentTexture (Standard_True),
|
||||
myToEnableDepthTest (Standard_True),
|
||||
myToEnableDepthWrite(Standard_True),
|
||||
@@ -62,6 +64,30 @@ struct Graphic3d_ZLayerSettings
|
||||
}
|
||||
}
|
||||
|
||||
//! Return TRUE, if culling of distant objects (distance culling) should be performed; FALSE by default.
|
||||
//! @sa CullingDistance()
|
||||
Standard_Boolean HasCullingDistance() const { return !Precision::IsInfinite (myCullingDistance) && myCullingDistance > 0.0; }
|
||||
|
||||
//! Return the distance to discard drawing of distant objects (distance from camera Eye point); by default it is Infinite (distance culling is disabled).
|
||||
//! Since camera eye definition has no strong meaning within orthographic projection, option is considered only within perspective projection.
|
||||
//! Note also that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingDistance() const { return myCullingDistance; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingDistance (Standard_Real theDistance) { myCullingDistance = theDistance; }
|
||||
|
||||
//! Return TRUE, if culling of small objects (size culling) should be performed; FALSE by default.
|
||||
//! @sa CullingSize()
|
||||
Standard_Boolean HasCullingSize() const { return !Precision::IsInfinite (myCullingSize) && myCullingSize > 0.0; }
|
||||
|
||||
//! Return the size to discard drawing of small objects; by default it is Infinite (size culling is disabled).
|
||||
//! Current implementation checks the length of projected diagonal of bounding box in pixels for discarding.
|
||||
//! Note that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingSize() const { return myCullingSize; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingSize (Standard_Real theSize) { myCullingSize = theSize; }
|
||||
|
||||
//! Return true if this layer should be drawn after all normal (non-immediate) layers.
|
||||
Standard_Boolean IsImmediate() const { return myIsImmediate; }
|
||||
|
||||
@@ -162,6 +188,8 @@ protected:
|
||||
TCollection_AsciiString myName; //!< user-provided name
|
||||
Handle(Geom_Transformation) myOriginTrsf; //!< transformation to the origin
|
||||
gp_XYZ myOrigin; //!< the origin of all objects within the layer
|
||||
Standard_Real myCullingDistance; //!< distance to discard objects
|
||||
Standard_Real myCullingSize; //!< size to discard objects
|
||||
Graphic3d_PolygonOffset myPolygonOffset; //!< glPolygonOffset() arguments
|
||||
Standard_Boolean myIsImmediate; //!< immediate layer will be drawn after all normal layers
|
||||
Standard_Boolean myUseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
|
||||
|
@@ -24,7 +24,11 @@
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
|
||||
: myIsProjectionParallel (Standard_True)
|
||||
: myIsProjectionParallel (Standard_True),
|
||||
myCamScaleInv (1.0),
|
||||
myDistCull (-1.0),
|
||||
myPixelSize (1.0),
|
||||
mySizeCull2 (-1.0)
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -44,6 +48,8 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
||||
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();
|
||||
|
||||
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;
|
||||
@@ -124,11 +130,14 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
||||
// function : SetViewportSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight)
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio)
|
||||
{
|
||||
myViewportHeight = theViewportHeight;
|
||||
myViewportWidth = theViewportWidth;
|
||||
myViewportWidth = theViewportWidth;
|
||||
myPixelSize = Max (theResolutionRatio / theViewportHeight,
|
||||
theResolutionRatio / theViewportWidth);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -153,10 +162,38 @@ Standard_Real OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec
|
||||
return aD + (anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCullingDistance
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetCullingDistance (Standard_Real theDistance)
|
||||
{
|
||||
myDistCull = -1.0;
|
||||
if (!myIsProjectionParallel)
|
||||
{
|
||||
myDistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance)
|
||||
? theDistance
|
||||
: -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCullingSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetCullingSize (Standard_Real theSize)
|
||||
{
|
||||
mySizeCull2 = -1.0;
|
||||
if (theSize > 0.0 && !Precision::IsInfinite (theSize))
|
||||
{
|
||||
mySizeCull2 = (myPixelSize * theSize) / myCamScaleInv;
|
||||
mySizeCull2 *= mySizeCull2;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : CacheClipPtsProjections
|
||||
// purpose : Caches view volume's vertices projections along its normals and AABBs dimensions
|
||||
// Must be called at the beginning of each BVH tree traverse loop
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
||||
{
|
||||
@@ -254,5 +291,26 @@ Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec3d& theMinPt
|
||||
}
|
||||
}
|
||||
|
||||
// distance culling - discard node if distance to it's bounding box from camera eye is less than specified culling distance
|
||||
if (myDistCull > 0.0)
|
||||
{
|
||||
// check distance to the bounding sphere as fast approximation
|
||||
const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5;
|
||||
const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5;
|
||||
if ((aSphereCenter - myCamEye).Modulus() - aSphereRadius > myDistCull)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// size culling - discard node if diagonal of it's bounding box is less than specified culling size
|
||||
if (mySizeCull2 > 0.0)
|
||||
{
|
||||
if ((theMaxPt - theMinPt).SquareModulus() < mySizeCull2)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -33,7 +33,19 @@ public:
|
||||
//! Retrieves view volume's planes equations and its vertices from projection and world-view matrices.
|
||||
Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
|
||||
|
||||
Standard_EXPORT void SetViewportSize (const Standard_Integer theViewportWidth, const Standard_Integer theViewportHeight);
|
||||
Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio);
|
||||
|
||||
//! Setup distance culling.
|
||||
Standard_EXPORT void SetCullingDistance (Standard_Real theDistance);
|
||||
|
||||
//! Setup size culling.
|
||||
Standard_EXPORT void SetCullingSize (Standard_Real theSize);
|
||||
|
||||
//! Caches view volume's vertices projections along its normals and AABBs dimensions.
|
||||
//! Must be called at the beginning of each BVH tree traverse loop.
|
||||
Standard_EXPORT void CacheClipPtsProjections();
|
||||
|
||||
//! Detects if AABB overlaps view volume using separating axis theorem (SAT).
|
||||
//! @param theMinPt [in] maximum point of AABB.
|
||||
@@ -42,10 +54,6 @@ public:
|
||||
Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const;
|
||||
|
||||
//! Caches view volume's vertices projections along its normals and AABBs dimensions.
|
||||
//! Must be called at the beginning of each BVH tree traverse loop.
|
||||
Standard_EXPORT void CacheClipPtsProjections();
|
||||
|
||||
//! Return the camera definition.
|
||||
const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
|
||||
|
||||
@@ -139,6 +147,13 @@ protected:
|
||||
Standard_Integer myViewportHeight;
|
||||
|
||||
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
|
||||
Standard_Real myDistCull; //!< culling distance
|
||||
Standard_Real myPixelSize; //!< pixel size for size culling
|
||||
Standard_Real mySizeCull2; //!< squared culling size
|
||||
|
||||
};
|
||||
|
||||
#endif // _OpenGl_BVHTreeSelector_HeaderFile
|
||||
|
@@ -489,9 +489,15 @@ void OpenGl_Layer::updateBVH() const
|
||||
void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
|
||||
{
|
||||
updateBVH();
|
||||
|
||||
OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
|
||||
traverse (aSelector);
|
||||
if (myBVHPrimitives .Size() != 0
|
||||
|| myBVHPrimitivesTrsfPers.Size() != 0)
|
||||
{
|
||||
OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
|
||||
aSelector.SetCullingDistance (myLayerSettings.CullingDistance());
|
||||
aSelector.SetCullingSize (myLayerSettings.CullingSize());
|
||||
aSelector.CacheClipPtsProjections();
|
||||
traverse (aSelector);
|
||||
}
|
||||
|
||||
const Standard_Integer aViewId = theWorkspace->View()->Identification();
|
||||
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
|
||||
@@ -516,15 +522,8 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
|
||||
// function : traverse
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
|
||||
void OpenGl_Layer::traverse (const OpenGl_BVHTreeSelector& theSelector) const
|
||||
{
|
||||
// handle a case when all objects are infinite
|
||||
if (myBVHPrimitives .Size() == 0
|
||||
&& myBVHPrimitivesTrsfPers.Size() == 0)
|
||||
return;
|
||||
|
||||
theSelector.CacheClipPtsProjections();
|
||||
|
||||
opencascade::handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
|
||||
for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
|
||||
{
|
||||
@@ -595,9 +594,9 @@ void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
|
||||
else
|
||||
{
|
||||
Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
|
||||
const OpenGl_Structure* aStruct =
|
||||
isTrsfPers ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
|
||||
: myBVHPrimitives.GetStructureById (aIdx);
|
||||
const OpenGl_Structure* aStruct = isTrsfPers
|
||||
? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
|
||||
: myBVHPrimitives.GetStructureById (aIdx);
|
||||
aStruct->MarkAsNotCulled();
|
||||
if (aHead < 0)
|
||||
{
|
||||
@@ -696,7 +695,6 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull();
|
||||
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
|
||||
const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
|
||||
Handle(Graphic3d_Camera) aCameraBack;
|
||||
if (hasLocalCS)
|
||||
{
|
||||
// Apply local camera transformation.
|
||||
|
@@ -135,7 +135,7 @@ protected:
|
||||
void updateBVH() const;
|
||||
|
||||
//! Traverses through BVH tree to determine which structures are in view volume.
|
||||
void traverse (OpenGl_BVHTreeSelector& theSelector) const;
|
||||
void traverse (const OpenGl_BVHTreeSelector& theSelector) const;
|
||||
|
||||
//! Iterates through the hierarchical list of existing structures and renders them all.
|
||||
void renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const;
|
||||
|
@@ -877,9 +877,10 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
|
||||
// update states of OpenGl_BVHTreeSelector (frustum culling algorithm);
|
||||
// note that we pass here window dimensions ignoring Graphic3d_RenderingParams::RenderResolutionScale
|
||||
myBVHSelector.SetViewVolume (myCamera);
|
||||
myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height());
|
||||
myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio());
|
||||
|
||||
const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
|
||||
if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
|
||||
|
@@ -4655,6 +4655,8 @@ inline void printZLayerInfo (Draw_Interpretor& theDI,
|
||||
theDI << " Immediate: TRUE\n";
|
||||
}
|
||||
theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
|
||||
theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
|
||||
theDI << " Culling size: " << theLayer.CullingSize() << "\n";
|
||||
theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
|
||||
theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
|
||||
theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
|
||||
@@ -4885,6 +4887,33 @@ static int VZLayer (Draw_Interpretor& theDI,
|
||||
aSettings.SetOrigin (anOrigin);
|
||||
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
||||
}
|
||||
else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
|
||||
&& anArgIter + 1 < theArgNb
|
||||
&& (anArg == "-cullingdistance"
|
||||
|| anArg == "-cullingdist"
|
||||
|| anArg == "-culldistance"
|
||||
|| anArg == "-culldist"
|
||||
|| anArg == "-distcull"
|
||||
|| anArg == "-distculling"
|
||||
|| anArg == "-distanceculling"))
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
||||
const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
|
||||
aSettings.SetCullingDistance (aDist);
|
||||
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
||||
}
|
||||
else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
|
||||
&& anArgIter + 1 < theArgNb
|
||||
&& (anArg == "-cullingsize"
|
||||
|| anArg == "-cullsize"
|
||||
|| anArg == "-sizecull"
|
||||
|| anArg == "-sizeculling"))
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
||||
const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
|
||||
aSettings.SetCullingSize (aSize);
|
||||
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
||||
}
|
||||
else if (anArg == "-settings"
|
||||
|| anArg == "settings")
|
||||
{
|
||||
@@ -11548,6 +11577,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("vzlayer",
|
||||
"vzlayer [layerId]"
|
||||
"\n\t\t: [-add|-delete|-get|-settings]"
|
||||
"\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
|
||||
"\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
|
||||
"\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv}]"
|
||||
"\n\t\t: ZLayer list management:"
|
||||
|
Reference in New Issue
Block a user