mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-30 12:14:08 +03:00
0030412: Visualization, TKV3d - add presentation of camera frustum
1) Added method Graphic3d_Camera::FrustumPoints() returning corner points of camera frustum. 2) Refactored methods OpenGl_BVHTreeSelector::isFullOut(...) and OpenGl_BVHTreeSelector::CacheClipPtsProjections() 3) Changed computation algorithm of frustum planes (build them by corner points) 4) Added interactive object AIS_CameraFrustum to draw camera frustum. 5) Extended Draw command "vcamera" with option displaying camera frustum.
This commit is contained in:
parent
25333d45ea
commit
30a1b24e19
285
src/AIS/AIS_CameraFrustum.cxx
Normal file
285
src/AIS/AIS_CameraFrustum.cxx
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
// Created on: 2018-12-12
|
||||||
|
// Created by: Olga SURYANINOVA
|
||||||
|
// Copyright (c) 2018 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <AIS_CameraFrustum.hxx>
|
||||||
|
|
||||||
|
#include <AIS_DisplayMode.hxx>
|
||||||
|
#include <Graphic3d_ArrayOfTriangles.hxx>
|
||||||
|
#include <Graphic3d_ArrayOfSegments.hxx>
|
||||||
|
#include <Prs3d_LineAspect.hxx>
|
||||||
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
|
#include <Select3D_SensitiveGroup.hxx>
|
||||||
|
#include <Select3D_SensitivePrimitiveArray.hxx>
|
||||||
|
#include <Select3D_SensitiveSegment.hxx>
|
||||||
|
#include <SelectMgr_EntityOwner.hxx>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static const Standard_ShortReal THE_DEFAULT_TRANSPARENCY = 0.7f;
|
||||||
|
static const Quantity_Color THE_DEFAULT_COLOR = Quantity_NOC_WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Constructor
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
AIS_CameraFrustum::AIS_CameraFrustum()
|
||||||
|
: myPoints (0, Graphic3d_Camera::FrustumVerticesNB)
|
||||||
|
{
|
||||||
|
myDrawer->SetLineAspect (new Prs3d_LineAspect (THE_DEFAULT_COLOR, Aspect_TOL_SOLID, 1.0));
|
||||||
|
|
||||||
|
Handle(Prs3d_ShadingAspect) aShadingAspect = new Prs3d_ShadingAspect();
|
||||||
|
aShadingAspect->SetMaterial (Graphic3d_NOM_PLASTIC);
|
||||||
|
aShadingAspect->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Blend);
|
||||||
|
aShadingAspect->SetTransparency (THE_DEFAULT_TRANSPARENCY);
|
||||||
|
aShadingAspect->SetColor (THE_DEFAULT_COLOR);
|
||||||
|
myDrawer->SetShadingAspect (aShadingAspect);
|
||||||
|
|
||||||
|
myDrawer->SetTransparency (THE_DEFAULT_TRANSPARENCY);
|
||||||
|
SetDisplayMode (AIS_Shaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : AcceptDisplayMode
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Boolean AIS_CameraFrustum::AcceptDisplayMode (const Standard_Integer theMode) const
|
||||||
|
{
|
||||||
|
return theMode == AIS_Shaded || theMode == AIS_WireFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetCameraFrustum
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera)
|
||||||
|
{
|
||||||
|
if (theCamera.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
theCamera->FrustumPoints (myPoints);
|
||||||
|
|
||||||
|
fillTriangles();
|
||||||
|
fillBorders();
|
||||||
|
|
||||||
|
SetToUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetColor
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::SetColor (const Quantity_Color& theColor)
|
||||||
|
{
|
||||||
|
AIS_InteractiveObject::SetColor (theColor);
|
||||||
|
myDrawer->ShadingAspect()->SetColor (theColor);
|
||||||
|
myDrawer->LineAspect()->SetColor (theColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : UnsetColor
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::UnsetColor()
|
||||||
|
{
|
||||||
|
if (!HasColor())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIS_InteractiveObject::UnsetColor();
|
||||||
|
|
||||||
|
myDrawer->ShadingAspect()->SetColor (THE_DEFAULT_COLOR);
|
||||||
|
myDrawer->LineAspect()->SetColor (THE_DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : UnsetColor
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::UnsetTransparency()
|
||||||
|
{
|
||||||
|
myDrawer->ShadingAspect()->SetTransparency (0.0f);
|
||||||
|
myDrawer->SetTransparency (0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : fillTriangles
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::fillTriangles()
|
||||||
|
{
|
||||||
|
if (myTriangles.IsNull())
|
||||||
|
{
|
||||||
|
const Standard_Integer aPlaneTriangleVertsNb = 2 * 3;
|
||||||
|
const Standard_Integer aPlanesNb = 3 * 2;
|
||||||
|
|
||||||
|
myTriangles = new Graphic3d_ArrayOfTriangles (Graphic3d_Camera::FrustumVerticesNB, aPlaneTriangleVertsNb * aPlanesNb);
|
||||||
|
myTriangles->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
// Triangles go in order (clockwise vertices traversing for correct normal):
|
||||||
|
// (0, 2, 1), (3, 1, 2)
|
||||||
|
const Standard_Integer aLookup1_clockwise[] = { 0, 1, 0, 1, 0, 1 };
|
||||||
|
const Standard_Integer aLookup2_clockwise[] = { 0, 0, 1, 1, 1, 0 };
|
||||||
|
// Triangles go in order (counterclockwise vertices traversing for correct normal):
|
||||||
|
// (1, 2, 0), (2, 1, 3)
|
||||||
|
const Standard_Integer aLookup1_anticlockwise[] = { 0, 1, 0, 1, 0, 1 };
|
||||||
|
const Standard_Integer aLookup2_anticlockwise[] = { 1, 0, 0, 0, 1, 1 };
|
||||||
|
Standard_Integer aShifts[] = { 0, 0, 0 };
|
||||||
|
|
||||||
|
// Planes go in order:
|
||||||
|
// LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
|
||||||
|
for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
for (Standard_Integer aPntIter = 0; aPntIter < aPlaneTriangleVertsNb; ++aPntIter)
|
||||||
|
{
|
||||||
|
aShifts[aFaceIdx] = i;
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
aShifts[(aFaceIdx + 1) % 3] = aLookup1_clockwise[aPntIter];
|
||||||
|
aShifts[(aFaceIdx + 2) % 3] = aLookup2_clockwise[aPntIter];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aShifts[(aFaceIdx + 1) % 3] = aLookup1_anticlockwise[aPntIter];
|
||||||
|
aShifts[(aFaceIdx + 2) % 3] = aLookup2_anticlockwise[aPntIter];
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
|
||||||
|
myTriangles->AddEdge (anIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
|
||||||
|
{
|
||||||
|
const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
|
||||||
|
myTriangles->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : fillBorders
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::fillBorders()
|
||||||
|
{
|
||||||
|
if (myBorders.IsNull())
|
||||||
|
{
|
||||||
|
const Standard_Integer aPlaneSegmVertsNb = 2 * 4;
|
||||||
|
const Standard_Integer aPlanesNb = 3 * 2;
|
||||||
|
myBorders = new Graphic3d_ArrayOfSegments (Graphic3d_Camera::FrustumVerticesNB, aPlaneSegmVertsNb * aPlanesNb);
|
||||||
|
myBorders->SetVertice (Graphic3d_Camera::FrustumVerticesNB, gp_Pnt (0.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
// Segments go in order:
|
||||||
|
// (0, 2), (2, 3), (3, 1), (1, 0)
|
||||||
|
const Standard_Integer aLookup1[] = { 0, 1, 1, 1, 1, 0, 0, 0 };
|
||||||
|
const Standard_Integer aLookup2[] = { 0, 0, 0, 1, 1, 1, 1, 0 };
|
||||||
|
Standard_Integer aShifts[] = { 0, 0, 0 };
|
||||||
|
|
||||||
|
// Planes go in order:
|
||||||
|
// LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
|
||||||
|
for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
for (Standard_Integer aSegmVertIter = 0; aSegmVertIter < aPlaneSegmVertsNb; ++aSegmVertIter)
|
||||||
|
{
|
||||||
|
aShifts[aFaceIdx] = i;
|
||||||
|
aShifts[(aFaceIdx + 1) % 3] = aLookup1[aSegmVertIter];
|
||||||
|
aShifts[(aFaceIdx + 2) % 3] = aLookup2[aSegmVertIter];
|
||||||
|
|
||||||
|
Standard_Integer anIndex = aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2];
|
||||||
|
myBorders->AddEdge (anIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Standard_Integer aPointIter = 0; aPointIter < Graphic3d_Camera::FrustumVerticesNB; ++aPointIter)
|
||||||
|
{
|
||||||
|
const Graphic3d_Vec3d aPnt = myPoints[aPointIter];
|
||||||
|
myBorders->SetVertice (aPointIter + 1, gp_Pnt (aPnt.x(), aPnt.y(), aPnt.z()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Compute
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||||
|
const Handle(Prs3d_Presentation)& thePrs,
|
||||||
|
const Standard_Integer theMode)
|
||||||
|
{
|
||||||
|
thePrs->SetInfiniteState (true);
|
||||||
|
if (myTriangles.IsNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
||||||
|
switch (theMode)
|
||||||
|
{
|
||||||
|
case AIS_Shaded:
|
||||||
|
{
|
||||||
|
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
|
||||||
|
aGroup->AddPrimitiveArray (myTriangles);
|
||||||
|
}
|
||||||
|
Standard_FALLTHROUGH
|
||||||
|
case AIS_WireFrame:
|
||||||
|
{
|
||||||
|
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
|
||||||
|
aGroup->AddPrimitiveArray (myBorders);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : ComputeSelection
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void AIS_CameraFrustum::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
||||||
|
const Standard_Integer theMode)
|
||||||
|
{
|
||||||
|
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
|
||||||
|
switch (theMode)
|
||||||
|
{
|
||||||
|
case SelectionMode_Edges:
|
||||||
|
{
|
||||||
|
Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (anOwner);
|
||||||
|
for (Standard_Integer anIter = 1; anIter <= myBorders->EdgeNumber(); anIter += 2)
|
||||||
|
{
|
||||||
|
aSensitiveEntity->Add (new Select3D_SensitiveSegment (anOwner, myBorders->Vertice (myBorders->Edge (anIter)), myBorders->Vertice(myBorders->Edge (anIter + 1))));
|
||||||
|
}
|
||||||
|
theSelection->Add (aSensitiveEntity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SelectionMode_Volume:
|
||||||
|
{
|
||||||
|
Handle(Select3D_SensitivePrimitiveArray) aSelArray = new Select3D_SensitivePrimitiveArray (anOwner);
|
||||||
|
aSelArray->InitTriangulation (myTriangles->Attributes(), myTriangles->Indices(), TopLoc_Location());
|
||||||
|
theSelection->Add (aSelArray);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
src/AIS/AIS_CameraFrustum.hxx
Normal file
85
src/AIS/AIS_CameraFrustum.hxx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Created on: 2018-12-12
|
||||||
|
// Created by: Olga SURYANINOVA
|
||||||
|
// Copyright (c) 2018 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _AIS_CameraFrustum_HeaderFile
|
||||||
|
#define _AIS_CameraFrustum_HeaderFile
|
||||||
|
|
||||||
|
#include <AIS_InteractiveObject.hxx>
|
||||||
|
|
||||||
|
class Graphic3d_ArrayOfSegments;
|
||||||
|
class Graphic3d_ArrayOfTriangles;
|
||||||
|
|
||||||
|
//! Presentation for drawing camera frustum.
|
||||||
|
//! Default configuration is built with filling and some transparency.
|
||||||
|
class AIS_CameraFrustum : public AIS_InteractiveObject
|
||||||
|
{
|
||||||
|
DEFINE_STANDARD_RTTIEXT(AIS_CameraFrustum, AIS_InteractiveObject)
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Selection modes supported by this object
|
||||||
|
enum SelectionMode
|
||||||
|
{
|
||||||
|
SelectionMode_Edges = 0, //!< detect by edges (default)
|
||||||
|
SelectionMode_Volume = 1, //!< detect by volume
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructs camera frustum with default configuration.
|
||||||
|
Standard_EXPORT AIS_CameraFrustum();
|
||||||
|
|
||||||
|
//! Sets camera frustum.
|
||||||
|
Standard_EXPORT void SetCameraFrustum (const Handle(Graphic3d_Camera)& theCamera);
|
||||||
|
|
||||||
|
//! Setup custom color.
|
||||||
|
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Restore default color.
|
||||||
|
Standard_EXPORT virtual void UnsetColor() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Restore transparency setting.
|
||||||
|
Standard_EXPORT virtual void UnsetTransparency() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Return true if specified display mode is supported.
|
||||||
|
Standard_EXPORT virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Computes presentation of camera frustum.
|
||||||
|
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||||
|
const Handle(Prs3d_Presentation)& thePrs,
|
||||||
|
const Standard_Integer theMode) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Compute selection.
|
||||||
|
Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
||||||
|
const Standard_Integer theMode) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//! Fills triangles primitive array for camera frustum filling.
|
||||||
|
void fillTriangles();
|
||||||
|
|
||||||
|
//! Fills polylines primitive array for camera frustum borders.
|
||||||
|
void fillBorders();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
NCollection_Array1<Graphic3d_Vec3d> myPoints; //!< Array of points
|
||||||
|
Handle(Graphic3d_ArrayOfTriangles) myTriangles; //!< Triangles for camera frustum filling
|
||||||
|
Handle(Graphic3d_ArrayOfSegments) myBorders; //!< Segments for camera frustum borders
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _AIS_CameraFrustum_HeaderFile
|
@ -19,6 +19,8 @@ AIS_BadEdgeFilter.cxx
|
|||||||
AIS_BadEdgeFilter.hxx
|
AIS_BadEdgeFilter.hxx
|
||||||
AIS_C0RegularityFilter.cxx
|
AIS_C0RegularityFilter.cxx
|
||||||
AIS_C0RegularityFilter.hxx
|
AIS_C0RegularityFilter.hxx
|
||||||
|
AIS_CameraFrustum.cxx
|
||||||
|
AIS_CameraFrustum.hxx
|
||||||
AIS_Chamf2dDimension.cxx
|
AIS_Chamf2dDimension.cxx
|
||||||
AIS_Chamf2dDimension.hxx
|
AIS_Chamf2dDimension.hxx
|
||||||
AIS_Chamf2dDimension.lxx
|
AIS_Chamf2dDimension.lxx
|
||||||
|
@ -1388,3 +1388,79 @@ Standard_EXPORT void NCollection_Lerp<Handle(Graphic3d_Camera)>::Interpolate (co
|
|||||||
theCamera->SetScale (aScale);
|
theCamera->SetScale (aScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : FrustumPoints
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void Graphic3d_Camera::FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePoints) const
|
||||||
|
{
|
||||||
|
if (thePoints.Length() != FrustumVerticesNB)
|
||||||
|
{
|
||||||
|
thePoints.Resize (0, FrustumVerticesNB, Standard_False);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Graphic3d_Mat4d& aProjectionMat = ProjectionMatrix();
|
||||||
|
const Graphic3d_Mat4d& aWorldViewMat = OrientationMatrix();
|
||||||
|
|
||||||
|
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;
|
||||||
|
Standard_Real aNear = 0.0, aFar = 0.0;
|
||||||
|
if (!IsOrthographic())
|
||||||
|
{
|
||||||
|
// handle perspective projection
|
||||||
|
aNear = aProjectionMat.GetValue (2, 3) / (-1.0 + aProjectionMat.GetValue (2, 2));
|
||||||
|
aFar = aProjectionMat.GetValue (2, 3) / ( 1.0 + aProjectionMat.GetValue (2, 2));
|
||||||
|
// Near plane
|
||||||
|
nLeft = aNear * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
|
||||||
|
nRight = aNear * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
|
||||||
|
nTop = aNear * (aProjectionMat.GetValue (1, 2) + 1.0) / aProjectionMat.GetValue (1, 1);
|
||||||
|
nBottom = aNear * (aProjectionMat.GetValue (1, 2) - 1.0) / aProjectionMat.GetValue (1, 1);
|
||||||
|
// Far plane
|
||||||
|
fLeft = aFar * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
|
||||||
|
fRight = aFar * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
|
||||||
|
fTop = aFar * (aProjectionMat.GetValue (1, 2) + 1.0) / aProjectionMat.GetValue (1, 1);
|
||||||
|
fBottom = aFar * (aProjectionMat.GetValue (1, 2) - 1.0) / aProjectionMat.GetValue (1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle orthographic projection
|
||||||
|
aNear = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) + 1.0);
|
||||||
|
aFar = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) - 1.0);
|
||||||
|
// Near plane
|
||||||
|
nLeft = ( 1.0 + aProjectionMat.GetValue (0, 3)) / (-aProjectionMat.GetValue (0, 0));
|
||||||
|
fLeft = nLeft;
|
||||||
|
nRight = ( 1.0 - aProjectionMat.GetValue (0, 3)) / aProjectionMat.GetValue (0, 0);
|
||||||
|
fRight = nRight;
|
||||||
|
nTop = ( 1.0 - aProjectionMat.GetValue (1, 3)) / aProjectionMat.GetValue (1, 1);
|
||||||
|
fTop = nTop;
|
||||||
|
nBottom = (-1.0 - aProjectionMat.GetValue (1, 3)) / aProjectionMat.GetValue (1, 1);
|
||||||
|
fBottom = nBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphic3d_Vec4d aLeftTopNear (nLeft, nTop, -aNear, 1.0), aRightBottomFar (fRight, fBottom, -aFar, 1.0);
|
||||||
|
Graphic3d_Vec4d aLeftBottomNear (nLeft, nBottom, -aNear, 1.0), aRightTopFar (fRight, fTop, -aFar, 1.0);
|
||||||
|
Graphic3d_Vec4d aRightBottomNear (nRight, nBottom, -aNear, 1.0), aLeftTopFar (fLeft, fTop, -aFar, 1.0);
|
||||||
|
Graphic3d_Vec4d aRightTopNear (nRight, nTop, -aNear, 1.0), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0);
|
||||||
|
|
||||||
|
Graphic3d_Mat4d anInvWorldView;
|
||||||
|
aWorldViewMat.Inverted (anInvWorldView);
|
||||||
|
|
||||||
|
Graphic3d_Vec4d aTmpPnt;
|
||||||
|
aTmpPnt = anInvWorldView * aLeftTopNear;
|
||||||
|
thePoints.SetValue (FrustumVert_LeftTopNear, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aRightBottomFar;
|
||||||
|
thePoints.SetValue (FrustumVert_RightBottomFar, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aLeftBottomNear;
|
||||||
|
thePoints.SetValue (FrustumVert_LeftBottomNear, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aRightTopFar;
|
||||||
|
thePoints.SetValue (FrustumVert_RightTopFar, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aRightBottomNear;
|
||||||
|
thePoints.SetValue (FrustumVert_RightBottomNear, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aLeftTopFar;
|
||||||
|
thePoints.SetValue (FrustumVert_LeftTopFar, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aRightTopNear;
|
||||||
|
thePoints.SetValue (FrustumVert_RightTopNear, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
aTmpPnt = anInvWorldView * aLeftBottomFar;
|
||||||
|
thePoints.SetValue (FrustumVert_LeftBottomFar, aTmpPnt.xyz() / aTmpPnt.w());
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <Graphic3d_Vec3.hxx>
|
#include <Graphic3d_Vec3.hxx>
|
||||||
#include <Graphic3d_WorldViewProjState.hxx>
|
#include <Graphic3d_WorldViewProjState.hxx>
|
||||||
#include <NCollection_Lerp.hxx>
|
#include <NCollection_Lerp.hxx>
|
||||||
|
#include <NCollection_Array1.hxx>
|
||||||
|
|
||||||
#include <gp_Dir.hxx>
|
#include <gp_Dir.hxx>
|
||||||
#include <gp_Pnt.hxx>
|
#include <gp_Pnt.hxx>
|
||||||
@ -630,6 +631,27 @@ private:
|
|||||||
const NCollection_Vec3<Elem_t>& theAxialScale,
|
const NCollection_Vec3<Elem_t>& theAxialScale,
|
||||||
NCollection_Mat4<Elem_t>& theOutMx);
|
NCollection_Mat4<Elem_t>& theOutMx);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Enumerates vertices of view volume.
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FrustumVert_LeftBottomNear,
|
||||||
|
FrustumVert_LeftBottomFar,
|
||||||
|
FrustumVert_LeftTopNear,
|
||||||
|
FrustumVert_LeftTopFar,
|
||||||
|
FrustumVert_RightBottomNear,
|
||||||
|
FrustumVert_RightBottomFar,
|
||||||
|
FrustumVert_RightTopNear,
|
||||||
|
FrustumVert_RightTopFar,
|
||||||
|
FrustumVerticesNB
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Fill array of current view frustum corners.
|
||||||
|
//! The size of this array is equal to FrustumVerticesNB.
|
||||||
|
//! The order of vertices is as defined in FrustumVert_* enumeration.
|
||||||
|
Standard_EXPORT void FrustumPoints (NCollection_Array1<Graphic3d_Vec3d>& thePoints) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
gp_Dir myUp; //!< Camera up direction vector.
|
gp_Dir myUp; //!< Camera up direction vector.
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
|
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
|
||||||
: myIsProjectionParallel (Standard_True),
|
: myClipVerts (0, Graphic3d_Camera::FrustumVerticesNB),
|
||||||
|
myIsProjectionParallel (Standard_True),
|
||||||
myCamScale (1.0),
|
myCamScale (1.0),
|
||||||
myPixelSize (1.0)
|
myPixelSize (1.0)
|
||||||
{
|
{
|
||||||
@ -53,77 +54,36 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
|||||||
? theCamera->Scale()
|
? theCamera->Scale()
|
||||||
: 2.0 * Tan (theCamera->FOVy() * M_PI / 360.0); // same as theCamera->Scale()/theCamera->Distance()
|
: 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;
|
// Compute frustum points
|
||||||
Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
|
theCamera->FrustumPoints (myClipVerts);
|
||||||
Standard_Real aNear = 0.0, aFar = 0.0;
|
|
||||||
if (!myIsProjectionParallel)
|
// Compute frustum planes
|
||||||
|
// Vertices go in order:
|
||||||
|
// 0, 2, 1
|
||||||
|
const Standard_Integer aLookup1[] = { 0, 1, 0 };
|
||||||
|
const Standard_Integer aLookup2[] = { 0, 0, 1 };
|
||||||
|
Standard_Integer aShifts[] = { 0, 0, 0 };
|
||||||
|
|
||||||
|
// Planes go in order:
|
||||||
|
// LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
|
||||||
|
for (Standard_Integer aFaceIdx = 0; aFaceIdx < 3; ++aFaceIdx)
|
||||||
{
|
{
|
||||||
// handle perspective projection
|
for (Standard_Integer i = 0; i < 2; ++i)
|
||||||
aNear = myProjectionMat.GetValue (2, 3) / (- 1.0 + myProjectionMat.GetValue (2, 2));
|
|
||||||
aFar = myProjectionMat.GetValue (2, 3) / ( 1.0 + myProjectionMat.GetValue (2, 2));
|
|
||||||
// Near plane
|
|
||||||
nLeft = aNear * (myProjectionMat.GetValue (0, 2) - 1.0) / myProjectionMat.GetValue (0, 0);
|
|
||||||
nRight = aNear * (myProjectionMat.GetValue (0, 2) + 1.0) / myProjectionMat.GetValue (0, 0);
|
|
||||||
nTop = aNear * (myProjectionMat.GetValue (1, 2) + 1.0) / myProjectionMat.GetValue (1, 1);
|
|
||||||
nBottom = aNear * (myProjectionMat.GetValue (1, 2) - 1.0) / myProjectionMat.GetValue (1, 1);
|
|
||||||
// Far plane
|
|
||||||
fLeft = aFar * (myProjectionMat.GetValue (0, 2) - 1.0) / myProjectionMat.GetValue (0, 0);
|
|
||||||
fRight = aFar * (myProjectionMat.GetValue (0, 2) + 1.0) / myProjectionMat.GetValue (0, 0);
|
|
||||||
fTop = aFar * (myProjectionMat.GetValue (1, 2) + 1.0) / myProjectionMat.GetValue (1, 1);
|
|
||||||
fBottom = aFar * (myProjectionMat.GetValue (1, 2) - 1.0) / myProjectionMat.GetValue (1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// handle orthographic projection
|
OpenGl_Vec3d aPlanePnts[3];
|
||||||
aNear = (1.0 / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) + 1.0);
|
for (Standard_Integer aPntIter = 0; aPntIter < 3; ++aPntIter)
|
||||||
aFar = (1.0 / myProjectionMat.GetValue (2, 2)) * (myProjectionMat.GetValue (2, 3) - 1.0);
|
{
|
||||||
// Near plane
|
aShifts[aFaceIdx] = i;
|
||||||
nLeft = ( 1.0 + myProjectionMat.GetValue (0, 3)) / (-myProjectionMat.GetValue (0, 0));
|
aShifts[(aFaceIdx + 1) % 3] = aLookup1[aPntIter];
|
||||||
fLeft = nLeft;
|
aShifts[(aFaceIdx + 2) % 3] = aLookup2[aPntIter];
|
||||||
nRight = ( 1.0 - myProjectionMat.GetValue (0, 3)) / myProjectionMat.GetValue (0, 0);
|
|
||||||
fRight = nRight;
|
aPlanePnts[aPntIter] = myClipVerts[aShifts[0] * 2 * 2 + aShifts[1] * 2 + aShifts[2]];
|
||||||
nTop = ( 1.0 - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
|
|
||||||
fTop = nTop;
|
|
||||||
nBottom = (-1.0 - myProjectionMat.GetValue (1, 3)) / myProjectionMat.GetValue (1, 1);
|
|
||||||
fBottom = nBottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGl_Vec4d aLeftTopNear (nLeft, nTop, -aNear, 1.0), aRightBottomFar (fRight, fBottom, -aFar, 1.0);
|
myClipPlanes[aFaceIdx * 2 + i].Origin = aPlanePnts[0];
|
||||||
OpenGl_Vec4d aLeftBottomNear (nLeft, nBottom, -aNear, 1.0), aRightTopFar (fRight, fTop, -aFar, 1.0);
|
myClipPlanes[aFaceIdx * 2 + i].Normal =
|
||||||
OpenGl_Vec4d aRightBottomNear (nRight, nBottom, -aNear, 1.0), aLeftTopFar (fLeft, fTop, -aFar, 1.0);
|
OpenGl_Vec3d::Cross (aPlanePnts[1] - aPlanePnts[0],
|
||||||
OpenGl_Vec4d aRightTopNear (nRight, nTop, -aNear, 1.0), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0);
|
aPlanePnts[2] - aPlanePnts[0]).Normalized() * (i == 0 ? -1.f : 1.f);
|
||||||
|
|
||||||
const OpenGl_Mat4d aViewProj = myProjectionMat * myWorldViewMat;
|
|
||||||
OpenGl_Mat4d anInvWorldView;
|
|
||||||
myWorldViewMat.Inverted (anInvWorldView);
|
|
||||||
|
|
||||||
myClipVerts[ClipVert_LeftTopNear] = anInvWorldView * aLeftTopNear;
|
|
||||||
myClipVerts[ClipVert_RightBottomFar] = anInvWorldView * aRightBottomFar;
|
|
||||||
myClipVerts[ClipVert_LeftBottomNear] = anInvWorldView * aLeftBottomNear;
|
|
||||||
myClipVerts[ClipVert_RightTopFar] = anInvWorldView * aRightTopFar;
|
|
||||||
myClipVerts[ClipVert_RightBottomNear] = anInvWorldView * aRightBottomNear;
|
|
||||||
myClipVerts[ClipVert_LeftTopFar] = anInvWorldView * aLeftTopFar;
|
|
||||||
myClipVerts[ClipVert_RightTopNear] = anInvWorldView * aRightTopNear;
|
|
||||||
myClipVerts[ClipVert_LeftBottomFar] = anInvWorldView * aLeftBottomFar;
|
|
||||||
|
|
||||||
// UNNORMALIZED!
|
|
||||||
myClipPlanes[Plane_Left] = aViewProj.GetRow (3) + aViewProj.GetRow (0);
|
|
||||||
myClipPlanes[Plane_Right] = aViewProj.GetRow (3) - aViewProj.GetRow (0);
|
|
||||||
myClipPlanes[Plane_Top] = aViewProj.GetRow (3) - aViewProj.GetRow (1);
|
|
||||||
myClipPlanes[Plane_Bottom] = aViewProj.GetRow (3) + aViewProj.GetRow (1);
|
|
||||||
myClipPlanes[Plane_Near] = aViewProj.GetRow (3) + aViewProj.GetRow (2);
|
|
||||||
myClipPlanes[Plane_Far] = aViewProj.GetRow (3) - aViewProj.GetRow (2);
|
|
||||||
|
|
||||||
gp_Pnt aPtCenter = theCamera->Center();
|
|
||||||
OpenGl_Vec4d aCenter (aPtCenter.X(), aPtCenter.Y(), aPtCenter.Z(), 1.0);
|
|
||||||
|
|
||||||
for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB; ++aPlaneIter)
|
|
||||||
{
|
|
||||||
OpenGl_Vec4d anEq = myClipPlanes[aPlaneIter];
|
|
||||||
if (SignedPlanePointDistance (anEq, aCenter) > 0)
|
|
||||||
{
|
|
||||||
anEq *= -1.0;
|
|
||||||
myClipPlanes[aPlaneIter] = anEq;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,17 +162,15 @@ void OpenGl_BVHTreeSelector::SetCullingSize (CullingContext& theCtx,
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
||||||
{
|
{
|
||||||
|
// project frustum onto its own normals
|
||||||
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
||||||
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
|
for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor)
|
||||||
{
|
{
|
||||||
const OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
|
|
||||||
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
|
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
|
||||||
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
|
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
|
||||||
for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
|
for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter)
|
||||||
{
|
{
|
||||||
Standard_Real aProjection = aPlane.x() * myClipVerts[aCornerIter].x()
|
Standard_Real aProjection = myClipVerts[aCornerIter].Dot (myClipPlanes[aPlaneIter].Normal);
|
||||||
+ aPlane.y() * myClipVerts[aCornerIter].y()
|
|
||||||
+ aPlane.z() * myClipVerts[aCornerIter].z();
|
|
||||||
aMaxProj = Max (aProjection, aMaxProj);
|
aMaxProj = Max (aProjection, aMaxProj);
|
||||||
aMinProj = Min (aProjection, aMinProj);
|
aMinProj = Min (aProjection, aMinProj);
|
||||||
}
|
}
|
||||||
@ -220,17 +178,17 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
|||||||
myMinClipProjectionPts[aPlaneIter] = aMinProj;
|
myMinClipProjectionPts[aPlaneIter] = aMinProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// project frustum onto main axes
|
||||||
|
OpenGl_Vec3d anAxes[] = { OpenGl_Vec3d (1.0, 0.0, 0.0),
|
||||||
|
OpenGl_Vec3d (0.0, 1.0, 0.0),
|
||||||
|
OpenGl_Vec3d (0.0, 0.0, 1.0) };
|
||||||
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
|
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
|
||||||
{
|
{
|
||||||
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
|
Standard_Real aMaxProj = -std::numeric_limits<Standard_Real>::max();
|
||||||
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
|
Standard_Real aMinProj = std::numeric_limits<Standard_Real>::max();
|
||||||
for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
|
for (Standard_Integer aCornerIter = 0; aCornerIter < Graphic3d_Camera::FrustumVerticesNB; ++aCornerIter)
|
||||||
{
|
{
|
||||||
Standard_Real aProjection = aDim == 0
|
Standard_Real aProjection = myClipVerts[aCornerIter].Dot (anAxes[aDim]);
|
||||||
? myClipVerts[aCornerIter].x()
|
|
||||||
: (aDim == 1
|
|
||||||
? myClipVerts[aCornerIter].y()
|
|
||||||
: myClipVerts[aCornerIter].z());
|
|
||||||
aMaxProj = Max (aProjection, aMaxProj);
|
aMaxProj = Max (aProjection, aMaxProj);
|
||||||
aMinProj = Min (aProjection, aMinProj);
|
aMinProj = Min (aProjection, aMinProj);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,25 @@ public:
|
|||||||
//! Empty constructor.
|
//! Empty constructor.
|
||||||
CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {}
|
CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Auxiliary structure representing 3D plane.
|
||||||
|
struct Plane
|
||||||
|
{
|
||||||
|
//! Creates default plane.
|
||||||
|
Plane()
|
||||||
|
: Origin (0.0, 0.0, 0.0),
|
||||||
|
Normal (0.0, 0.0, 1.0) {}
|
||||||
|
|
||||||
|
//! Creates plane with specific parameters.
|
||||||
|
Plane (const OpenGl_Vec3d& theOrigin,
|
||||||
|
const OpenGl_Vec3d& theNormal)
|
||||||
|
: Origin (theOrigin),
|
||||||
|
Normal (theNormal) {}
|
||||||
|
|
||||||
|
OpenGl_Vec3d Origin;
|
||||||
|
OpenGl_Vec3d Normal;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Creates an empty selector object with parallel projection type by default.
|
//! Creates an empty selector object with parallel projection type by default.
|
||||||
@ -124,46 +143,54 @@ protected:
|
|||||||
// /
|
// /
|
||||||
// E2
|
// E2
|
||||||
|
|
||||||
// E0 test
|
// E0 test (x axis)
|
||||||
if (theMinPt.x() > myMaxOrthoProjectionPts[0]
|
if (theMinPt.x() > myMaxOrthoProjectionPts[0]
|
||||||
|| theMaxPt.x() < myMinOrthoProjectionPts[0])
|
|| theMaxPt.x() < myMinOrthoProjectionPts[0])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// E1 test
|
// E1 test (y axis)
|
||||||
if (theMinPt.y() > myMaxOrthoProjectionPts[1]
|
if (theMinPt.y() > myMaxOrthoProjectionPts[1]
|
||||||
|| theMaxPt.y() < myMinOrthoProjectionPts[1])
|
|| theMaxPt.y() < myMinOrthoProjectionPts[1])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// E2 test
|
// E2 test (z axis)
|
||||||
if (theMinPt.z() > myMaxOrthoProjectionPts[2]
|
if (theMinPt.z() > myMaxOrthoProjectionPts[2]
|
||||||
|| theMaxPt.z() < myMinOrthoProjectionPts[2])
|
|| theMaxPt.z() < myMinOrthoProjectionPts[2])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0;
|
|
||||||
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
||||||
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
|
for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB - 1; aPlaneIter += anIncFactor)
|
||||||
{
|
{
|
||||||
OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
|
// frustum normals
|
||||||
aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x())
|
const OpenGl_Vec3d anAxis = myClipPlanes[aPlaneIter].Normal;
|
||||||
+ (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y())
|
|
||||||
+ (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z());
|
const OpenGl_Vec3d aPVertex (anAxis.x() > 0.0 ? theMaxPt.x() : theMinPt.x(),
|
||||||
if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter]
|
anAxis.y() > 0.0 ? theMaxPt.y() : theMinPt.y(),
|
||||||
&& aBoxProjMax < myMaxClipProjectionPts[aPlaneIter])
|
anAxis.z() > 0.0 ? theMaxPt.z() : theMinPt.z());
|
||||||
|
Standard_Real aPnt0 = aPVertex.Dot (anAxis);
|
||||||
|
|
||||||
|
if (aPnt0 >= myMinClipProjectionPts[aPlaneIter]
|
||||||
|
&& aPnt0 <= myMaxClipProjectionPts[aPlaneIter])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x())
|
const OpenGl_Vec3d aNVertex (anAxis.x() > 0.0 ? theMinPt.x() : theMaxPt.x(),
|
||||||
+ (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y())
|
anAxis.y() > 0.0 ? theMinPt.y() : theMaxPt.y(),
|
||||||
+ (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z());
|
anAxis.z() > 0.0 ? theMinPt.z() : theMaxPt.z());
|
||||||
if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter]
|
Standard_Real aPnt1 = aNVertex.Dot (anAxis);
|
||||||
|| aBoxProjMax < myMinClipProjectionPts[aPlaneIter])
|
|
||||||
|
const Standard_Real aMin = aPnt0 < aPnt1 ? aPnt0 : aPnt1;
|
||||||
|
const Standard_Real aMax = aPnt0 > aPnt1 ? aPnt0 : aPnt1;
|
||||||
|
|
||||||
|
if (aMin > myMaxClipProjectionPts[aPlaneIter]
|
||||||
|
|| aMax < myMinClipProjectionPts[aPlaneIter])
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -215,38 +242,24 @@ protected:
|
|||||||
//! Enumerates planes of view volume.
|
//! Enumerates planes of view volume.
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Plane_Top,
|
|
||||||
Plane_Bottom,
|
|
||||||
Plane_Left,
|
Plane_Left,
|
||||||
Plane_Right,
|
Plane_Right,
|
||||||
|
Plane_Bottom,
|
||||||
|
Plane_Top,
|
||||||
Plane_Near,
|
Plane_Near,
|
||||||
Plane_Far,
|
Plane_Far,
|
||||||
PlanesNB
|
PlanesNB
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Enumerates vertices of view volume.
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ClipVert_LeftTopNear,
|
|
||||||
ClipVert_LeftBottomNear,
|
|
||||||
ClipVert_RightTopNear,
|
|
||||||
ClipVert_RightBottomNear,
|
|
||||||
ClipVert_LeftTopFar,
|
|
||||||
ClipVert_LeftBottomFar,
|
|
||||||
ClipVert_RightTopFar,
|
|
||||||
ClipVert_RightBottomFar,
|
|
||||||
ClipVerticesNB
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
OpenGl_Vec4d myClipPlanes[PlanesNB]; //!< Plane equations
|
Plane myClipPlanes[PlanesNB]; //!< Planes
|
||||||
OpenGl_Vec4d myClipVerts[ClipVerticesNB]; //!< Vertices
|
NCollection_Array1<OpenGl_Vec3d> myClipVerts; //!< Vertices
|
||||||
|
|
||||||
Handle(Graphic3d_Camera) myCamera; //!< camera definition
|
Handle(Graphic3d_Camera) myCamera; //!< camera definition
|
||||||
|
|
||||||
// for caching clip points projections onto viewing area normals once per traverse
|
// for caching clip points projections onto viewing area normals once per traverse
|
||||||
// ORDER: TOP, BOTTOM, LEFT, RIGHT, NEAR, FAR
|
// ORDER: LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
|
||||||
Standard_Real myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
|
Standard_Real myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
|
||||||
Standard_Real myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
|
Standard_Real myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <AIS_Animation.hxx>
|
#include <AIS_Animation.hxx>
|
||||||
#include <AIS_AnimationCamera.hxx>
|
#include <AIS_AnimationCamera.hxx>
|
||||||
#include <AIS_AnimationObject.hxx>
|
#include <AIS_AnimationObject.hxx>
|
||||||
|
#include <AIS_CameraFrustum.hxx>
|
||||||
#include <AIS_ColorScale.hxx>
|
#include <AIS_ColorScale.hxx>
|
||||||
#include <AIS_Manipulator.hxx>
|
#include <AIS_Manipulator.hxx>
|
||||||
#include <AIS_RubberBand.hxx>
|
#include <AIS_RubberBand.hxx>
|
||||||
@ -8974,6 +8975,7 @@ static int VCamera (Draw_Interpretor& theDI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCollection_AsciiString aPrsName;
|
||||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
||||||
{
|
{
|
||||||
Standard_CString anArg = theArgVec[anArgIter];
|
Standard_CString anArg = theArgVec[anArgIter];
|
||||||
@ -9133,6 +9135,11 @@ static int VCamera (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
theDI << aCamera->FOVy() << " ";
|
theDI << aCamera->FOVy() << " ";
|
||||||
}
|
}
|
||||||
|
else if (aPrsName.IsEmpty()
|
||||||
|
&& !anArgCase.StartsWith ("-"))
|
||||||
|
{
|
||||||
|
aPrsName = anArg;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Error: unknown argument '" << anArg << "'\n";
|
std::cout << "Error: unknown argument '" << anArg << "'\n";
|
||||||
@ -9140,8 +9147,41 @@ static int VCamera (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aPrsName.IsEmpty()
|
||||||
|
|| theArgsNb > 2)
|
||||||
|
{
|
||||||
aView->AutoZFit();
|
aView->AutoZFit();
|
||||||
aView->Redraw();
|
aView->Redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aPrsName.IsEmpty())
|
||||||
|
{
|
||||||
|
Handle(AIS_CameraFrustum) aCameraFrustum;
|
||||||
|
if (GetMapOfAIS().IsBound2 (aPrsName))
|
||||||
|
{
|
||||||
|
// find existing object
|
||||||
|
aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
|
||||||
|
if (aCameraFrustum.IsNull())
|
||||||
|
{
|
||||||
|
std::cout << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum!\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCameraFrustum.IsNull())
|
||||||
|
{
|
||||||
|
aCameraFrustum = new AIS_CameraFrustum();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not include displayed object of old camera frustum in the new one.
|
||||||
|
ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
|
||||||
|
aView->ZFitAll();
|
||||||
|
}
|
||||||
|
aCameraFrustum->SetCameraFrustum (aView->Camera());
|
||||||
|
|
||||||
|
ViewerTest::Display (aPrsName, aCameraFrustum);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -12404,13 +12444,14 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|||||||
"vnbselected"
|
"vnbselected"
|
||||||
"\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
|
"\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
|
||||||
theCommands.Add ("vcamera",
|
theCommands.Add ("vcamera",
|
||||||
"vcamera [-ortho] [-projtype]"
|
"vcamera [PrsName] [-ortho] [-projtype]"
|
||||||
"\n\t\t: [-persp]"
|
"\n\t\t: [-persp]"
|
||||||
"\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
|
"\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
|
||||||
"\n\t\t: [-stereo] [-leftEye] [-rightEye]"
|
"\n\t\t: [-stereo] [-leftEye] [-rightEye]"
|
||||||
"\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
|
"\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
|
||||||
"\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
|
"\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
|
||||||
"\n\t\t: Manage camera parameters."
|
"\n\t\t: Manages camera parameters."
|
||||||
|
"\n\t\t: Displays frustum when presntation name PrsName is specified."
|
||||||
"\n\t\t: Prints current value when option called without argument."
|
"\n\t\t: Prints current value when option called without argument."
|
||||||
"\n\t\t: Orthographic camera:"
|
"\n\t\t: Orthographic camera:"
|
||||||
"\n\t\t: -ortho activate orthographic projection"
|
"\n\t\t: -ortho activate orthographic projection"
|
||||||
|
33
tests/bugs/vis/bug30412
Normal file
33
tests/bugs/vis/bug30412
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
puts "============="
|
||||||
|
puts "0030412: Visualization, TKV3d - add presentation of camera frustum"
|
||||||
|
puts "============="
|
||||||
|
|
||||||
|
pload MODELING VISUALIZATION
|
||||||
|
vclear
|
||||||
|
vinit View1
|
||||||
|
|
||||||
|
vfront
|
||||||
|
vcamera -persp
|
||||||
|
|
||||||
|
set THE_NB_BOXES 5
|
||||||
|
puts "Creating [expr $THE_NB_BOXES * $THE_NB_BOXES * $THE_NB_BOXES] boxes..."
|
||||||
|
for {set i 0} {$i < $THE_NB_BOXES} {incr i} {
|
||||||
|
for {set j 0} {$j < $THE_NB_BOXES} {incr j} {
|
||||||
|
for {set k 0} {$k < $THE_NB_BOXES} {incr k} {
|
||||||
|
box b$i$j$k 3.*$i 3.*$j 3.*$k 1 1 1
|
||||||
|
vdisplay -noupdate -dispMode 1 b$i$j$k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vfit
|
||||||
|
vzoom 1.5
|
||||||
|
vcamera cam
|
||||||
|
|
||||||
|
vright
|
||||||
|
vfit
|
||||||
|
vdump $::imagedir/${::casename}_cam_right.png
|
||||||
|
|
||||||
|
vaxo
|
||||||
|
vfit
|
||||||
|
vdump $::imagedir/${::casename}_cam_axo.png
|
Loading…
x
Reference in New Issue
Block a user