mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0029384: Visualization, TKOpenGl - basic integration with OpenVR
V3d_View::AutoZFit() is now called only before redraw within methods V3d_View::Redraw() and V3d_View::Update(). Graphic3d_CView now holds Aspect_ExtendedRealitySession object. Aspect_OpenVRSession implements new interface via optional OpenVR library. Graphic3d_CView::ProcessInput() - added new interface method which should be called for processing positional input (head tracking). Graphic3d_Camera now allows setting custom stereoscopic Projection matrices. OpenGl_Context::Camera() - context now holds Camera object in addition to active camera matrices. genproj.tcl has been extended to handle optional CSF_OpenVR dependency.
This commit is contained in:
@@ -65,6 +65,7 @@
|
||||
#include <StdSelect_ViewerSelector3d.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <ViewerTest_AutoUpdater.hxx>
|
||||
#include <Aspect_XRSession.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1155,16 +1156,23 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
|
||||
Standard_Integer theArgNb,
|
||||
Standard_CString* theArgVec)
|
||||
{
|
||||
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
||||
if (theArgNb < 2)
|
||||
{
|
||||
Message::SendFail ("Error: wrong number of arguments! Image file name should be specified at least.");
|
||||
return 1;
|
||||
}
|
||||
if (aView.IsNull())
|
||||
{
|
||||
Message::SendFail() << "Error: cannot find an active view!";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Standard_Integer anArgIter = 1;
|
||||
Standard_CString aFilePath = theArgVec[anArgIter++];
|
||||
ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
|
||||
V3d_ImageDumpOptions aParams;
|
||||
Handle(Graphic3d_Camera) aCustomCam;
|
||||
aParams.BufferType = Graphic3d_BT_RGB;
|
||||
aParams.StereoOptions = V3d_SDO_MONO;
|
||||
for (; anArgIter < theArgNb; ++anArgIter)
|
||||
@@ -1203,6 +1211,41 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (anArgIter + 1 < theArgNb
|
||||
&& anArg == "-xrpose")
|
||||
{
|
||||
TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
|
||||
anXRArg.LowerCase();
|
||||
if (anXRArg == "base")
|
||||
{
|
||||
aCustomCam = aView->View()->BaseXRCamera();
|
||||
}
|
||||
else if (anXRArg == "head")
|
||||
{
|
||||
aCustomCam = aView->View()->PosedXRCamera();
|
||||
}
|
||||
else if (anXRArg == "handleft"
|
||||
|| anXRArg == "handright")
|
||||
{
|
||||
if (aView->View()->IsActiveXR())
|
||||
{
|
||||
aCustomCam = new Graphic3d_Camera();
|
||||
aView->View()->ComputeXRPosedCameraFromBase (*aCustomCam, anXRArg == "handleft"
|
||||
? aView->View()->XRSession()->LeftHandPose()
|
||||
: aView->View()->XRSession()->RightHandPose());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
|
||||
return 1;
|
||||
}
|
||||
if (aCustomCam.IsNull())
|
||||
{
|
||||
Message::SendFail() << "Error: undefined XR pose";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (anArg == "-stereo")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
@@ -1324,13 +1367,6 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
|
||||
return 1;
|
||||
}
|
||||
|
||||
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
||||
if (aView.IsNull())
|
||||
{
|
||||
Message::SendFail() << "Error: cannot find an active view!";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (aParams.Width <= 0 || aParams.Height <= 0)
|
||||
{
|
||||
aView->Window()->Size (aParams.Width, aParams.Height);
|
||||
@@ -1347,6 +1383,12 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
|
||||
case Graphic3d_BT_Red: aFormat = Image_Format_Gray; break;
|
||||
}
|
||||
|
||||
const bool wasImmUpdate = aView->SetImmediateUpdate (false);
|
||||
Handle(Graphic3d_Camera) aCamBack = aView->Camera();
|
||||
if (!aCustomCam.IsNull())
|
||||
{
|
||||
aView->SetCamera (aCustomCam);
|
||||
}
|
||||
switch (aStereoPair)
|
||||
{
|
||||
case ViewerTest_SP_Single:
|
||||
@@ -1415,6 +1457,11 @@ static Standard_Integer VDump (Draw_Interpretor& theDI,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!aCustomCam.IsNull())
|
||||
{
|
||||
aView->SetCamera (aCamBack);
|
||||
}
|
||||
aView->SetImmediateUpdate (wasImmUpdate);
|
||||
|
||||
if (!aPixMap.Save (aFilePath))
|
||||
{
|
||||
@@ -6691,6 +6738,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
|
||||
"vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
|
||||
"\n\t\t: [-buffer rgb|rgba|depth=rgb]"
|
||||
"\n\t\t: [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
|
||||
"\n\t\t: [-xrPose base|head|handLeft|handRight=base]"
|
||||
"\n\t\t: [-tileSize Size=0]"
|
||||
"\n\t\t: Dumps content of the active view into image file",
|
||||
__FILE__,VDump,group);
|
||||
|
@@ -9982,9 +9982,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
|
||||
}
|
||||
|
||||
aCurrentView->SetAutoZFitMode (isOn, aScale);
|
||||
aCurrentView->AutoZFit();
|
||||
aCurrentView->Redraw();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10022,6 +10020,8 @@ static int VCamera (Draw_Interpretor& theDI,
|
||||
{
|
||||
theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
|
||||
theDI << "FOVy: " << aCamera->FOVy() << "\n";
|
||||
theDI << "FOVx: " << aCamera->FOVx() << "\n";
|
||||
theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
|
||||
theDI << "Distance: " << aCamera->Distance() << "\n";
|
||||
theDI << "IOD: " << aCamera->IOD() << "\n";
|
||||
theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
|
||||
@@ -10177,18 +10177,83 @@ static int VCamera (Draw_Interpretor& theDI,
|
||||
case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
|
||||
}
|
||||
}
|
||||
else if (anArgCase == "-lockzup"
|
||||
|| anArgCase == "-turntable")
|
||||
{
|
||||
bool toLockUp = true;
|
||||
if (++anArgIter < theArgsNb
|
||||
&& !ViewerTest::ParseOnOff (theArgVec[anArgIter], toLockUp))
|
||||
{
|
||||
--anArgIter;
|
||||
}
|
||||
ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
|
||||
}
|
||||
else if (anArgCase == "-fov"
|
||||
|| anArgCase == "-fovy")
|
||||
|| anArgCase == "-fovy"
|
||||
|| anArgCase == "-fovx"
|
||||
|| anArgCase == "-fov2d")
|
||||
{
|
||||
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
|
||||
if (anArgValue != NULL
|
||||
&& *anArgValue != '-')
|
||||
{
|
||||
++anArgIter;
|
||||
aCamera->SetFOVy (Draw::Atof (anArgValue));
|
||||
if (anArgCase == "-fov2d")
|
||||
{
|
||||
aCamera->SetFOV2d (Draw::Atof (anArgValue));
|
||||
}
|
||||
else if (anArgCase == "-fovx")
|
||||
{
|
||||
aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
|
||||
}
|
||||
else
|
||||
{
|
||||
aCamera->SetFOVy (Draw::Atof (anArgValue));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
theDI << aCamera->FOVy() << " ";
|
||||
if (anArgCase == "-fov2d")
|
||||
{
|
||||
theDI << aCamera->FOV2d() << " ";
|
||||
}
|
||||
else if (anArgCase == "-fovx")
|
||||
{
|
||||
theDI << aCamera->FOVx() << " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
theDI << aCamera->FOVy() << " ";
|
||||
}
|
||||
}
|
||||
else if (anArgIter + 1 < theArgsNb
|
||||
&& anArgCase == "-xrpose")
|
||||
{
|
||||
TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
|
||||
anXRArg.LowerCase();
|
||||
if (anXRArg == "base")
|
||||
{
|
||||
aCamera = aView->View()->BaseXRCamera();
|
||||
}
|
||||
else if (anXRArg == "head")
|
||||
{
|
||||
aCamera = aView->View()->PosedXRCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
|
||||
return 1;
|
||||
}
|
||||
if (aCamera.IsNull())
|
||||
{
|
||||
Message::SendFail() << "Error: undefined XR pose";
|
||||
return 0;
|
||||
}
|
||||
if (aView->AutoZFitMode())
|
||||
{
|
||||
const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
|
||||
const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
|
||||
aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
|
||||
}
|
||||
}
|
||||
else if (aPrsName.IsEmpty()
|
||||
&& !anArgCase.StartsWith ("-"))
|
||||
@@ -10205,7 +10270,6 @@ static int VCamera (Draw_Interpretor& theDI,
|
||||
if (aPrsName.IsEmpty()
|
||||
|| theArgsNb > 2)
|
||||
{
|
||||
aView->AutoZFit();
|
||||
aView->Redraw();
|
||||
}
|
||||
|
||||
@@ -10233,7 +10297,7 @@ static int VCamera (Draw_Interpretor& theDI,
|
||||
ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
|
||||
aView->ZFitAll();
|
||||
}
|
||||
aCameraFrustum->SetCameraFrustum (aView->Camera());
|
||||
aCameraFrustum->SetCameraFrustum (aCamera);
|
||||
|
||||
ViewerTest::Display (aPrsName, aCameraFrustum);
|
||||
}
|
||||
@@ -10286,6 +10350,11 @@ inline Standard_Boolean parseStereoMode (Standard_CString theArg,
|
||||
{
|
||||
theMode = Graphic3d_StereoMode_SoftPageFlip;
|
||||
}
|
||||
else if (aFlag == "openvr"
|
||||
|| aFlag == "vr")
|
||||
{
|
||||
theMode = Graphic3d_StereoMode_OpenVR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Standard_False;
|
||||
@@ -10361,6 +10430,7 @@ static int VStereo (Draw_Interpretor& theDI,
|
||||
case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
|
||||
case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
|
||||
case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
|
||||
case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
|
||||
case Graphic3d_StereoMode_Anaglyph :
|
||||
aMode = "anaglyph";
|
||||
switch (aView->RenderingParams().AnaglyphFilter)
|
||||
@@ -10430,7 +10500,10 @@ static int VStereo (Draw_Interpretor& theDI,
|
||||
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
|
||||
}
|
||||
ViewerTest_myDefaultCaps.contextStereo = Standard_True;
|
||||
return 0;
|
||||
if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (aFlag == "-reverse"
|
||||
|| aFlag == "-reversed"
|
||||
@@ -10491,6 +10564,34 @@ static int VStereo (Draw_Interpretor& theDI,
|
||||
ViewerTest_myDefaultCaps.contextStereo = Standard_True;
|
||||
}
|
||||
}
|
||||
else if (anArgIter + 1 < theArgNb
|
||||
&& aFlag == "-hmdfov2d")
|
||||
{
|
||||
aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
|
||||
if (aParams->HmdFov2d < 10.0f
|
||||
|| aParams->HmdFov2d > 180.0f)
|
||||
{
|
||||
Message::SendFail() << "Error: FOV is out of range";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aFlag == "-mirror"
|
||||
|| aFlag == "-mirrorcomposer")
|
||||
{
|
||||
Standard_Boolean toEnable = Standard_True;
|
||||
if (++anArgIter < theArgNb
|
||||
&& !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
|
||||
{
|
||||
--anArgIter;
|
||||
}
|
||||
aParams->ToMirrorComposer = toEnable;
|
||||
}
|
||||
else if (anArgIter + 1 < theArgNb
|
||||
&& (aFlag == "-unitfactor"
|
||||
|| aFlag == "-unitscale"))
|
||||
{
|
||||
aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
||||
@@ -10502,6 +10603,11 @@ static int VStereo (Draw_Interpretor& theDI,
|
||||
{
|
||||
aParams->StereoMode = aMode;
|
||||
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
|
||||
if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
|
||||
{
|
||||
// initiate implicit continuous rendering
|
||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -13372,6 +13478,7 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
||||
}
|
||||
|
||||
const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
|
||||
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
||||
if (aContext.IsNull())
|
||||
{
|
||||
Message::SendFail ("Error: no active viewer");
|
||||
@@ -13380,6 +13487,7 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
||||
|
||||
TCollection_AsciiString aFile;
|
||||
StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
|
||||
Handle(Graphic3d_Camera) aCustomCam;
|
||||
Image_Format anImgFormat = Image_Format_BGR;
|
||||
Standard_Integer aPickedIndex = 1;
|
||||
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
||||
@@ -13453,6 +13561,30 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
||||
|
||||
aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
|
||||
}
|
||||
else if (anArgIter + 1 < theArgsNb
|
||||
&& aParam == "-xrpose")
|
||||
{
|
||||
TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
|
||||
anXRArg.LowerCase();
|
||||
if (anXRArg == "base")
|
||||
{
|
||||
aCustomCam = aView->View()->BaseXRCamera();
|
||||
}
|
||||
else if (anXRArg == "head")
|
||||
{
|
||||
aCustomCam = aView->View()->PosedXRCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
|
||||
return 1;
|
||||
}
|
||||
if (aCustomCam.IsNull())
|
||||
{
|
||||
Message::SendFail() << "Error: undefined XR pose";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (aFile.IsEmpty())
|
||||
{
|
||||
aFile = theArgVec[anArgIter];
|
||||
@@ -13469,7 +13601,6 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
||||
return 1;
|
||||
}
|
||||
|
||||
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
||||
Standard_Integer aWidth = 0, aHeight = 0;
|
||||
aView->Window()->Size (aWidth, aHeight);
|
||||
|
||||
@@ -13479,11 +13610,24 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
||||
Message::SendFail ("Error: can't allocate image");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const bool wasImmUpdate = aView->SetImmediateUpdate (false);
|
||||
Handle(Graphic3d_Camera) aCamBack = aView->Camera();
|
||||
if (!aCustomCam.IsNull())
|
||||
{
|
||||
aView->SetCamera (aCustomCam);
|
||||
}
|
||||
if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
|
||||
{
|
||||
Message::SendFail ("Error: can't generate selection image");
|
||||
return 1;
|
||||
}
|
||||
if (!aCustomCam.IsNull())
|
||||
{
|
||||
aView->SetCamera (aCamBack);
|
||||
}
|
||||
aView->SetImmediateUpdate (wasImmUpdate);
|
||||
|
||||
if (!aPixMap.Save (aFile))
|
||||
{
|
||||
Message::SendFail ("Error: can't save selection image");
|
||||
@@ -14208,8 +14352,12 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
__FILE__, VVbo, group);
|
||||
theCommands.Add ("vstereo",
|
||||
"vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
|
||||
"\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
|
||||
"\n\t\t: [-anaglyph Filter]"
|
||||
"\n\t\t: Control stereo output mode. Available modes for -mode:"
|
||||
"\n\t\t: Control stereo output mode."
|
||||
"\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
|
||||
"\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
|
||||
"\n\t\t: Available modes for -mode:"
|
||||
"\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
|
||||
"\n\t\t: requires driver support."
|
||||
"\n\t\t: Should be called BEFORE vinit!"
|
||||
@@ -14219,6 +14367,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: chessBoard - chess-board output"
|
||||
"\n\t\t: sideBySide - horizontal pair"
|
||||
"\n\t\t: overUnder - vertical pair"
|
||||
"\n\t\t: openVR - OpenVR (HMD)"
|
||||
"\n\t\t: Available Anaglyph filters for -anaglyph:"
|
||||
"\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
|
||||
"\n\t\t: greenMagentaSimple",
|
||||
@@ -14387,6 +14536,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: [-stereo] [-leftEye] [-rightEye]"
|
||||
"\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
|
||||
"\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
|
||||
"\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
|
||||
"\n\t\t: [-xrPose base|head=base]"
|
||||
"\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."
|
||||
@@ -14395,7 +14546,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: Perspective camera:"
|
||||
"\n\t\t: -persp activate perspective projection (mono)"
|
||||
"\n\t\t: -fovy field of view in y axis, in degrees"
|
||||
"\n\t\t: -fov2d field of view limit for 2d on-screen elements"
|
||||
"\n\t\t: -distance distance of eye from camera center"
|
||||
"\n\t\t: -lockZup lock Z up (tunrtable mode)"
|
||||
"\n\t\t: Stereoscopic camera:"
|
||||
"\n\t\t: -stereo perspective projection (stereo)"
|
||||
"\n\t\t: -leftEye perspective projection (left eye)"
|
||||
@@ -14658,6 +14811,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
|
||||
theCommands.Add ("vseldump",
|
||||
"vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
|
||||
"\n\t\t: [-xrPose base|head=base]"
|
||||
"\n\t\t: Generate an image based on detection results:"
|
||||
"\n\t\t: depth normalized depth values"
|
||||
"\n\t\t: unnormDepth unnormalized depth values"
|
||||
|
Reference in New Issue
Block a user