mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-02 17:46:22 +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:
parent
2615c2d705
commit
b40cdc2b55
@ -3,6 +3,7 @@ StdResource
|
||||
SHMessage
|
||||
Textures
|
||||
Shaders
|
||||
XRResources
|
||||
XSMessage
|
||||
XSTEPResource
|
||||
XmlOcafResource
|
||||
|
@ -222,6 +222,7 @@ n Xw
|
||||
n Cocoa
|
||||
r Textures
|
||||
r Shaders
|
||||
r XRResources
|
||||
t TKMeshVS
|
||||
t TKOpenGl
|
||||
t TKD3DHost
|
||||
|
@ -187,6 +187,9 @@ proc wokdep:gui:UpdateList {} {
|
||||
if { "$::HAVE_FFMPEG" == "true" } {
|
||||
wokdep:SearchFFmpeg anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||
}
|
||||
if { "$::HAVE_OPENVR" == "true" } {
|
||||
wokdep:SearchOpenVR anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||
}
|
||||
if { "$::HAVE_TBB" == "true" } {
|
||||
wokdep:SearchTBB anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||
}
|
||||
@ -472,6 +475,8 @@ checkbutton .myFrame.myChecks.myFImageCheck -offvalue "false" -onvalue "true
|
||||
ttk::label .myFrame.myChecks.myFImageLbl -text "Use FreeImage"
|
||||
checkbutton .myFrame.myChecks.myTbbCheck -offvalue "false" -onvalue "true" -variable HAVE_TBB -command wokdep:gui:UpdateList
|
||||
ttk::label .myFrame.myChecks.myTbbLbl -text "Use Intel TBB"
|
||||
checkbutton .myFrame.myChecks.myOpenVrCheck -offvalue "false" -onvalue "true" -variable HAVE_OPENVR -command wokdep:gui:UpdateList
|
||||
ttk::label .myFrame.myChecks.myOpenVrLbl -text "Use OpenVR"
|
||||
if { "$::tcl_platform(os)" != "Darwin" } {
|
||||
checkbutton .myFrame.myChecks.myGlesCheck -offvalue "false" -onvalue "true" -variable HAVE_GLES2 -command wokdep:gui:UpdateList
|
||||
ttk::label .myFrame.myChecks.myGlesLbl -text "Use OpenGL ES"
|
||||
@ -635,6 +640,8 @@ grid .myFrame.myChecks.myJDKLbl -row $aCheckRowIter -column 13 -sticky w
|
||||
incr aCheckRowIter
|
||||
grid .myFrame.myChecks.myRapidJsonCheck -row $aCheckRowIter -column 0 -sticky e
|
||||
grid .myFrame.myChecks.myRapidJsonLbl -row $aCheckRowIter -column 1 -sticky w
|
||||
grid .myFrame.myChecks.myOpenVrCheck -row $aCheckRowIter -column 4 -sticky e
|
||||
grid .myFrame.myChecks.myOpenVrLbl -row $aCheckRowIter -column 5 -sticky w
|
||||
grid .myFrame.myChecks.myE57Check -row $aCheckRowIter -column 6 -sticky e
|
||||
grid .myFrame.myChecks.myE57Lbl -row $aCheckRowIter -column 7 -sticky w
|
||||
|
||||
|
@ -68,7 +68,7 @@ if { [info exists ::env(SHORTCUT_HEADERS)] } {
|
||||
}
|
||||
|
||||
# fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name
|
||||
set THE_ENV_VARIABLES {HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_E57 HAVE_RAPIDJSON HAVE_OPENCL CHECK_QT4 CHECK_JDK MACOSX_USE_GLX HAVE_RelWithDebInfo BUILD_Inspector}
|
||||
set THE_ENV_VARIABLES {HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_E57 HAVE_RAPIDJSON HAVE_OPENVR HAVE_OPENCL CHECK_QT4 CHECK_JDK MACOSX_USE_GLX HAVE_RelWithDebInfo BUILD_Inspector}
|
||||
foreach anEnvIter $THE_ENV_VARIABLES {
|
||||
set ${anEnvIter} "false"
|
||||
if { [info exists ::env(${anEnvIter})] } {
|
||||
@ -625,6 +625,59 @@ proc wokdep:SearchFFmpeg {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBi
|
||||
return "$isFound"
|
||||
}
|
||||
|
||||
# Search OpenVR SDK placement
|
||||
proc wokdep:SearchOpenVR {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
|
||||
upvar $theErrInc anErrInc
|
||||
upvar $theErrLib32 anErrLib32
|
||||
upvar $theErrLib64 anErrLib64
|
||||
upvar $theErrBin32 anErrBin32
|
||||
upvar $theErrBin64 anErrBin64
|
||||
|
||||
set isFound "true"
|
||||
set anOpenVrHPath [wokdep:SearchHeader "openvr.h"]
|
||||
if { "$anOpenVrHPath" == "" } {
|
||||
set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{openvr}*] "$::VCVER" "$::ARCH" ]
|
||||
if { "$aPath" != "" && [file exists "$aPath/include/openvr.h"] } {
|
||||
lappend ::CSF_OPT_INC "$aPath/include"
|
||||
} elseif { "$aPath" != "" && [file exists "$aPath/headers/openvr.h"] } {
|
||||
lappend ::CSF_OPT_INC "$aPath/headers"
|
||||
} else {
|
||||
lappend anErrInc "Error: 'openvr.h' not found (OpenVR)"
|
||||
set isFound "false"
|
||||
}
|
||||
}
|
||||
|
||||
set aPlatform "unknown"
|
||||
if { "$::tcl_platform(platform)" == "windows" } {
|
||||
set aPlatform "win"
|
||||
} elseif { "$::tcl_platform(os)" == "Darwin" } {
|
||||
set aPlatform "osx"
|
||||
} elseif { "$::tcl_platform(os)" == "Linux" } {
|
||||
set aPlatform "linux"
|
||||
}
|
||||
|
||||
foreach anArchIter {64 32} {
|
||||
set anOpenVrLibPath [wokdep:SearchLib "openvr_api" "$anArchIter"]
|
||||
if { "$anOpenVrLibPath" == "" } {
|
||||
set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{openvr}*] "$::VCVER" "$anArchIter" ]
|
||||
set anOpenVrLibPath [wokdep:SearchLib "openvr_api" "$anArchIter" "$aPath/lib/${aPlatform}${anArchIter}"]
|
||||
set anOpenVrLibPath2 [wokdep:SearchLib "openvr_api" "$anArchIter" "$aPath/lib"]
|
||||
if { "$anOpenVrLibPath" != "" } {
|
||||
lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/${aPlatform}${anArchIter}"
|
||||
lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin/${aPlatform}${anArchIter}"
|
||||
} elseif { "$anOpenVrLibPath2" != "" } {
|
||||
lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib"
|
||||
lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin"
|
||||
} else {
|
||||
lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}openvr_api.${::SYS_LIB_SUFFIX}' not found (OpenVR)"
|
||||
if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "$isFound"
|
||||
}
|
||||
|
||||
# Search TBB library placement
|
||||
proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
|
||||
upvar $theErrInc anErrInc
|
||||
|
@ -1440,6 +1440,9 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap theRelease} {
|
||||
if { "$::HAVE_LIBLZMA" == "true" } {
|
||||
set aLibsMap(CSF_LIBLZMA) "liblzma"
|
||||
}
|
||||
if { "$::HAVE_OPENVR" == "true" } {
|
||||
set aLibsMap(CSF_OpenVR) "openvr_api"
|
||||
}
|
||||
if { "$::HAVE_E57" == "true" && "$theOS" != "wnt" } {
|
||||
# exclude wnt, as there are different pragma lib depending on debug/release
|
||||
set aLibsMap(CSF_E57) "E57RefImpl"
|
||||
|
@ -25,6 +25,7 @@ set "HAVE_D3D=false"
|
||||
set "HAVE_ZLIB=false"
|
||||
set "HAVE_LIBLZMA=false"
|
||||
set "HAVE_RAPIDJSON=false"
|
||||
set "HAVE_OPENVR=false"
|
||||
set "HAVE_E57=false"
|
||||
set "CSF_OPT_INC="
|
||||
set "CSF_OPT_LIB32="
|
||||
@ -189,6 +190,7 @@ if ["%HAVE_D3D%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DH
|
||||
if ["%HAVE_ZLIB%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_ZLIB" & set "CSF_DEFINES=HAVE_ZLIB;%CSF_DEFINES%"
|
||||
if ["%HAVE_LIBLZMA%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_LIBLZMA" & set "CSF_DEFINES=HAVE_LIBLZMA;%CSF_DEFINES%"
|
||||
if ["%HAVE_RAPIDJSON%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_RAPIDJSON" & set "CSF_DEFINES=HAVE_RAPIDJSON;%CSF_DEFINES%"
|
||||
if ["%HAVE_OPENVR%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_OPENVR" & set "CSF_DEFINES=HAVE_OPENVR;%CSF_DEFINES%"
|
||||
if ["%HAVE_E57%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_E57" & set "CSF_DEFINES=HAVE_E57;%CSF_DEFINES%"
|
||||
|
||||
rem Eliminate VS warning
|
||||
|
@ -16,6 +16,7 @@ export HAVE_GLES2="false";
|
||||
export HAVE_ZLIB="false";
|
||||
export HAVE_LIBLZMA="false";
|
||||
export HAVE_RAPIDJSON="false";
|
||||
export HAVE_OPENVR="false";
|
||||
export HAVE_E57="false";
|
||||
export MACOSX_USE_GLX="false";
|
||||
export CSF_OPT_INC=""
|
||||
@ -106,6 +107,7 @@ if [ "$HAVE_VTK" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -D
|
||||
if [ "$HAVE_ZLIB" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_ZLIB"; fi
|
||||
if [ "$HAVE_LIBLZMA" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_LIBLZMA"; fi
|
||||
if [ "$HAVE_RAPIDJSON" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_RAPIDJSON"; fi
|
||||
if [ "$HAVE_OPENVR" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_OPENVR"; fi
|
||||
if [ "$HAVE_E57" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_E57"; fi
|
||||
# Option to compile OCCT with X11 libs on Mac OS X
|
||||
if [ "$MACOSX_USE_GLX" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DMACOSX_USE_GLX"; fi
|
||||
|
@ -18,8 +18,12 @@
|
||||
#include <AIS_Manipulator.hxx>
|
||||
#include <AIS_Point.hxx>
|
||||
#include <AIS_RubberBand.hxx>
|
||||
#include <AIS_XRTrackedDevice.hxx>
|
||||
#include <Aspect_XRSession.hxx>
|
||||
#include <Aspect_Grid.hxx>
|
||||
#include <Geom_CartesianPoint.hxx>
|
||||
#include <Graphic3d_ArrayOfSegments.hxx>
|
||||
#include <Graphic3d_Texture2Dmanual.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <gp_Quaternion.hxx>
|
||||
@ -60,6 +64,17 @@ AIS_ViewController::AIS_ViewController()
|
||||
myPrevMoveTo (-1, -1),
|
||||
myHasHlrOnBeforeRotation (false),
|
||||
//
|
||||
myXRPrsDevices (0, 0),
|
||||
myXRLaserTeleColor (Quantity_NOC_GREEN),
|
||||
myXRLaserPickColor (Quantity_NOC_BLUE),
|
||||
myXRLastTeleportHand(Aspect_XRTrackedDeviceRole_Other),
|
||||
myXRLastPickingHand (Aspect_XRTrackedDeviceRole_Other),
|
||||
myXRLastPickDepthLeft (Precision::Infinite()),
|
||||
myXRLastPickDepthRight(Precision::Infinite()),
|
||||
myXRTurnAngle (M_PI_4),
|
||||
myToDisplayXRAuxDevices (false),
|
||||
myToDisplayXRHands (true),
|
||||
//
|
||||
myMouseClickThreshold (3.0),
|
||||
myMouseDoubleClickInt (0.4),
|
||||
myScrollZoomRatio (15.0f),
|
||||
@ -111,6 +126,18 @@ AIS_ViewController::AIS_ViewController()
|
||||
|
||||
myMouseGestureMap.Bind (Aspect_VKeyMouse_MiddleButton, AIS_MouseGesture_Pan);
|
||||
myMouseGestureMap.Bind (Aspect_VKeyMouse_MiddleButton | Aspect_VKeyFlags_CTRL, AIS_MouseGesture_Pan);
|
||||
|
||||
myXRTeleportHaptic.Duration = 3600.0f;
|
||||
myXRTeleportHaptic.Frequency = 0.1f;
|
||||
myXRTeleportHaptic.Amplitude = 0.2f;
|
||||
|
||||
myXRPickingHaptic.Duration = 0.1f;
|
||||
myXRPickingHaptic.Frequency = 4.0f;
|
||||
myXRPickingHaptic.Amplitude = 0.1f;
|
||||
|
||||
myXRSelectHaptic.Duration = 0.2f;
|
||||
myXRSelectHaptic.Frequency = 4.0f;
|
||||
myXRSelectHaptic.Amplitude = 0.5f;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1287,6 +1314,7 @@ void AIS_ViewController::handlePanning (const Handle(V3d_View)& theView)
|
||||
{
|
||||
theView->Pan (myGL.Panning.Delta.x(), myGL.Panning.Delta.y());
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1307,6 +1335,7 @@ void AIS_ViewController::handlePanning (const Handle(V3d_View)& theView)
|
||||
aPanTrsf.SetTranslation (aCameraPan);
|
||||
aCam->Transform (aPanTrsf);
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1331,6 +1360,7 @@ void AIS_ViewController::handleZRotate (const Handle(V3d_View)& theView)
|
||||
aRotPnt.y() += myGL.ZRotate.Angle * aViewPort.y();
|
||||
theView->Rotation (int(aRotPnt.x()), int(aRotPnt.y()));
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1361,6 +1391,7 @@ void AIS_ViewController::handleZoom (const Handle(V3d_View)& theView,
|
||||
aCoeff = theParams.Delta > 0.0 ? aCoeff : 1.0 / aCoeff;
|
||||
theView->SetZoom (aCoeff, true);
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1432,6 +1463,7 @@ void AIS_ViewController::handleZoom (const Handle(V3d_View)& theView,
|
||||
aPanTrsf.SetTranslation (aCameraPan);
|
||||
aCam->Transform (aPanTrsf);
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1452,7 +1484,7 @@ void AIS_ViewController::handleZFocusScroll (const Handle(V3d_View)& theView,
|
||||
&& aFocus < 2.0)
|
||||
{
|
||||
theView->Camera()->SetZFocus (theView->Camera()->ZFocusType(), aFocus);
|
||||
theView->Redraw();
|
||||
theView->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1469,7 +1501,9 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
|
||||
return;
|
||||
}
|
||||
|
||||
const Handle(Graphic3d_Camera)& aCam = theView->Camera();
|
||||
const Handle(Graphic3d_Camera)& aCam = theView->View()->IsActiveXR()
|
||||
? theView->View()->BaseXRCamera()
|
||||
: theView->Camera();
|
||||
if (myGL.OrbitRotation.ToStart)
|
||||
{
|
||||
// default alternatives
|
||||
@ -1508,9 +1542,13 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
|
||||
theView->Window()->Size (aWinXY.x(), aWinXY.y());
|
||||
double aYawAngleDelta = ((myGL.OrbitRotation.PointStart.x() - myGL.OrbitRotation.PointTo.x()) / double (aWinXY.x())) * (M_PI * 0.5);
|
||||
double aPitchAngleDelta = -((myGL.OrbitRotation.PointStart.y() - myGL.OrbitRotation.PointTo.y()) / double (aWinXY.y())) * (M_PI * 0.5);
|
||||
const double aPitchAngleNew = Max (Min (myRotateStartYawPitchRoll[1] + aPitchAngleDelta, M_PI * 0.5 - M_PI / 180.0), -M_PI * 0.5 + M_PI / 180.0);
|
||||
const double aYawAngleNew = myRotateStartYawPitchRoll[0] + aYawAngleDelta;
|
||||
const double aRoll = 0.0;
|
||||
double aPitchAngleNew = 0.0, aRoll = 0.0;
|
||||
const double aYawAngleNew = myRotateStartYawPitchRoll[0] + aYawAngleDelta;
|
||||
if (!theView->View()->IsActiveXR())
|
||||
{
|
||||
aPitchAngleNew = Max (Min (myRotateStartYawPitchRoll[1] + aPitchAngleDelta, M_PI * 0.5 - M_PI / 180.0), -M_PI * 0.5 + M_PI / 180.0);
|
||||
aRoll = 0.0;
|
||||
}
|
||||
|
||||
gp_Quaternion aRot;
|
||||
aRot.SetEulerAngles (gp_YawPitchRoll, aYawAngleNew, aPitchAngleNew, aRoll);
|
||||
@ -1564,6 +1602,7 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
|
||||
}
|
||||
|
||||
theView->Invalidate();
|
||||
theView->View()->SynchronizeXRBaseToPosedCamera();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -1933,6 +1972,251 @@ void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContex
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRInput
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRInput (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView,
|
||||
const AIS_WalkDelta& )
|
||||
{
|
||||
theView->View()->ProcessXRInput();
|
||||
if (!theView->View()->IsActiveXR())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (myXRCameraTmp.IsNull())
|
||||
{
|
||||
myXRCameraTmp = new Graphic3d_Camera();
|
||||
}
|
||||
handleXRTurnPad (theCtx, theView);
|
||||
handleXRTeleport(theCtx, theView);
|
||||
handleXRPicking (theCtx, theView);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRTurnPad
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRTurnPad (const Handle(AIS_InteractiveContext)& ,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
if (myXRTurnAngle <= 0.0
|
||||
|| !theView->View()->IsActiveXR())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// turn left/right at 45 degrees on left/right trackpad clicks
|
||||
for (int aHand = 0; aHand < 2; ++aHand)
|
||||
{
|
||||
const Aspect_XRTrackedDeviceRole aRole = aHand == 0 ? Aspect_XRTrackedDeviceRole_RightHand : Aspect_XRTrackedDeviceRole_LeftHand;
|
||||
const Handle(Aspect_XRAction)& aPadClickAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTrackPadClick);
|
||||
const Handle(Aspect_XRAction)& aPadPosAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTrackPadPosition);
|
||||
if (aPadClickAct.IsNull()
|
||||
|| aPadPosAct.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Aspect_XRDigitalActionData aPadClick = theView->View()->XRSession()->GetDigitalActionData (aPadClickAct);
|
||||
const Aspect_XRAnalogActionData aPadPos = theView->View()->XRSession()->GetAnalogActionData (aPadPosAct);
|
||||
if (aPadClick.IsActive
|
||||
&& aPadClick.IsPressed
|
||||
&& aPadClick.IsChanged
|
||||
&& aPadPos.IsActive
|
||||
&& Abs (aPadPos.VecXYZ.y()) < 0.5f
|
||||
&& Abs (aPadPos.VecXYZ.x()) > 0.7f)
|
||||
{
|
||||
gp_Trsf aTrsfTurn;
|
||||
aTrsfTurn.SetRotation (gp_Ax1 (gp::Origin(), theView->View()->BaseXRCamera()->Up()), aPadPos.VecXYZ.x() < 0.0f ? myXRTurnAngle : -myXRTurnAngle);
|
||||
theView->View()->TurnViewXRCamera (aTrsfTurn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRTeleport
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRTeleport (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
if (!theView->View()->IsActiveXR())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// teleport on forward trackpad unclicks
|
||||
const Aspect_XRTrackedDeviceRole aTeleOld = myXRLastTeleportHand;
|
||||
myXRLastTeleportHand = Aspect_XRTrackedDeviceRole_Other;
|
||||
for (int aHand = 0; aHand < 2; ++aHand)
|
||||
{
|
||||
const Aspect_XRTrackedDeviceRole aRole = aHand == 0 ? Aspect_XRTrackedDeviceRole_RightHand : Aspect_XRTrackedDeviceRole_LeftHand;
|
||||
const Standard_Integer aDeviceId = theView->View()->XRSession()->NamedTrackedDevice (aRole);
|
||||
if (aDeviceId == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Handle(Aspect_XRAction)& aPadClickAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTrackPadClick);
|
||||
const Handle(Aspect_XRAction)& aPadPosAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTrackPadPosition);
|
||||
if (aPadClickAct.IsNull()
|
||||
|| aPadPosAct.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Aspect_XRDigitalActionData aPadClick = theView->View()->XRSession()->GetDigitalActionData (aPadClickAct);
|
||||
const Aspect_XRAnalogActionData aPadPos = theView->View()->XRSession()->GetAnalogActionData (aPadPosAct);
|
||||
const bool isPressed = aPadClick.IsPressed;
|
||||
const bool isClicked = !aPadClick.IsPressed
|
||||
&& aPadClick.IsChanged;
|
||||
if (aPadClick.IsActive
|
||||
&& (isPressed || isClicked)
|
||||
&& aPadPos.IsActive
|
||||
&& aPadPos.VecXYZ.y() > 0.6f
|
||||
&& Abs (aPadPos.VecXYZ.x()) < 0.5f)
|
||||
{
|
||||
const Aspect_TrackedDevicePose& aPose = theView->View()->XRSession()->TrackedPoses()[aDeviceId];
|
||||
if (!aPose.IsValidPose)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
myXRLastTeleportHand = aRole;
|
||||
Standard_Real& aPickDepth = aRole == Aspect_XRTrackedDeviceRole_LeftHand ? myXRLastPickDepthLeft : myXRLastPickDepthRight;
|
||||
aPickDepth = Precision::Infinite();
|
||||
Graphic3d_Vec3 aPickNorm;
|
||||
const gp_Trsf aHandBase = theView->View()->PoseXRToWorld (aPose.Orientation);
|
||||
const Standard_Real aHeadHeight = theView->View()->XRSession()->HeadPose().TranslationPart().Y();
|
||||
{
|
||||
const Standard_Integer aPickedId = handleXRMoveTo (theCtx, theView, aPose.Orientation, false);
|
||||
if (aPickedId >= 1)
|
||||
{
|
||||
const SelectMgr_SortCriterion& aPickedData = theCtx->MainSelector()->PickedData (aPickedId);
|
||||
aPickNorm = aPickedData.Normal;
|
||||
if (aPickNorm.SquareModulus() > ShortRealEpsilon())
|
||||
{
|
||||
aPickDepth = aPickedData.Point.Distance (aHandBase.TranslationPart());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isClicked)
|
||||
{
|
||||
myXRLastTeleportHand = Aspect_XRTrackedDeviceRole_Other;
|
||||
if (!Precision::IsInfinite (aPickDepth))
|
||||
{
|
||||
const gp_Dir aTeleDir = -gp::DZ().Transformed (aHandBase);
|
||||
const gp_Dir anUpDir = theView->View()->BaseXRCamera()->Up();
|
||||
|
||||
bool isHorizontal = false;
|
||||
gp_Dir aPickNormDir (aPickNorm.x(), aPickNorm.y(), aPickNorm.z());
|
||||
if (anUpDir.IsEqual ( aPickNormDir, M_PI_4)
|
||||
|| anUpDir.IsEqual (-aPickNormDir, M_PI_4))
|
||||
{
|
||||
isHorizontal = true;
|
||||
}
|
||||
|
||||
gp_Pnt aNewEye = aHandBase.TranslationPart();
|
||||
if (isHorizontal)
|
||||
{
|
||||
aNewEye = aHandBase.TranslationPart()
|
||||
+ aTeleDir.XYZ() * aPickDepth
|
||||
+ anUpDir.XYZ() * aHeadHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aPickNormDir.Dot (aTeleDir) < 0.0)
|
||||
{
|
||||
aPickNormDir.Reverse();
|
||||
}
|
||||
aNewEye = aHandBase.TranslationPart()
|
||||
+ aTeleDir.XYZ() * aPickDepth
|
||||
- aPickNormDir.XYZ() * aHeadHeight / 4;
|
||||
}
|
||||
|
||||
theView->View()->PosedXRCamera()->MoveEyeTo (aNewEye);
|
||||
theView->View()->ComputeXRBaseCameraFromPosed (theView->View()->PosedXRCamera(), theView->View()->XRSession()->HeadPose());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (myXRLastTeleportHand != aTeleOld)
|
||||
{
|
||||
if (aTeleOld != Aspect_XRTrackedDeviceRole_Other)
|
||||
{
|
||||
if (const Handle(Aspect_XRAction)& aHaptic = theView->View()->XRSession()->GenericAction (aTeleOld, Aspect_XRGenericAction_OutputHaptic))
|
||||
{
|
||||
theView->View()->XRSession()->AbortHapticVibrationAction (aHaptic);
|
||||
}
|
||||
}
|
||||
if (myXRLastTeleportHand != Aspect_XRTrackedDeviceRole_Other)
|
||||
{
|
||||
if (const Handle(Aspect_XRAction)& aHaptic = theView->View()->XRSession()->GenericAction (myXRLastTeleportHand, Aspect_XRGenericAction_OutputHaptic))
|
||||
{
|
||||
theView->View()->XRSession()->TriggerHapticVibrationAction (aHaptic, myXRTeleportHaptic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRPicking
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRPicking (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
if (!theView->View()->IsActiveXR())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// handle selection on trigger clicks
|
||||
Aspect_XRTrackedDeviceRole aPickDevOld = myXRLastPickingHand;
|
||||
myXRLastPickingHand = Aspect_XRTrackedDeviceRole_Other;
|
||||
for (int aHand = 0; aHand < 2; ++aHand)
|
||||
{
|
||||
const Aspect_XRTrackedDeviceRole aRole = aHand == 0 ? Aspect_XRTrackedDeviceRole_RightHand : Aspect_XRTrackedDeviceRole_LeftHand;
|
||||
const Handle(Aspect_XRAction)& aTrigClickAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTriggerClick);
|
||||
const Handle(Aspect_XRAction)& aTrigPullAct = theView->View()->XRSession()->GenericAction (aRole, Aspect_XRGenericAction_InputTriggerPull);
|
||||
if (aTrigClickAct.IsNull()
|
||||
|| aTrigPullAct.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Aspect_XRDigitalActionData aTrigClick = theView->View()->XRSession()->GetDigitalActionData (aTrigClickAct);
|
||||
const Aspect_XRAnalogActionData aTrigPos = theView->View()->XRSession()->GetAnalogActionData (aTrigPullAct);
|
||||
if (aTrigPos.IsActive
|
||||
&& Abs (aTrigPos.VecXYZ.x()) > 0.1f)
|
||||
{
|
||||
myXRLastPickingHand = aRole;
|
||||
handleXRHighlight (theCtx, theView);
|
||||
if (aTrigClick.IsActive
|
||||
&& aTrigClick.IsPressed
|
||||
&& aTrigClick.IsChanged)
|
||||
{
|
||||
theCtx->Select (false);
|
||||
OnSelectionChanged (theCtx, theView);
|
||||
if (const Handle(Aspect_XRAction)& aHaptic = theView->View()->XRSession()->GenericAction (myXRLastPickingHand, Aspect_XRGenericAction_OutputHaptic))
|
||||
{
|
||||
theView->View()->XRSession()->TriggerHapticVibrationAction (aHaptic, myXRSelectHaptic);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myXRLastPickingHand != aPickDevOld)
|
||||
{
|
||||
theCtx->ClearDetected();
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : OnSelectionChanged
|
||||
// purpose :
|
||||
@ -2041,6 +2325,7 @@ void AIS_ViewController::contextLazyMoveTo (const Handle(AIS_InteractiveContext)
|
||||
myPrevMoveTo = thePnt;
|
||||
|
||||
Handle(SelectMgr_EntityOwner) aLastPicked = theCtx->DetectedOwner();
|
||||
theView->AutoZFit();
|
||||
theCtx->MoveTo (thePnt.x(), thePnt.y(), theView, false);
|
||||
Handle(SelectMgr_EntityOwner) aNewPicked = theCtx->DetectedOwner();
|
||||
|
||||
@ -2272,9 +2557,10 @@ void AIS_ViewController::handleDynamicHighlight (const Handle(AIS_InteractiveCon
|
||||
else if (myToAllowHighlight)
|
||||
{
|
||||
if (myPrevMoveTo != aMoveToPnt
|
||||
|| myGL.OrbitRotation.ToRotate
|
||||
|| myGL.ViewRotation.ToRotate
|
||||
|| theView->IsInvalidated())
|
||||
|| (!theView->View()->IsActiveXR()
|
||||
&& (myGL.OrbitRotation.ToRotate
|
||||
|| myGL.ViewRotation.ToRotate
|
||||
|| theView->IsInvalidated())))
|
||||
{
|
||||
ResetPreviousMoveTo();
|
||||
contextLazyMoveTo (theCtx, theView, aMoveToPnt);
|
||||
@ -2340,6 +2626,12 @@ void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)&
|
||||
setAskNextFrame();
|
||||
}
|
||||
|
||||
if (theView->View()->IsActiveXR())
|
||||
{
|
||||
// VR requires continuous rendering
|
||||
myToAskNextFrame = true;
|
||||
}
|
||||
|
||||
for (V3d_ListOfViewIterator aViewIter (theView->Viewer()->ActiveViewIterator()); aViewIter.More(); aViewIter.Next())
|
||||
{
|
||||
const Handle(V3d_View)& aView = aViewIter.Value();
|
||||
@ -2368,6 +2660,266 @@ void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)&
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRMoveTo
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer AIS_ViewController::handleXRMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView,
|
||||
const gp_Trsf& thePose,
|
||||
const Standard_Boolean theToHighlight)
|
||||
{
|
||||
//ResetPreviousMoveTo();
|
||||
Standard_Integer aPickResult = 0;
|
||||
|
||||
Handle(Graphic3d_Camera) aCamBack = theView->Camera();
|
||||
myXRCameraTmp->Copy (aCamBack);
|
||||
theView->View()->ComputeXRPosedCameraFromBase (*myXRCameraTmp, thePose);
|
||||
theView->SetCamera (myXRCameraTmp);
|
||||
Graphic3d_Vec2i aPickPixel;
|
||||
theView->Window()->Size (aPickPixel.x(), aPickPixel.y());
|
||||
aPickPixel /= 2;
|
||||
const Standard_Integer aSelTolerBack = theCtx->MainSelector()->CustomPixelTolerance();
|
||||
theCtx->MainSelector()->SetPixelTolerance (1);
|
||||
theView->AutoZFit();
|
||||
if (theToHighlight)
|
||||
{
|
||||
theCtx->MoveTo (aPickPixel.x(), aPickPixel.y(), theView, false);
|
||||
if (!theCtx->DetectedOwner().IsNull())
|
||||
{
|
||||
// ignore 2D objects
|
||||
for (aPickResult = 1; !theCtx->DetectedOwner()->Selectable()->TransformPersistence().IsNull(); ++aPickResult)
|
||||
{
|
||||
if (theCtx->HilightNextDetected (theView, false) <= 1)
|
||||
{
|
||||
theCtx->ClearDetected();
|
||||
aPickResult = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->MainSelector()->Pick (aPickPixel.x(), aPickPixel.y(), theView);
|
||||
for (Standard_Integer aPickIter = 1; aPickIter <= theCtx->MainSelector()->NbPicked(); ++aPickIter)
|
||||
{
|
||||
const SelectMgr_SortCriterion& aPickedData = theCtx->MainSelector()->PickedData (aPickIter);
|
||||
if (!aPickedData.Entity->OwnerId()->Selectable()->TransformPersistence().IsNull())
|
||||
{
|
||||
// skip 2d objects
|
||||
continue;
|
||||
}
|
||||
|
||||
aPickResult = aPickIter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
theCtx->MainSelector()->SetPixelTolerance (aSelTolerBack);
|
||||
theView->SetCamera (aCamBack);
|
||||
return aPickResult;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRHighlight
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRHighlight (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
if (myXRLastPickingHand != Aspect_XRTrackedDeviceRole_LeftHand
|
||||
&& myXRLastPickingHand != Aspect_XRTrackedDeviceRole_RightHand)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aDeviceId = theView->View()->XRSession()->NamedTrackedDevice (myXRLastPickingHand);
|
||||
if (aDeviceId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Aspect_TrackedDevicePose& aPose = theView->View()->XRSession()->TrackedPoses()[aDeviceId];
|
||||
if (!aPose.IsValidPose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(SelectMgr_EntityOwner) aDetOld = theCtx->DetectedOwner();
|
||||
handleXRMoveTo (theCtx, theView, aPose.Orientation, true);
|
||||
if (!theCtx->DetectedOwner().IsNull()
|
||||
&& theCtx->DetectedOwner() != aDetOld)
|
||||
{
|
||||
if (const Handle(Aspect_XRAction)& aHaptic = theView->View()->XRSession()->GenericAction (myXRLastPickingHand, Aspect_XRGenericAction_OutputHaptic))
|
||||
{
|
||||
theView->View()->XRSession()->TriggerHapticVibrationAction (aHaptic, myXRPickingHaptic);
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Real& aPickDepth = myXRLastPickingHand == Aspect_XRTrackedDeviceRole_LeftHand ? myXRLastPickDepthLeft : myXRLastPickDepthRight;
|
||||
aPickDepth = Precision::Infinite();
|
||||
if (theCtx->MainSelector()->NbPicked() > 0)
|
||||
{
|
||||
const gp_Trsf aHandBase = theView->View()->PoseXRToWorld (aPose.Orientation);
|
||||
const SelectMgr_SortCriterion& aPicked = theCtx->MainSelector()->PickedData (1);
|
||||
aPickDepth = aPicked.Point.Distance (aHandBase.TranslationPart());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleXRPresentations
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::handleXRPresentations (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
if (!theView->View()->IsActiveXR()
|
||||
|| (!myToDisplayXRAuxDevices
|
||||
&& !myToDisplayXRHands))
|
||||
{
|
||||
for (NCollection_Array1<Handle(AIS_XRTrackedDevice)>::Iterator aPrsIter (myXRPrsDevices); aPrsIter.More(); aPrsIter.Next())
|
||||
{
|
||||
if (!aPrsIter.Value().IsNull()
|
||||
&& aPrsIter.Value()->HasInteractiveContext())
|
||||
{
|
||||
theCtx->Remove (aPrsIter.Value(), false);
|
||||
}
|
||||
aPrsIter.ChangeValue().Nullify();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (myXRPrsDevices.Length() != theView->View()->XRSession()->TrackedPoses().Length())
|
||||
{
|
||||
for (NCollection_Array1<Handle(AIS_XRTrackedDevice)>::Iterator aPrsIter (myXRPrsDevices); aPrsIter.More(); aPrsIter.Next())
|
||||
{
|
||||
if (!aPrsIter.Value().IsNull())
|
||||
{
|
||||
theCtx->Remove (aPrsIter.Value(), false);
|
||||
}
|
||||
}
|
||||
myXRPrsDevices.Resize (theView->View()->XRSession()->TrackedPoses().Lower(), theView->View()->XRSession()->TrackedPoses().Upper(), false);
|
||||
}
|
||||
|
||||
const Standard_Integer aHeadDevice = theView->View()->XRSession()->NamedTrackedDevice (Aspect_XRTrackedDeviceRole_Head);
|
||||
const Standard_Integer aLeftDevice = theView->View()->XRSession()->NamedTrackedDevice (Aspect_XRTrackedDeviceRole_LeftHand);
|
||||
const Standard_Integer aRightDevice = theView->View()->XRSession()->NamedTrackedDevice (Aspect_XRTrackedDeviceRole_RightHand);
|
||||
for (Standard_Integer aDeviceIter = theView->View()->XRSession()->TrackedPoses().Lower(); aDeviceIter <= theView->View()->XRSession()->TrackedPoses().Upper(); ++aDeviceIter)
|
||||
{
|
||||
const Aspect_TrackedDevicePose& aPose = theView->View()->XRSession()->TrackedPoses()[aDeviceIter];
|
||||
Handle(AIS_XRTrackedDevice)& aPosePrs = myXRPrsDevices[aDeviceIter];
|
||||
if (!aPose.IsValidPose)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool isHand = aDeviceIter == aLeftDevice
|
||||
|| aDeviceIter == aRightDevice;
|
||||
if ((!myToDisplayXRHands && isHand)
|
||||
|| (!myToDisplayXRAuxDevices && !isHand))
|
||||
{
|
||||
if (!aPosePrs.IsNull()
|
||||
&& aPosePrs->HasInteractiveContext())
|
||||
{
|
||||
theCtx->Remove (aPosePrs, false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Aspect_XRTrackedDeviceRole aRole = Aspect_XRTrackedDeviceRole_Other;
|
||||
if (aDeviceIter == aLeftDevice)
|
||||
{
|
||||
aRole = Aspect_XRTrackedDeviceRole_LeftHand;
|
||||
}
|
||||
else if (aDeviceIter == aRightDevice)
|
||||
{
|
||||
aRole = Aspect_XRTrackedDeviceRole_RightHand;
|
||||
}
|
||||
|
||||
if (!aPosePrs.IsNull()
|
||||
&& aPosePrs->UnitFactor() != (float )theView->View()->UnitFactor())
|
||||
{
|
||||
theCtx->Remove (aPosePrs, false);
|
||||
aPosePrs.Nullify();
|
||||
}
|
||||
|
||||
if (aPosePrs.IsNull())
|
||||
{
|
||||
Handle(Image_Texture) aTexture;
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTris;
|
||||
if (aDeviceIter != aHeadDevice)
|
||||
{
|
||||
aTris = theView->View()->XRSession()->LoadRenderModel (aDeviceIter, aTexture);
|
||||
}
|
||||
if (!aTris.IsNull())
|
||||
{
|
||||
aPosePrs = new AIS_XRTrackedDevice (aTris, aTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
aPosePrs = new AIS_XRTrackedDevice();
|
||||
}
|
||||
aPosePrs->SetUnitFactor ((float )theView->View()->UnitFactor());
|
||||
aPosePrs->SetMutable (true);
|
||||
aPosePrs->SetInfiniteState (true);
|
||||
}
|
||||
aPosePrs->SetRole (aRole);
|
||||
|
||||
if (!aPosePrs->HasInteractiveContext())
|
||||
{
|
||||
theCtx->Display (aPosePrs, 0, -1, false);
|
||||
}
|
||||
|
||||
gp_Trsf aPoseLocal = aPose.Orientation;
|
||||
if (aDeviceIter == aHeadDevice)
|
||||
{
|
||||
// show headset position on floor level
|
||||
aPoseLocal.SetTranslationPart (gp_Vec (aPoseLocal.TranslationPart().X(), 0.0, aPoseLocal.TranslationPart().Z()));
|
||||
}
|
||||
const gp_Trsf aPoseWorld = theView->View()->PoseXRToWorld (aPoseLocal);
|
||||
theCtx->SetLocation (aPosePrs, aPoseWorld);
|
||||
|
||||
Standard_Real aLaserLen = 0.0;
|
||||
if (isHand
|
||||
&& aPosePrs->Role() == myXRLastPickingHand)
|
||||
{
|
||||
aLaserLen = myXRLastPickingHand == Aspect_XRTrackedDeviceRole_LeftHand ? myXRLastPickDepthLeft : myXRLastPickDepthRight;
|
||||
if (Precision::IsInfinite (aLaserLen))
|
||||
{
|
||||
const Bnd_Box aViewBox = theView->View()->MinMaxValues (true);
|
||||
if (!aViewBox.IsVoid())
|
||||
{
|
||||
aLaserLen = Sqrt (aViewBox.SquareExtent());
|
||||
}
|
||||
else
|
||||
{
|
||||
aLaserLen = 100.0;
|
||||
}
|
||||
}
|
||||
aPosePrs->SetLaserColor (myXRLaserPickColor);
|
||||
}
|
||||
else if (isHand
|
||||
&& aPosePrs->Role() == myXRLastTeleportHand)
|
||||
{
|
||||
aLaserLen = myXRLastTeleportHand == Aspect_XRTrackedDeviceRole_LeftHand ? myXRLastPickDepthLeft : myXRLastPickDepthRight;
|
||||
if (Precision::IsInfinite (aLaserLen))
|
||||
{
|
||||
const Bnd_Box aViewBox = theView->View()->MinMaxValues (true);
|
||||
if (!aViewBox.IsVoid())
|
||||
{
|
||||
aLaserLen = Sqrt (aViewBox.SquareExtent());
|
||||
}
|
||||
else
|
||||
{
|
||||
aLaserLen = 100.0;
|
||||
}
|
||||
}
|
||||
aPosePrs->SetLaserColor (myXRLaserTeleColor);
|
||||
}
|
||||
aPosePrs->SetLaserLength ((float )aLaserLen);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : HandleViewEvents
|
||||
// purpose :
|
||||
@ -2375,11 +2927,23 @@ void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)&
|
||||
void AIS_ViewController::HandleViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
handleMoveTo (theCtx, theView);
|
||||
const bool wasImmediateUpdate = theView->SetImmediateUpdate (false);
|
||||
|
||||
const AIS_WalkDelta aWalk = FetchNavigationKeys (1.0, 1.0);
|
||||
handleXRInput (theCtx, theView, aWalk);
|
||||
if (theView->View()->IsActiveXR())
|
||||
{
|
||||
theView->View()->SetupXRPosedCamera();
|
||||
}
|
||||
handleCameraActions (theCtx, theView, aWalk);
|
||||
theView->View()->SynchronizeXRPosedToBaseCamera(); // handleCameraActions() may modify posed camera position - copy this modifications also to the base camera
|
||||
handleXRPresentations (theCtx, theView);
|
||||
|
||||
handleMoveTo (theCtx, theView);
|
||||
handleViewRedraw (theCtx, theView);
|
||||
theView->View()->UnsetXRPosedCamera();
|
||||
|
||||
theView->SetImmediateUpdate (wasImmediateUpdate);
|
||||
|
||||
// make sure to not process the same events twice
|
||||
myGL.Reset();
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include <Aspect_VKeySet.hxx>
|
||||
#include <Aspect_TouchMap.hxx>
|
||||
#include <Aspect_XRHapticActionData.hxx>
|
||||
#include <Aspect_XRTrackedDeviceRole.hxx>
|
||||
#include <AIS_DragAction.hxx>
|
||||
#include <AIS_MouseGesture.hxx>
|
||||
#include <AIS_NavigationMode.hxx>
|
||||
@ -28,6 +30,7 @@
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Quantity_ColorRGBA.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
|
||||
class AIS_AnimationCamera;
|
||||
@ -35,6 +38,8 @@ class AIS_InteractiveObject;
|
||||
class AIS_InteractiveContext;
|
||||
class AIS_Point;
|
||||
class AIS_RubberBand;
|
||||
class AIS_XRTrackedDevice;
|
||||
class Graphic3d_Camera;
|
||||
class V3d_View;
|
||||
|
||||
//! Auxiliary structure for handling viewer events between GUI and Rendering threads.
|
||||
@ -200,6 +205,18 @@ public: //! @name global parameters
|
||||
//! Reset previous position of MoveTo.
|
||||
void ResetPreviousMoveTo() { myPrevMoveTo = Graphic3d_Vec2i (-1); }
|
||||
|
||||
//! Return TRUE to display auxiliary tracked XR devices (like tracking stations).
|
||||
bool ToDisplayXRAuxDevices() const { return myToDisplayXRAuxDevices; }
|
||||
|
||||
//! Set if auxiliary tracked XR devices should be displayed.
|
||||
void SetDisplayXRAuxDevices (bool theToDisplay) { myToDisplayXRAuxDevices = theToDisplay; }
|
||||
|
||||
//! Return TRUE to display XR hand controllers.
|
||||
bool ToDisplayXRHands() const { return myToDisplayXRHands; }
|
||||
|
||||
//! Set if tracked XR hand controllers should be displayed.
|
||||
void SetDisplayXRHands (bool theToDisplay) { myToDisplayXRHands = theToDisplay; }
|
||||
|
||||
public: //! @name keyboard input
|
||||
|
||||
//! Return keyboard state.
|
||||
@ -548,6 +565,40 @@ public:
|
||||
Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
public:
|
||||
|
||||
//! Perform XR input.
|
||||
//! This method is expected to be called from rendering thread.
|
||||
Standard_EXPORT virtual void handleXRInput (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView,
|
||||
const AIS_WalkDelta& theWalk);
|
||||
|
||||
//! Handle trackpad view turn action.
|
||||
Standard_EXPORT virtual void handleXRTurnPad (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
//! Handle trackpad teleportation action.
|
||||
Standard_EXPORT virtual void handleXRTeleport (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
//! Handle picking on trigger click.
|
||||
Standard_EXPORT virtual void handleXRPicking (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
//! Perform dynamic highlighting for active hand.
|
||||
Standard_EXPORT virtual void handleXRHighlight (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
//! Display auxiliary XR presentations.
|
||||
Standard_EXPORT virtual void handleXRPresentations (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView);
|
||||
|
||||
//! Perform picking with/without dynamic highlighting for XR pose.
|
||||
Standard_EXPORT virtual Standard_Integer handleXRMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
|
||||
const Handle(V3d_View)& theView,
|
||||
const gp_Trsf& thePose,
|
||||
const Standard_Boolean theToHighlight);
|
||||
|
||||
protected:
|
||||
|
||||
//! Flush buffers.
|
||||
@ -629,6 +680,23 @@ protected:
|
||||
Graphic3d_Vec2i myPrevMoveTo; //!< previous position of MoveTo event in 3D viewer
|
||||
Standard_Boolean myHasHlrOnBeforeRotation; //!< flag for restoring Computed mode after rotation
|
||||
|
||||
protected: //! @name XR input variables
|
||||
|
||||
NCollection_Array1<Handle(AIS_XRTrackedDevice)> myXRPrsDevices; //!< array of XR tracked devices presentations
|
||||
Handle(Graphic3d_Camera) myXRCameraTmp; //!< temporary camera
|
||||
Quantity_Color myXRLaserTeleColor; //!< color of teleport laser
|
||||
Quantity_Color myXRLaserPickColor; //!< color of picking laser
|
||||
Aspect_XRTrackedDeviceRole myXRLastTeleportHand;//!< active hand for teleport
|
||||
Aspect_XRTrackedDeviceRole myXRLastPickingHand; //!< active hand for picking objects
|
||||
Aspect_XRHapticActionData myXRTeleportHaptic; //!< vibration on picking teleport destination
|
||||
Aspect_XRHapticActionData myXRPickingHaptic; //!< vibration on dynamic highlighting
|
||||
Aspect_XRHapticActionData myXRSelectHaptic; //!< vibration on selection
|
||||
Standard_Real myXRLastPickDepthLeft; //!< last picking depth for left hand
|
||||
Standard_Real myXRLastPickDepthRight; //!< last picking depth for right hand
|
||||
Standard_Real myXRTurnAngle; //!< discrete turn angle for XR trackpad
|
||||
Standard_Boolean myToDisplayXRAuxDevices; //!< flag to display auxiliary tracked XR devices
|
||||
Standard_Boolean myToDisplayXRHands; //!< flag to display XR hands
|
||||
|
||||
protected: //! @name keyboard input variables
|
||||
|
||||
Aspect_VKeySet myKeys; //!< keyboard state
|
||||
|
202
src/AIS/AIS_XRTrackedDevice.cxx
Normal file
202
src/AIS/AIS_XRTrackedDevice.cxx
Normal file
@ -0,0 +1,202 @@
|
||||
// Copyright (c) 2020 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_XRTrackedDevice.hxx>
|
||||
|
||||
#include <Graphic3d_ArrayOfSegments.hxx>
|
||||
#include <Graphic3d_ArrayOfTriangles.hxx>
|
||||
#include <Graphic3d_Group.hxx>
|
||||
#include <Graphic3d_Texture2Dmanual.hxx>
|
||||
#include <Image_Texture.hxx>
|
||||
#include <Prs3d_LineAspect.hxx>
|
||||
#include <Prs3d_ShadingAspect.hxx>
|
||||
#include <Select3D_SensitivePrimitiveArray.hxx>
|
||||
#include <SelectMgr_EntityOwner.hxx>
|
||||
|
||||
//! Texture holder.
|
||||
class AIS_XRTrackedDevice::XRTexture : public Graphic3d_Texture2Dmanual
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor.
|
||||
XRTexture (const Handle(Image_Texture)& theImageSource,
|
||||
const Graphic3d_TextureUnit theUnit = Graphic3d_TextureUnit_BaseColor)
|
||||
: Graphic3d_Texture2Dmanual (""), myImageSource (theImageSource)
|
||||
{
|
||||
if (!theImageSource->TextureId().IsEmpty())
|
||||
{
|
||||
myTexId = theImageSource->TextureId();
|
||||
}
|
||||
myParams->SetTextureUnit (theUnit);
|
||||
myIsColorMap = theUnit == Graphic3d_TextureUnit_BaseColor
|
||||
|| theUnit == Graphic3d_TextureUnit_Emissive;
|
||||
}
|
||||
|
||||
//! Image reader.
|
||||
virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE { return myImageSource->ReadImage(); }
|
||||
|
||||
protected:
|
||||
Handle(Image_Texture) myImageSource;
|
||||
};
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(AIS_XRTrackedDevice, AIS_InteractiveObject)
|
||||
|
||||
//=======================================================================
|
||||
//function : AIS_XRTrackedDevice
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
AIS_XRTrackedDevice::AIS_XRTrackedDevice (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
|
||||
const Handle(Image_Texture)& theTexture)
|
||||
: myTris (theTris),
|
||||
myLaserColor (Quantity_NOC_BLUE),
|
||||
myLaserLength (0.0f),
|
||||
myUnitFactor (1.0f),
|
||||
myRole (Aspect_XRTrackedDeviceRole_Other),
|
||||
myToShowAxes (false)
|
||||
{
|
||||
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_DEFAULT);
|
||||
myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
|
||||
if (!theTexture.IsNull())
|
||||
{
|
||||
myDrawer->ShadingAspect()->Aspect()->SetTextureMap (new XRTexture (theTexture));
|
||||
myDrawer->ShadingAspect()->Aspect()->SetTextureMapOn (true);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AIS_XRTrackedDevice
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
AIS_XRTrackedDevice::AIS_XRTrackedDevice()
|
||||
: myLaserColor (Quantity_NOC_BLUE),
|
||||
myLaserLength (0.0f),
|
||||
myUnitFactor (1.0f),
|
||||
myRole (Aspect_XRTrackedDeviceRole_Other),
|
||||
myToShowAxes (true)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetLaserColor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_XRTrackedDevice::SetLaserColor (const Quantity_Color& theColor)
|
||||
{
|
||||
if (!myLaserColor.IsEqual (theColor))
|
||||
{
|
||||
myLaserColor = theColor;
|
||||
computeLaserRay();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetLaserLength
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_XRTrackedDevice::SetLaserLength (Standard_ShortReal theLength)
|
||||
{
|
||||
if (myLaserLength != theLength)
|
||||
{
|
||||
myLaserLength = theLength;
|
||||
computeLaserRay();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : computeLaserRay
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_XRTrackedDevice::computeLaserRay()
|
||||
{
|
||||
if (myRayGroup.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!myRayGroup->IsEmpty())
|
||||
{
|
||||
myRayGroup->Clear();
|
||||
}
|
||||
if (myLaserLength <= 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(Graphic3d_ArrayOfPrimitives) aLines = new Graphic3d_ArrayOfSegments (2, 0, Graphic3d_ArrayFlags_VertexColor);
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, 0.0), myLaserColor);
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, -myLaserLength), myLaserColor);
|
||||
myRayGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
|
||||
myRayGroup->AddPrimitiveArray (aLines, false); // do not extend camera frustum by ray
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Compute
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_XRTrackedDevice::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
const Handle(Prs3d_Presentation)& thePrs,
|
||||
const Standard_Integer theMode)
|
||||
{
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
thePrs->SetInfiniteState (myInfiniteState);
|
||||
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
||||
if (!myTris.IsNull())
|
||||
{
|
||||
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
|
||||
aGroup->AddPrimitiveArray (myTris);
|
||||
}
|
||||
|
||||
if (myToShowAxes || myTris.IsNull())
|
||||
{
|
||||
const float aSize = 0.1f * myUnitFactor;
|
||||
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
|
||||
Handle(Graphic3d_ArrayOfPrimitives) aLines = new Graphic3d_ArrayOfSegments (6, 0, Graphic3d_ArrayFlags_VertexColor);
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, 0.0), Quantity_Color (Quantity_NOC_RED));
|
||||
aLines->AddVertex (gp_Pnt (aSize, 0.0, 0.0), Quantity_Color (Quantity_NOC_RED));
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, 0.0), Quantity_Color (Quantity_NOC_GREEN));
|
||||
aLines->AddVertex (gp_Pnt (0.0, aSize, 0.0), Quantity_Color (Quantity_NOC_GREEN));
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, 0.0), Quantity_Color (Quantity_NOC_BLUE));
|
||||
aLines->AddVertex (gp_Pnt (0.0, 0.0, aSize), Quantity_Color (Quantity_NOC_BLUE));
|
||||
aGroup->AddPrimitiveArray (aLines);
|
||||
}
|
||||
|
||||
myRayGroup = thePrs->NewGroup();
|
||||
computeLaserRay();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeSelection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_XRTrackedDevice::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
|
||||
const Standard_Integer theMode)
|
||||
{
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!myTris.IsNull())
|
||||
{
|
||||
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
|
||||
Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
|
||||
aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location(), true);
|
||||
theSel->Add (aSensitive);
|
||||
}
|
||||
}
|
92
src/AIS/AIS_XRTrackedDevice.hxx
Normal file
92
src/AIS/AIS_XRTrackedDevice.hxx
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2020 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_XRTrackedDevice_HeaderFile
|
||||
#define _AIS_XRTrackedDevice_HeaderFile
|
||||
|
||||
#include <AIS_InteractiveObject.hxx>
|
||||
#include <Aspect_XRTrackedDeviceRole.hxx>
|
||||
|
||||
class Graphic3d_ArrayOfTriangles;
|
||||
class Image_Texture;
|
||||
|
||||
//! Auxiliary textured mesh presentation of tracked XR device.
|
||||
class AIS_XRTrackedDevice : public AIS_InteractiveObject
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(AIS_XRTrackedDevice, AIS_InteractiveObject)
|
||||
public:
|
||||
//! Main constructor.
|
||||
Standard_EXPORT AIS_XRTrackedDevice (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
|
||||
const Handle(Image_Texture)& theTexture);
|
||||
|
||||
//! Empty constructor.
|
||||
Standard_EXPORT AIS_XRTrackedDevice();
|
||||
|
||||
//! Return device role.
|
||||
Aspect_XRTrackedDeviceRole Role() const { return myRole; }
|
||||
|
||||
//! Set device role.
|
||||
void SetRole (Aspect_XRTrackedDeviceRole theRole) { myRole = theRole; }
|
||||
|
||||
//! Return laser color.
|
||||
const Quantity_Color& LaserColor() const { return myLaserColor; }
|
||||
|
||||
//! Set laser color.
|
||||
Standard_EXPORT void SetLaserColor (const Quantity_Color& theColor);
|
||||
|
||||
//! Return laser length.
|
||||
Standard_ShortReal LaserLength() const { return myLaserLength; }
|
||||
|
||||
//! Set laser length.
|
||||
Standard_EXPORT void SetLaserLength (Standard_ShortReal theLength);
|
||||
|
||||
//! Return unit scale factor.
|
||||
Standard_ShortReal UnitFactor() const { return myUnitFactor; }
|
||||
|
||||
//! Set unit scale factor.
|
||||
void SetUnitFactor (Standard_ShortReal theFactor) { myUnitFactor = theFactor; }
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns true for 0 mode.
|
||||
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
|
||||
|
||||
//! Compute presentation.
|
||||
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)& theSel,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE;
|
||||
|
||||
//! Compute laser ray presentation.
|
||||
Standard_EXPORT void computeLaserRay();
|
||||
|
||||
private:
|
||||
//! Texture holder.
|
||||
class XRTexture;
|
||||
|
||||
private:
|
||||
|
||||
Handle(Graphic3d_Group) myRayGroup;
|
||||
|
||||
Handle(Graphic3d_ArrayOfTriangles) myTris;
|
||||
Quantity_Color myLaserColor;
|
||||
Standard_ShortReal myLaserLength;
|
||||
Standard_ShortReal myUnitFactor;
|
||||
Aspect_XRTrackedDeviceRole myRole;
|
||||
Standard_Boolean myToShowAxes;
|
||||
};
|
||||
|
||||
#endif // _AIS_XRTrackedDevice_HeaderFile
|
@ -141,3 +141,5 @@ AIS_RadiusDimension.hxx
|
||||
AIS_Relation.hxx
|
||||
AIS_SymmetricRelation.hxx
|
||||
AIS_TangentRelation.hxx
|
||||
AIS_XRTrackedDevice.cxx
|
||||
AIS_XRTrackedDevice.hxx
|
||||
|
26
src/Aspect/Aspect_ColorSpace.hxx
Normal file
26
src/Aspect/Aspect_ColorSpace.hxx
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2020 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 _Aspect_ColorSpace_HeaderFile
|
||||
#define _Aspect_ColorSpace_HeaderFile
|
||||
|
||||
#include <Aspect_GraphicsLibrary.hxx>
|
||||
|
||||
//! Texture color spaces accepted by XR composer.
|
||||
enum Aspect_ColorSpace
|
||||
{
|
||||
Aspect_ColorSpace_sRGB = 0, //!< non-linear sRGB color space
|
||||
Aspect_ColorSpace_Linear = 1, //!< linear RGB color space
|
||||
};
|
||||
|
||||
#endif // _Aspect_ColorSpace_HeaderFile
|
24
src/Aspect/Aspect_Eye.hxx
Normal file
24
src/Aspect/Aspect_Eye.hxx
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2020 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 _Aspect_Eye_HeaderFile
|
||||
#define _Aspect_Eye_HeaderFile
|
||||
|
||||
//! Camera eye index within stereoscopic pair.
|
||||
enum Aspect_Eye
|
||||
{
|
||||
Aspect_Eye_Left,
|
||||
Aspect_Eye_Right
|
||||
};
|
||||
|
||||
#endif // _Aspect_Eye_HeaderFile
|
55
src/Aspect/Aspect_FrustumLRBT.hxx
Normal file
55
src/Aspect/Aspect_FrustumLRBT.hxx
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2020 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 _Aspect_FrustumLRBT_HeaderFile
|
||||
#define _Aspect_FrustumLRBT_HeaderFile
|
||||
|
||||
//! Structure defining frustum boundaries.
|
||||
template<typename Elem_t>
|
||||
struct Aspect_FrustumLRBT
|
||||
{
|
||||
Elem_t Left;
|
||||
Elem_t Right;
|
||||
Elem_t Bottom;
|
||||
Elem_t Top;
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_FrustumLRBT() : Left (0), Right (0), Bottom (0), Top (0) {}
|
||||
|
||||
//! Copy/cast constructor.
|
||||
template<typename Other_t>
|
||||
explicit Aspect_FrustumLRBT (const Aspect_FrustumLRBT<Other_t>& theOther)
|
||||
: Left (static_cast<Elem_t> (theOther.Left)),
|
||||
Right (static_cast<Elem_t> (theOther.Right)),
|
||||
Bottom(static_cast<Elem_t> (theOther.Bottom)),
|
||||
Top (static_cast<Elem_t> (theOther.Top)) {}
|
||||
|
||||
//! Apply multiply factor.
|
||||
void Multiply (Elem_t theScale)
|
||||
{
|
||||
Left *= theScale;
|
||||
Right *= theScale;
|
||||
Bottom *= theScale;
|
||||
Top *= theScale;
|
||||
}
|
||||
|
||||
//! Return multiplied frustum.
|
||||
Aspect_FrustumLRBT<Elem_t> Multiplied (Elem_t theScale)
|
||||
{
|
||||
Aspect_FrustumLRBT<Elem_t> aCopy (*this);
|
||||
aCopy.Multiply (theScale);
|
||||
return aCopy;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _Aspect_FrustumLRBT_HeaderFile
|
24
src/Aspect/Aspect_GraphicsLibrary.hxx
Normal file
24
src/Aspect/Aspect_GraphicsLibrary.hxx
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2020 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 _Aspect_GraphicsLibrary_HeaderFile
|
||||
#define _Aspect_GraphicsLibrary_HeaderFile
|
||||
|
||||
//! Graphics API enumeration.
|
||||
enum Aspect_GraphicsLibrary
|
||||
{
|
||||
Aspect_GraphicsLibrary_OpenGL,
|
||||
Aspect_GraphicsLibrary_OpenGLES,
|
||||
};
|
||||
|
||||
#endif // _Aspect_GraphicsLibrary_HeaderFile
|
1151
src/Aspect/Aspect_OpenVRSession.cxx
Normal file
1151
src/Aspect/Aspect_OpenVRSession.cxx
Normal file
File diff suppressed because it is too large
Load Diff
149
src/Aspect/Aspect_OpenVRSession.hxx
Normal file
149
src/Aspect/Aspect_OpenVRSession.hxx
Normal file
@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2020 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 _Aspect_OpenVRSession_HeaderFile
|
||||
#define _Aspect_OpenVRSession_HeaderFile
|
||||
|
||||
#include <Aspect_XRSession.hxx>
|
||||
|
||||
//! OpenVR wrapper implementing Aspect_XRSession interface.
|
||||
class Aspect_OpenVRSession : public Aspect_XRSession
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Aspect_OpenVRSession, Aspect_XRSession)
|
||||
public:
|
||||
|
||||
//! Return TRUE if an HMD may be presented on the system (e.g. to show VR checkbox in application GUI).
|
||||
//! This is fast check, and even if it returns TRUE, opening session may fail.
|
||||
Standard_EXPORT static bool IsHmdPresent();
|
||||
|
||||
public:
|
||||
|
||||
//! Empty constructor.
|
||||
Standard_EXPORT Aspect_OpenVRSession();
|
||||
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~Aspect_OpenVRSession();
|
||||
|
||||
//! Return TRUE if session is opened.
|
||||
Standard_EXPORT virtual bool IsOpen() const Standard_OVERRIDE;
|
||||
|
||||
//! Initialize session.
|
||||
Standard_EXPORT virtual bool Open() Standard_OVERRIDE;
|
||||
|
||||
//! Release session.
|
||||
Standard_EXPORT virtual void Close() Standard_OVERRIDE;
|
||||
|
||||
//! Fetch actual poses of tracked devices.
|
||||
Standard_EXPORT virtual bool WaitPoses() Standard_OVERRIDE;
|
||||
|
||||
//! Return recommended viewport Width x Height for rendering into VR.
|
||||
virtual NCollection_Vec2<int> RecommendedViewport() const Standard_OVERRIDE { return myRendSize; }
|
||||
|
||||
//! Return transformation from eye to head.
|
||||
//! vr::GetEyeToHeadTransform() wrapper.
|
||||
Standard_EXPORT virtual NCollection_Mat4<double> EyeToHeadTransform (Aspect_Eye theEye) const Standard_OVERRIDE;
|
||||
|
||||
//! Return projection matrix.
|
||||
Standard_EXPORT virtual NCollection_Mat4<double> ProjectionMatrix (Aspect_Eye theEye,
|
||||
double theZNear,
|
||||
double theZFar) const Standard_OVERRIDE;
|
||||
|
||||
//! Return TRUE.
|
||||
virtual bool HasProjectionFrustums() const Standard_OVERRIDE { return true; }
|
||||
|
||||
//! Receive XR events.
|
||||
Standard_EXPORT virtual void ProcessEvents() Standard_OVERRIDE;
|
||||
|
||||
//! Submit texture eye to XR Composer.
|
||||
//! @param theTexture [in] texture handle
|
||||
//! @param theGraphicsLib [in] graphics library in which texture handle is defined
|
||||
//! @param theColorSpace [in] texture color space;
|
||||
//! sRGB means no color conversion by composer;
|
||||
//! Linear means to sRGB color conversion by composer
|
||||
//! @param theEye [in] eye to display
|
||||
//! @return FALSE on error
|
||||
Standard_EXPORT virtual bool SubmitEye (void* theTexture,
|
||||
Aspect_GraphicsLibrary theGraphicsLib,
|
||||
Aspect_ColorSpace theColorSpace,
|
||||
Aspect_Eye theEye) Standard_OVERRIDE;
|
||||
|
||||
//! Query information.
|
||||
Standard_EXPORT virtual TCollection_AsciiString GetString (InfoString theInfo) const Standard_OVERRIDE;
|
||||
|
||||
//! Return index of tracked device of known role.
|
||||
Standard_EXPORT virtual Standard_Integer NamedTrackedDevice (Aspect_XRTrackedDeviceRole theDevice) const Standard_OVERRIDE;
|
||||
|
||||
//! Fetch data for digital input action (like button).
|
||||
Standard_EXPORT virtual Aspect_XRDigitalActionData GetDigitalActionData (const Handle(Aspect_XRAction)& theAction) const Standard_OVERRIDE;
|
||||
|
||||
//! Fetch data for analog input action (like axis).
|
||||
Standard_EXPORT virtual Aspect_XRAnalogActionData GetAnalogActionData (const Handle(Aspect_XRAction)& theAction) const Standard_OVERRIDE;
|
||||
|
||||
//! Fetch data for pose input action (like fingertip position).
|
||||
Standard_EXPORT virtual Aspect_XRPoseActionData GetPoseActionDataForNextFrame (const Handle(Aspect_XRAction)& theAction) const Standard_OVERRIDE;
|
||||
|
||||
//! Set tracking origin.
|
||||
Standard_EXPORT virtual void SetTrackingOrigin (TrackingUniverseOrigin theOrigin) Standard_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
//! Find location of default actions manifest file (based on CSF_OCCTResourcePath or CASROOT variables).
|
||||
Standard_EXPORT TCollection_AsciiString defaultActionsManifest();
|
||||
|
||||
//! Release OpenVR device.
|
||||
Standard_EXPORT void closeVR();
|
||||
|
||||
//! Update projection frustums.
|
||||
Standard_EXPORT virtual void updateProjectionFrustums();
|
||||
|
||||
//! Init VR input.
|
||||
Standard_EXPORT virtual bool initInput();
|
||||
|
||||
//! Handle tracked device activation.
|
||||
Standard_EXPORT virtual void onTrackedDeviceActivated (Standard_Integer theDeviceIndex);
|
||||
|
||||
//! Handle tracked device deactivation.
|
||||
Standard_EXPORT virtual void onTrackedDeviceDeactivated (Standard_Integer theDeviceIndex);
|
||||
|
||||
//! Handle tracked device update.
|
||||
Standard_EXPORT virtual void onTrackedDeviceUpdated (Standard_Integer theDeviceIndex);
|
||||
|
||||
//! Trigger vibration.
|
||||
Standard_EXPORT virtual void triggerHapticVibrationAction (const Handle(Aspect_XRAction)& theAction,
|
||||
const Aspect_XRHapticActionData& theParams) Standard_OVERRIDE;
|
||||
|
||||
//! Return model for displaying device.
|
||||
Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) loadRenderModel (Standard_Integer theDevice,
|
||||
Standard_Boolean theToApplyUnitFactor,
|
||||
Handle(Image_Texture)& theTexture) Standard_OVERRIDE;
|
||||
|
||||
protected:
|
||||
|
||||
//! Access vr::IVRSystem* - OpenVR session object.
|
||||
Standard_EXPORT void* getVRSystem() const;
|
||||
|
||||
private:
|
||||
|
||||
//! Internal fields
|
||||
struct VRContext;
|
||||
class VRImagePixmap;
|
||||
class VRTextureSource;
|
||||
|
||||
protected:
|
||||
|
||||
VRContext* myContext;
|
||||
TCollection_AsciiString myActionsManifest;
|
||||
|
||||
};
|
||||
|
||||
#endif // _Aspect_OpenVRSession_HeaderFile
|
36
src/Aspect/Aspect_TrackedDevicePose.hxx
Normal file
36
src/Aspect/Aspect_TrackedDevicePose.hxx
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2020 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 _Aspect_TrackedDevicePose_HeaderFile
|
||||
#define _Aspect_TrackedDevicePose_HeaderFile
|
||||
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
|
||||
//! Describes a single pose for a tracked object (for XR).
|
||||
struct Aspect_TrackedDevicePose
|
||||
{
|
||||
gp_Trsf Orientation; //!< device to absolute transformation
|
||||
gp_Vec Velocity; //!< velocity in tracker space in m/s
|
||||
gp_Vec AngularVelocity; //!< angular velocity in radians/s
|
||||
bool IsValidPose; //!< indicates valid pose
|
||||
bool IsConnectedDevice; //!< indicates connected state
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_TrackedDevicePose() : IsValidPose (false), IsConnectedDevice (false) {}
|
||||
};
|
||||
|
||||
//! Array of tracked poses.
|
||||
typedef NCollection_Array1<Aspect_TrackedDevicePose> Aspect_TrackedDevicePoseArray;
|
||||
|
||||
#endif // _Aspect_TrackedDevicePose_HeaderFile
|
58
src/Aspect/Aspect_XRAction.hxx
Normal file
58
src/Aspect/Aspect_XRAction.hxx
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRAction_HeaderFile
|
||||
#define _Aspect_XRAction_HeaderFile
|
||||
|
||||
#include <Aspect_XRActionType.hxx>
|
||||
#include <NCollection_IndexedDataMap.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
//! XR action definition.
|
||||
class Aspect_XRAction : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Aspect_XRAction, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Return action id.
|
||||
const TCollection_AsciiString& Id() const { return myId; }
|
||||
|
||||
//! Return action type.
|
||||
Aspect_XRActionType Type() const { return myType; }
|
||||
|
||||
//! Return TRUE if action is defined.
|
||||
bool IsValid() const { return myRawHandle != 0; }
|
||||
|
||||
//! Return action handle.
|
||||
uint64_t RawHandle() const { return myRawHandle; }
|
||||
|
||||
//! Set action handle.
|
||||
void SetRawHandle (uint64_t theHande) { myRawHandle = theHande; }
|
||||
|
||||
//! Main constructor.
|
||||
Aspect_XRAction (const TCollection_AsciiString& theId,
|
||||
const Aspect_XRActionType theType)
|
||||
: myId (theId), myRawHandle (0), myType (theType) {}
|
||||
|
||||
protected:
|
||||
TCollection_AsciiString myId; //!< action id
|
||||
uint64_t myRawHandle; //!< action handle
|
||||
Aspect_XRActionType myType; //!< action type
|
||||
};
|
||||
|
||||
//! Map of actions with action Id as a key.
|
||||
typedef NCollection_IndexedDataMap<TCollection_AsciiString, Handle(Aspect_XRAction), TCollection_AsciiString> Aspect_XRActionMap;
|
||||
|
||||
#endif // _Aspect_XRAction_HeaderFile
|
55
src/Aspect/Aspect_XRActionSet.hxx
Normal file
55
src/Aspect/Aspect_XRActionSet.hxx
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRActionSet_HeaderFile
|
||||
#define _Aspect_XRActionSet_HeaderFile
|
||||
|
||||
#include <Aspect_XRAction.hxx>
|
||||
|
||||
//! XR action set.
|
||||
class Aspect_XRActionSet : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Aspect_XRActionSet, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Return action id.
|
||||
const TCollection_AsciiString& Id() const { return myId; }
|
||||
|
||||
//! Return action handle.
|
||||
uint64_t RawHandle() const { return myRawHandle; }
|
||||
|
||||
//! Set action handle.
|
||||
void SetRawHandle (uint64_t theHande) { myRawHandle = theHande; }
|
||||
|
||||
//! Add action.
|
||||
void AddAction (const Handle(Aspect_XRAction)& theAction)
|
||||
{
|
||||
myActions.Add (theAction->Id(), theAction);
|
||||
}
|
||||
|
||||
//! Return map of actions.
|
||||
const Aspect_XRActionMap& Actions() const { return myActions; }
|
||||
|
||||
//! Main constructor.
|
||||
Aspect_XRActionSet (const TCollection_AsciiString& theId)
|
||||
: myId (theId), myRawHandle (0) {}
|
||||
|
||||
protected:
|
||||
TCollection_AsciiString myId; //!< action set id
|
||||
uint64_t myRawHandle; //!< action set handle
|
||||
Aspect_XRActionMap myActions; //!< map of actions
|
||||
};
|
||||
|
||||
typedef NCollection_IndexedDataMap<TCollection_AsciiString, Handle(Aspect_XRActionSet), TCollection_AsciiString> Aspect_XRActionSetMap;
|
||||
|
||||
#endif // _Aspect_XRActionSet_HeaderFile
|
27
src/Aspect/Aspect_XRActionType.hxx
Normal file
27
src/Aspect/Aspect_XRActionType.hxx
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRActionType_HeaderFile
|
||||
#define _Aspect_XRActionType_HeaderFile
|
||||
|
||||
//! XR action type.
|
||||
enum Aspect_XRActionType
|
||||
{
|
||||
Aspect_XRActionType_InputDigital, //!< boolean input (like button)
|
||||
Aspect_XRActionType_InputAnalog, //!< analog input (1/2/3 axes)
|
||||
Aspect_XRActionType_InputPose, //!< positional input
|
||||
Aspect_XRActionType_InputSkeletal, //!< skeletal input
|
||||
Aspect_XRActionType_OutputHaptic //!< haptic output (vibration)
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRActionType_HeaderFile
|
35
src/Aspect/Aspect_XRAnalogActionData.hxx
Normal file
35
src/Aspect/Aspect_XRAnalogActionData.hxx
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRAnalogActionData_HeaderFile
|
||||
#define _Aspect_XRAnalogActionData_HeaderFile
|
||||
|
||||
#include <NCollection_Vec3.hxx>
|
||||
|
||||
//! Analog input XR action data.
|
||||
struct Aspect_XRAnalogActionData
|
||||
{
|
||||
uint64_t ActiveOrigin; //!< The origin that caused this action's current state
|
||||
float UpdateTime; //!< Time relative to now when this event happened. Will be negative to indicate a past time
|
||||
NCollection_Vec3<float> VecXYZ; //!< the current state of this action
|
||||
NCollection_Vec3<float> DeltaXYZ; //!< deltas since the previous update
|
||||
bool IsActive; //!< whether or not this action is currently available to be bound in the active action set
|
||||
|
||||
//! Return TRUE if delta is non-zero.
|
||||
bool IsChanged() { return !DeltaXYZ.IsEqual (NCollection_Vec3<float> (0.0f, 0.0f, 0.0f)); }
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_XRAnalogActionData() : ActiveOrigin (0), UpdateTime (0.0f), IsActive (false) {}
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRAnalogActionData_HeaderFile
|
32
src/Aspect/Aspect_XRDigitalActionData.hxx
Normal file
32
src/Aspect/Aspect_XRDigitalActionData.hxx
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRDigitalActionData_HeaderFile
|
||||
#define _Aspect_XRDigitalActionData_HeaderFile
|
||||
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
//! Digital input XR action data.
|
||||
struct Aspect_XRDigitalActionData
|
||||
{
|
||||
uint64_t ActiveOrigin; //!< The origin that caused this action's current state
|
||||
float UpdateTime; //!< Time relative to now when this event happened. Will be negative to indicate a past time
|
||||
bool IsActive; //!< whether or not this action is currently available to be bound in the active action set
|
||||
bool IsPressed; //!< Aspect_InputActionType_Digital state - The current state of this action; will be true if currently pressed
|
||||
bool IsChanged; //!< Aspect_InputActionType_Digital state - this is true if the state has changed since the last frame
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_XRDigitalActionData() : ActiveOrigin (0), UpdateTime (0.0f), IsActive (false), IsPressed (false), IsChanged (false) {}
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRDigitalActionData_HeaderFile
|
40
src/Aspect/Aspect_XRGenericAction.hxx
Normal file
40
src/Aspect/Aspect_XRGenericAction.hxx
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRGenericAction_HeaderFile
|
||||
#define _Aspect_XRGenericAction_HeaderFile
|
||||
|
||||
//! Generic XR action.
|
||||
enum Aspect_XRGenericAction
|
||||
{
|
||||
Aspect_XRGenericAction_IsHeadsetOn, //!< headset is on/off head
|
||||
Aspect_XRGenericAction_InputAppMenu, //!< application menu button pressed/released
|
||||
Aspect_XRGenericAction_InputSysMenu, //!< system menu button pressed/released
|
||||
Aspect_XRGenericAction_InputTriggerPull, //!< trigger squeezing [0..1], 1 to click
|
||||
Aspect_XRGenericAction_InputTriggerClick, //!< trigger clicked/released
|
||||
Aspect_XRGenericAction_InputGripClick, //!< grip state on/off
|
||||
Aspect_XRGenericAction_InputTrackPadPosition, //!< trackpad 2D position [-1,+1] with X and Y axes
|
||||
Aspect_XRGenericAction_InputTrackPadTouch, //!< trackpad touched/untouched
|
||||
Aspect_XRGenericAction_InputTrackPadClick, //!< trackpad clicked/released
|
||||
Aspect_XRGenericAction_InputThumbstickPosition, //!< thumbstick 2D position [-1,+1] with X and Y axes
|
||||
Aspect_XRGenericAction_InputThumbstickTouch, //!< thumbstick touched/untouched
|
||||
Aspect_XRGenericAction_InputThumbstickClick, //!< thumbstick clicked/released
|
||||
Aspect_XRGenericAction_InputPoseBase, //!< base position of hand
|
||||
Aspect_XRGenericAction_InputPoseFront, //!< front position of hand
|
||||
Aspect_XRGenericAction_InputPoseHandGrip, //!< position of main handgrip
|
||||
Aspect_XRGenericAction_InputPoseFingerTip, //!< position of main fingertip
|
||||
Aspect_XRGenericAction_OutputHaptic //!< haptic output (vibration)
|
||||
};
|
||||
enum { Aspect_XRGenericAction_NB = Aspect_XRGenericAction_OutputHaptic + 1 };
|
||||
|
||||
#endif // _Aspect_XRGenericAction_HeaderFile
|
38
src/Aspect/Aspect_XRHapticActionData.hxx
Normal file
38
src/Aspect/Aspect_XRHapticActionData.hxx
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRHapticActionData_HeaderFile
|
||||
#define _Aspect_XRHapticActionData_HeaderFile
|
||||
|
||||
//! Haptic output XR action data.
|
||||
struct Aspect_XRHapticActionData
|
||||
{
|
||||
float Delay; //!< delay in seconds before start
|
||||
float Duration; //!< duration in seconds
|
||||
float Frequency; //!< vibration frequency
|
||||
float Amplitude; //!< vibration amplitude
|
||||
|
||||
//! Return TRUE if data is not empty.
|
||||
bool IsValid() const
|
||||
{
|
||||
return Duration > 0.0f
|
||||
&& Amplitude > 0.0f
|
||||
&& Frequency > 0.0f
|
||||
&& Delay >= 0.0f;
|
||||
}
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_XRHapticActionData() : Delay (0.0f), Duration (0.0f), Frequency (0.0f), Amplitude (0.0f) {}
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRHapticActionData_HeaderFile
|
31
src/Aspect/Aspect_XRPoseActionData.hxx
Normal file
31
src/Aspect/Aspect_XRPoseActionData.hxx
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRPoseActionData_HeaderFile
|
||||
#define _Aspect_XRPoseActionData_HeaderFile
|
||||
|
||||
#include <Aspect_TrackedDevicePose.hxx>
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
//! Pose input XR action data.
|
||||
struct Aspect_XRPoseActionData
|
||||
{
|
||||
Aspect_TrackedDevicePose Pose; //!< pose state
|
||||
uint64_t ActiveOrigin; //!< The origin that caused this action's current state
|
||||
bool IsActive; //!< whether or not this action is currently available to be bound in the active action set
|
||||
|
||||
//! Empty constructor.
|
||||
Aspect_XRPoseActionData() : ActiveOrigin (0), IsActive (false) {}
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRPoseActionData_HeaderFile
|
60
src/Aspect/Aspect_XRSession.cxx
Normal file
60
src/Aspect/Aspect_XRSession.cxx
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2020 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 <Aspect_XRSession.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Aspect_XRSession, Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Aspect_XRAction, Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Aspect_XRActionSet, Standard_Transient)
|
||||
|
||||
// =======================================================================
|
||||
// function : Aspect_XRSession
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Aspect_XRSession::Aspect_XRSession()
|
||||
: myTrackOrigin (TrackingUniverseOrigin_Standing),
|
||||
myTrackedPoses (0, 0),
|
||||
myUnitFactor (1.0),
|
||||
myAspect (1.0),
|
||||
myFieldOfView (90.0),
|
||||
myIod (0.0),
|
||||
myDispFreq (0.0f)
|
||||
{
|
||||
for (Standard_Integer aRoleIter = 0; aRoleIter < Aspect_XRTrackedDeviceRole_NB; ++aRoleIter)
|
||||
{
|
||||
myRoleActions[aRoleIter].Resize (0, Aspect_XRGenericAction_NB - 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AbortHapticVibrationAction
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Aspect_XRSession::AbortHapticVibrationAction (const Handle(Aspect_XRAction)& theAction)
|
||||
{
|
||||
triggerHapticVibrationAction (theAction, Aspect_XRHapticActionData());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : TriggerHapticVibrationAction
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Aspect_XRSession::TriggerHapticVibrationAction (const Handle(Aspect_XRAction)& theAction,
|
||||
const Aspect_XRHapticActionData& theParams)
|
||||
{
|
||||
if (!theParams.IsValid())
|
||||
{
|
||||
throw Standard_ProgramError("Aspect_OpenVRSession::TriggerHapticVibrationAction() called for wrong action");
|
||||
}
|
||||
triggerHapticVibrationAction (theAction, theParams);
|
||||
}
|
262
src/Aspect/Aspect_XRSession.hxx
Normal file
262
src/Aspect/Aspect_XRSession.hxx
Normal file
@ -0,0 +1,262 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRSession_HeaderFile
|
||||
#define _Aspect_XRSession_HeaderFile
|
||||
|
||||
#include <Aspect_ColorSpace.hxx>
|
||||
#include <Aspect_Eye.hxx>
|
||||
#include <Aspect_FrustumLRBT.hxx>
|
||||
#include <Aspect_GraphicsLibrary.hxx>
|
||||
#include <Aspect_XRActionSet.hxx>
|
||||
#include <Aspect_XRAnalogActionData.hxx>
|
||||
#include <Aspect_XRDigitalActionData.hxx>
|
||||
#include <Aspect_XRGenericAction.hxx>
|
||||
#include <Aspect_XRHapticActionData.hxx>
|
||||
#include <Aspect_XRPoseActionData.hxx>
|
||||
#include <Aspect_XRTrackedDeviceRole.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
|
||||
class Graphic3d_ArrayOfTriangles;
|
||||
class Image_Texture;
|
||||
|
||||
//! Extended Reality (XR) Session interface.
|
||||
class Aspect_XRSession : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Aspect_XRSession, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Identifies which style of tracking origin the application wants to use for the poses it is requesting.
|
||||
enum TrackingUniverseOrigin
|
||||
{
|
||||
TrackingUniverseOrigin_Seated, //! poses are provided relative to the seated zero pose
|
||||
TrackingUniverseOrigin_Standing, //! poses are provided relative to the safe bounds configured by the user
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//! Return TRUE if session is opened.
|
||||
virtual bool IsOpen() const = 0;
|
||||
|
||||
//! Initialize session.
|
||||
virtual bool Open() = 0;
|
||||
|
||||
//! Release session.
|
||||
virtual void Close() = 0;
|
||||
|
||||
//! Fetch actual poses of tracked devices.
|
||||
virtual bool WaitPoses() = 0;
|
||||
|
||||
//! Return recommended viewport Width x Height for rendering into VR.
|
||||
virtual NCollection_Vec2<int> RecommendedViewport() const = 0;
|
||||
|
||||
//! Return transformation from eye to head.
|
||||
virtual NCollection_Mat4<double> EyeToHeadTransform (Aspect_Eye theEye) const = 0;
|
||||
|
||||
//! Return transformation from head to eye.
|
||||
NCollection_Mat4<double> HeadToEyeTransform (Aspect_Eye theEye) const
|
||||
{
|
||||
NCollection_Mat4<double> aMat;
|
||||
EyeToHeadTransform (theEye).Inverted (aMat);
|
||||
return aMat;
|
||||
}
|
||||
|
||||
//! Return projection matrix.
|
||||
virtual NCollection_Mat4<double> ProjectionMatrix (Aspect_Eye theEye,
|
||||
double theZNear,
|
||||
double theZFar) const = 0;
|
||||
|
||||
//! Return FALSE if projection frustums are unsupported and general 4x4 projection matrix should be fetched instead
|
||||
virtual bool HasProjectionFrustums() const = 0;
|
||||
|
||||
//! Receive XR events.
|
||||
virtual void ProcessEvents() = 0;
|
||||
|
||||
//! Submit texture eye to XR Composer.
|
||||
//! @param theTexture [in] texture handle
|
||||
//! @param theGraphicsLib [in] graphics library in which texture handle is defined
|
||||
//! @param theColorSpace [in] texture color space;
|
||||
//! sRGB means no color conversion by composer;
|
||||
//! Linear means to sRGB color conversion by composer
|
||||
//! @param theEye [in] eye to display
|
||||
//! @return FALSE on error
|
||||
virtual bool SubmitEye (void* theTexture,
|
||||
Aspect_GraphicsLibrary theGraphicsLib,
|
||||
Aspect_ColorSpace theColorSpace,
|
||||
Aspect_Eye theEye) = 0;
|
||||
|
||||
//! Return unit scale factor defined as scale factor for m (meters); 1.0 by default.
|
||||
Standard_Real UnitFactor() const { return myUnitFactor; }
|
||||
|
||||
//! Set unit scale factor.
|
||||
void SetUnitFactor (Standard_Real theFactor) { myUnitFactor = theFactor; }
|
||||
|
||||
//! Return aspect ratio.
|
||||
Standard_Real Aspect() const { return myAspect; }
|
||||
|
||||
//! Return field of view.
|
||||
Standard_Real FieldOfView() const { return myFieldOfView; }
|
||||
|
||||
//! Return Intra-ocular Distance (IOD); also known as Interpupillary Distance (IPD).
|
||||
//! Defined in meters by default (@sa UnitFactor()).
|
||||
Standard_Real IOD() const { return myIod; }
|
||||
|
||||
//! Return display frequency or 0 if unknown.
|
||||
Standard_ShortReal DisplayFrequency() const { return myDispFreq; }
|
||||
|
||||
//! Return projection frustum.
|
||||
//! @sa HasProjectionFrustums().
|
||||
const Aspect_FrustumLRBT<double>& ProjectionFrustum (Aspect_Eye theEye) const
|
||||
{
|
||||
return theEye == Aspect_Eye_Right ? myFrustumR : myFrustumL;
|
||||
}
|
||||
|
||||
//! Return head orientation in right-handed system:
|
||||
//! +y is up
|
||||
//! +x is to the right
|
||||
//! -z is forward
|
||||
//! Distance unit is meters by default (@sa UnitFactor()).
|
||||
const gp_Trsf& HeadPose() const { return myHeadPose; }
|
||||
|
||||
//! Return left hand orientation.
|
||||
gp_Trsf LeftHandPose() const
|
||||
{
|
||||
const Standard_Integer aDevice = NamedTrackedDevice (Aspect_XRTrackedDeviceRole_LeftHand);
|
||||
return aDevice != -1 ? myTrackedPoses[aDevice].Orientation : gp_Trsf();
|
||||
}
|
||||
|
||||
//! Return right hand orientation.
|
||||
gp_Trsf RightHandPose() const
|
||||
{
|
||||
const Standard_Integer aDevice = NamedTrackedDevice (Aspect_XRTrackedDeviceRole_RightHand);
|
||||
return aDevice != -1 ? myTrackedPoses[aDevice].Orientation : gp_Trsf();
|
||||
}
|
||||
|
||||
//! Return number of tracked poses array.
|
||||
const Aspect_TrackedDevicePoseArray& TrackedPoses() const { return myTrackedPoses; }
|
||||
|
||||
//! Return TRUE if device orientation is defined.
|
||||
bool HasTrackedPose (Standard_Integer theDevice) const { return myTrackedPoses[theDevice].IsValidPose; }
|
||||
|
||||
//! Return index of tracked device of known role, or -1 if undefined.
|
||||
virtual Standard_Integer NamedTrackedDevice (Aspect_XRTrackedDeviceRole theDevice) const = 0;
|
||||
|
||||
//! Load model for displaying device.
|
||||
//! @param theDevice [in] device index
|
||||
//! @param theTexture [out] texture source
|
||||
//! @return model triangulation or NULL if not found
|
||||
Handle(Graphic3d_ArrayOfTriangles) LoadRenderModel (Standard_Integer theDevice,
|
||||
Handle(Image_Texture)& theTexture)
|
||||
{
|
||||
return loadRenderModel (theDevice, true, theTexture);
|
||||
}
|
||||
|
||||
//! Load model for displaying device.
|
||||
//! @param theDevice [in] device index
|
||||
//! @param theToApplyUnitFactor [in] flag to apply unit scale factor
|
||||
//! @param theTexture [out] texture source
|
||||
//! @return model triangulation or NULL if not found
|
||||
Handle(Graphic3d_ArrayOfTriangles) LoadRenderModel (Standard_Integer theDevice,
|
||||
Standard_Boolean theToApplyUnitFactor,
|
||||
Handle(Image_Texture)& theTexture)
|
||||
{
|
||||
return loadRenderModel (theDevice, theToApplyUnitFactor, theTexture);
|
||||
}
|
||||
|
||||
//! Fetch data for digital input action (like button).
|
||||
//! @param theAction [in] action of Aspect_XRActionType_InputDigital type
|
||||
virtual Aspect_XRDigitalActionData GetDigitalActionData (const Handle(Aspect_XRAction)& theAction) const = 0;
|
||||
|
||||
//! Fetch data for digital input action (like axis).
|
||||
//! @param theAction [in] action of Aspect_XRActionType_InputAnalog type
|
||||
virtual Aspect_XRAnalogActionData GetAnalogActionData (const Handle(Aspect_XRAction)& theAction) const = 0;
|
||||
|
||||
//! Fetch data for pose input action (like fingertip position).
|
||||
//! The returned values will match the values returned by the last call to WaitPoses().
|
||||
//! @param theAction [in] action of Aspect_XRActionType_InputPose type
|
||||
virtual Aspect_XRPoseActionData GetPoseActionDataForNextFrame (const Handle(Aspect_XRAction)& theAction) const = 0;
|
||||
|
||||
//! Trigger vibration.
|
||||
Standard_EXPORT void TriggerHapticVibrationAction (const Handle(Aspect_XRAction)& theAction,
|
||||
const Aspect_XRHapticActionData& theParams);
|
||||
|
||||
//! Abort vibration.
|
||||
Standard_EXPORT void AbortHapticVibrationAction (const Handle(Aspect_XRAction)& theAction);
|
||||
|
||||
//! Return tracking origin.
|
||||
TrackingUniverseOrigin TrackingOrigin() const { return myTrackOrigin; }
|
||||
|
||||
//! Set tracking origin.
|
||||
virtual void SetTrackingOrigin (TrackingUniverseOrigin theOrigin) { myTrackOrigin = theOrigin; }
|
||||
|
||||
//! Return generic action for specific hand or NULL if undefined.
|
||||
const Handle(Aspect_XRAction)& GenericAction (Aspect_XRTrackedDeviceRole theDevice,
|
||||
Aspect_XRGenericAction theAction) const
|
||||
{
|
||||
const NCollection_Array1<Handle(Aspect_XRAction)>& anActions = myRoleActions[theDevice];
|
||||
return anActions[theAction];
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Info string enumeration.
|
||||
enum InfoString
|
||||
{
|
||||
InfoString_Vendor,
|
||||
InfoString_Device,
|
||||
InfoString_Tracker,
|
||||
InfoString_SerialNumber,
|
||||
};
|
||||
|
||||
//! Query information.
|
||||
virtual TCollection_AsciiString GetString (InfoString theInfo) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
//! Empty constructor.
|
||||
Standard_EXPORT Aspect_XRSession();
|
||||
|
||||
//! Load model for displaying device.
|
||||
//! @param theDevice [in] device index
|
||||
//! @param theToApplyUnitFactor [in] flag to apply unit scale factor
|
||||
//! @param theTexture [out] texture source
|
||||
//! @return model triangulation or NULL if not found
|
||||
virtual Handle(Graphic3d_ArrayOfTriangles) loadRenderModel (Standard_Integer theDevice,
|
||||
Standard_Boolean theToApplyUnitFactor,
|
||||
Handle(Image_Texture)& theTexture) = 0;
|
||||
|
||||
//! Trigger vibration.
|
||||
virtual void triggerHapticVibrationAction (const Handle(Aspect_XRAction)& theAction,
|
||||
const Aspect_XRHapticActionData& theParams) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
NCollection_Array1<Handle(Aspect_XRAction)>
|
||||
myRoleActions[Aspect_XRTrackedDeviceRole_NB]; //!< generic actions
|
||||
Aspect_XRActionSetMap myActionSets; //!< actions sets
|
||||
TrackingUniverseOrigin myTrackOrigin; //!< tracking origin
|
||||
Aspect_TrackedDevicePoseArray myTrackedPoses; //!< array of tracked poses
|
||||
gp_Trsf myHeadPose; //!< head orientation
|
||||
NCollection_Vec2<int> myRendSize; //!< viewport Width x Height for rendering into VR
|
||||
Aspect_FrustumLRBT<double> myFrustumL; //!< left eye projection frustum
|
||||
Aspect_FrustumLRBT<double> myFrustumR; //!< right eye projection frustum
|
||||
Standard_Real myUnitFactor; //!< unit scale factor defined as scale factor for m (meters)
|
||||
Standard_Real myAspect; //!< aspect ratio
|
||||
Standard_Real myFieldOfView; //!< field of view
|
||||
Standard_Real myIod; //!< intra-ocular distance in meters
|
||||
Standard_ShortReal myDispFreq; //!< display frequency
|
||||
|
||||
};
|
||||
|
||||
#endif // _Aspect_XRSession_HeaderFile
|
27
src/Aspect/Aspect_XRTrackedDeviceRole.hxx
Normal file
27
src/Aspect/Aspect_XRTrackedDeviceRole.hxx
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2020 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 _Aspect_XRTrackedDeviceRole_HeaderFile
|
||||
#define _Aspect_XRTrackedDeviceRole_HeaderFile
|
||||
|
||||
//! Predefined tracked devices.
|
||||
enum Aspect_XRTrackedDeviceRole
|
||||
{
|
||||
Aspect_XRTrackedDeviceRole_Head, //!< head
|
||||
Aspect_XRTrackedDeviceRole_LeftHand, //!< left hand
|
||||
Aspect_XRTrackedDeviceRole_RightHand, //!< right hand
|
||||
Aspect_XRTrackedDeviceRole_Other, //!< other devices
|
||||
};
|
||||
enum { Aspect_XRTrackedDeviceRole_NB = Aspect_XRTrackedDeviceRole_Other + 1 };
|
||||
|
||||
#endif // _Aspect_XRTrackedDeviceRole_HeaderFile
|
@ -5,26 +5,32 @@ Aspect_Background.cxx
|
||||
Aspect_Background.hxx
|
||||
Aspect_CircularGrid.cxx
|
||||
Aspect_CircularGrid.hxx
|
||||
Aspect_ColorSpace.hxx
|
||||
Aspect_Convert.hxx
|
||||
Aspect_Display.hxx
|
||||
Aspect_DisplayConnection.cxx
|
||||
Aspect_DisplayConnection.hxx
|
||||
Aspect_DisplayConnectionDefinitionError.hxx
|
||||
Aspect_Drawable.hxx
|
||||
Aspect_Eye.hxx
|
||||
Aspect_FBConfig.hxx
|
||||
Aspect_FillMethod.hxx
|
||||
Aspect_FrustumLRBT.hxx
|
||||
Aspect_GenId.cxx
|
||||
Aspect_GenId.hxx
|
||||
Aspect_GradientBackground.cxx
|
||||
Aspect_GradientBackground.hxx
|
||||
Aspect_GradientFillMethod.hxx
|
||||
Aspect_GraphicDeviceDefinitionError.hxx
|
||||
Aspect_GraphicsLibrary.hxx
|
||||
Aspect_Grid.cxx
|
||||
Aspect_Grid.hxx
|
||||
Aspect_GridDrawMode.hxx
|
||||
Aspect_GridType.hxx
|
||||
Aspect_NeutralWindow.cxx
|
||||
Aspect_NeutralWindow.hxx
|
||||
Aspect_OpenVRSession.cxx
|
||||
Aspect_OpenVRSession.hxx
|
||||
Aspect_Handle.hxx
|
||||
Aspect_HatchStyle.hxx
|
||||
Aspect_IdentDefinitionError.hxx
|
||||
@ -37,6 +43,7 @@ Aspect_SequenceOfColor.hxx
|
||||
Aspect_ScrollDelta.hxx
|
||||
Aspect_Touch.hxx
|
||||
Aspect_TouchMap.hxx
|
||||
Aspect_TrackedDevicePose.hxx
|
||||
Aspect_TypeOfColorScaleData.hxx
|
||||
Aspect_TypeOfColorScaleOrientation.hxx
|
||||
Aspect_TypeOfColorScalePosition.hxx
|
||||
@ -60,4 +67,15 @@ Aspect_Window.hxx
|
||||
Aspect_WindowDefinitionError.hxx
|
||||
Aspect_WindowError.hxx
|
||||
Aspect_XAtom.hxx
|
||||
Aspect_XRAction.hxx
|
||||
Aspect_XRActionSet.hxx
|
||||
Aspect_XRActionType.hxx
|
||||
Aspect_XRAnalogActionData.hxx
|
||||
Aspect_XRDigitalActionData.hxx
|
||||
Aspect_XRGenericAction.hxx
|
||||
Aspect_XRHapticActionData.hxx
|
||||
Aspect_XRPoseActionData.hxx
|
||||
Aspect_XRSession.cxx
|
||||
Aspect_XRSession.hxx
|
||||
Aspect_XRTrackedDeviceRole.hxx
|
||||
Aspect_XWD.hxx
|
||||
|
@ -362,6 +362,11 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
|
||||
#else
|
||||
di << "OpenGL: desktop\n";
|
||||
#endif
|
||||
#ifdef HAVE_OPENVR
|
||||
di << "OpenVR enabled (HAVE_OPENVR)\n";
|
||||
#else
|
||||
di << "OpenVR disabled\n";
|
||||
#endif
|
||||
#ifdef HAVE_RAPIDJSON
|
||||
di << "RapidJSON enabled (HAVE_RAPIDJSON)\n";
|
||||
#else
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <Graphic3d_CView.hxx>
|
||||
|
||||
#include <Aspect_OpenVRSession.hxx>
|
||||
#include <Graphic3d_Layer.hxx>
|
||||
#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
|
||||
#include <Graphic3d_StructureManager.hxx>
|
||||
@ -32,7 +33,8 @@ Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theM
|
||||
myIsActive (Standard_False),
|
||||
myIsRemoved (Standard_False),
|
||||
myShadingModel (Graphic3d_TOSM_FRAGMENT),
|
||||
myVisualization (Graphic3d_TOV_WIREFRAME)
|
||||
myVisualization (Graphic3d_TOV_WIREFRAME),
|
||||
myUnitFactor (1.0)
|
||||
{
|
||||
myId = myStructureManager->Identification (this);
|
||||
}
|
||||
@ -43,6 +45,7 @@ Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theM
|
||||
//=======================================================================
|
||||
Graphic3d_CView::~Graphic3d_CView()
|
||||
{
|
||||
myXRSession.Nullify();
|
||||
if (!IsRemoved())
|
||||
{
|
||||
myStructureManager->UnIdentification (this);
|
||||
@ -1083,3 +1086,311 @@ void Graphic3d_CView::SetShadingModel (Graphic3d_TypeOfShadingModel theModel)
|
||||
|
||||
myShadingModel = theModel;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetUnitFactor
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_CView::SetUnitFactor (Standard_Real theFactor)
|
||||
{
|
||||
if (theFactor <= 0.0)
|
||||
{
|
||||
throw Standard_ProgramError ("Graphic3d_CView::SetUnitFactor() - invalid unit factor");
|
||||
}
|
||||
myUnitFactor = theFactor;
|
||||
if (!myXRSession.IsNull())
|
||||
{
|
||||
myXRSession->SetUnitFactor (theFactor);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : IsActiveXR
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Graphic3d_CView::IsActiveXR() const
|
||||
{
|
||||
return !myXRSession.IsNull()
|
||||
&& myXRSession->IsOpen();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InitXR
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Graphic3d_CView::InitXR()
|
||||
{
|
||||
if (myXRSession.IsNull())
|
||||
{
|
||||
myXRSession = new Aspect_OpenVRSession();
|
||||
myXRSession->SetUnitFactor (myUnitFactor);
|
||||
}
|
||||
if (!myXRSession->IsOpen())
|
||||
{
|
||||
myXRSession->Open();
|
||||
if (myBackXRCamera.IsNull())
|
||||
{
|
||||
// backup camera properties
|
||||
myBackXRCamera = new Graphic3d_Camera (myCamera);
|
||||
}
|
||||
}
|
||||
return myXRSession->IsOpen();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ReleaseXR
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_CView::ReleaseXR()
|
||||
{
|
||||
if (!myXRSession.IsNull())
|
||||
{
|
||||
if (myXRSession->IsOpen()
|
||||
&& !myBackXRCamera.IsNull())
|
||||
{
|
||||
// restore projection properties overridden by HMD
|
||||
myCamera->SetFOV2d (myBackXRCamera->FOV2d());
|
||||
myCamera->SetFOVy (myBackXRCamera->FOVy());
|
||||
myCamera->SetAspect(myBackXRCamera->Aspect());
|
||||
myCamera->SetIOD (myBackXRCamera->GetIODType(), myBackXRCamera->IOD());
|
||||
myCamera->SetZFocus(myBackXRCamera->ZFocusType(), myBackXRCamera->ZFocus());
|
||||
myCamera->ResetCustomProjection();
|
||||
myBackXRCamera.Nullify();
|
||||
}
|
||||
myXRSession->Close();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ProcessXRInput
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::ProcessXRInput()
|
||||
{
|
||||
if (myRenderParams.StereoMode == Graphic3d_StereoMode_OpenVR
|
||||
&& myCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
|
||||
{
|
||||
InitXR();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReleaseXR();
|
||||
}
|
||||
|
||||
if (!IsActiveXR())
|
||||
{
|
||||
myBaseXRCamera.Nullify();
|
||||
myPosedXRCamera.Nullify();
|
||||
return;
|
||||
}
|
||||
|
||||
myXRSession->ProcessEvents();
|
||||
Invalidate();
|
||||
|
||||
myCamera->SetFOV2d (myRenderParams.HmdFov2d);
|
||||
myCamera->SetAspect(myXRSession->Aspect());
|
||||
myCamera->SetFOVy (myXRSession->FieldOfView());
|
||||
myCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, myXRSession->IOD());
|
||||
myCamera->SetZFocus(Graphic3d_Camera::FocusType_Absolute, 1.0 * myUnitFactor);
|
||||
|
||||
// VR APIs tend to decompose camera orientation-projection matrices into the following components:
|
||||
// @begincode
|
||||
// Model * [View * Eye^-1] * [Projection]
|
||||
// @endcode
|
||||
// so that Eye position is encoded into Orientation matrix, and there should be 2 Orientation matrices and 2 Projection matrices to make the stereo.
|
||||
// Graphic3d_Camera historically follows different decomposition, with Eye position encoded into Projection matrix,
|
||||
// so that there is only 1 Orientation matrix (matching mono view) and 2 Projection matrices.
|
||||
if (myXRSession->HasProjectionFrustums())
|
||||
{
|
||||
// note that this definition does not include a small forward/backward offset from head to eye
|
||||
myCamera->SetCustomStereoFrustums (myXRSession->ProjectionFrustum (Aspect_Eye_Left),
|
||||
myXRSession->ProjectionFrustum (Aspect_Eye_Right));
|
||||
}
|
||||
else
|
||||
{
|
||||
const Graphic3d_Mat4d aPoseL = myXRSession->HeadToEyeTransform (Aspect_Eye_Left);
|
||||
const Graphic3d_Mat4d aPoseR = myXRSession->HeadToEyeTransform (Aspect_Eye_Right);
|
||||
const Graphic3d_Mat4d aProjL = myXRSession->ProjectionMatrix (Aspect_Eye_Left, myCamera->ZNear(), myCamera->ZFar());
|
||||
const Graphic3d_Mat4d aProjR = myXRSession->ProjectionMatrix (Aspect_Eye_Right, myCamera->ZNear(), myCamera->ZFar());
|
||||
myCamera->SetCustomStereoProjection (aProjL * aPoseL, aProjR * aPoseR);
|
||||
}
|
||||
myBaseXRCamera = myCamera;
|
||||
if (myPosedXRCamera.IsNull())
|
||||
{
|
||||
myPosedXRCamera = new Graphic3d_Camera();
|
||||
}
|
||||
SynchronizeXRBaseToPosedCamera();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SynchronizeXRBaseToPosedCamera
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::SynchronizeXRBaseToPosedCamera()
|
||||
{
|
||||
if (!myPosedXRCamera.IsNull())
|
||||
{
|
||||
ComputeXRPosedCameraFromBase (*myPosedXRCamera, myXRSession->HeadPose());
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeXRPosedCameraFromBase
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::ComputeXRPosedCameraFromBase (Graphic3d_Camera& theCam,
|
||||
const gp_Trsf& theXRTrsf) const
|
||||
{
|
||||
theCam.Copy (myBaseXRCamera);
|
||||
|
||||
// convert head pose into camera transformation
|
||||
const gp_Ax3 anAxVr (gp::Origin(), gp::DZ(), gp::DX());
|
||||
const gp_Ax3 aCameraCS (gp::Origin(), -myBaseXRCamera->Direction(), -myBaseXRCamera->SideRight());
|
||||
gp_Trsf aTrsfCS;
|
||||
aTrsfCS.SetTransformation (aCameraCS, anAxVr);
|
||||
const gp_Trsf aTrsfToCamera = aTrsfCS * theXRTrsf * aTrsfCS.Inverted();
|
||||
gp_Trsf aTrsfToEye;
|
||||
aTrsfToEye.SetTranslation (myBaseXRCamera->Eye().XYZ());
|
||||
|
||||
const gp_Trsf aTrsf = aTrsfToEye * aTrsfToCamera;
|
||||
const gp_Dir anUpNew = myBaseXRCamera->Up().Transformed (aTrsf);
|
||||
const gp_Dir aDirNew = myBaseXRCamera->Direction().Transformed (aTrsf);
|
||||
const gp_Pnt anEyeNew = gp::Origin().Translated (aTrsf.TranslationPart());
|
||||
theCam.SetUp (anUpNew);
|
||||
theCam.SetDirectionFromEye (aDirNew);
|
||||
theCam.MoveEyeTo (anEyeNew);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SynchronizeXRPosedToBaseCamera
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::SynchronizeXRPosedToBaseCamera()
|
||||
{
|
||||
if (myPosedXRCameraCopy.IsNull()
|
||||
|| myPosedXRCamera.IsNull()
|
||||
|| myBaseXRCamera.IsNull()
|
||||
|| myCamera != myPosedXRCamera)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (myPosedXRCameraCopy->Eye().IsEqual (myPosedXRCamera->Eye(), gp::Resolution())
|
||||
&& (myPosedXRCameraCopy->Distance() - myPosedXRCamera->Distance()) <= gp::Resolution()
|
||||
&& myPosedXRCameraCopy->Direction().IsEqual (myPosedXRCamera->Direction(), gp::Resolution())
|
||||
&& myPosedXRCameraCopy->Up().IsEqual (myPosedXRCamera->Up(), gp::Resolution()))
|
||||
{
|
||||
// avoid floating point math in case of no changes
|
||||
return;
|
||||
}
|
||||
|
||||
// re-compute myBaseXRCamera from myPosedXRCamera by applying reversed head pose transformation
|
||||
ComputeXRBaseCameraFromPosed (myPosedXRCamera, myXRSession->HeadPose());
|
||||
myPosedXRCameraCopy->Copy (myPosedXRCamera);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeXRBaseCameraFromPosed
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::ComputeXRBaseCameraFromPosed (const Graphic3d_Camera& theCamPosed,
|
||||
const gp_Trsf& thePoseTrsf)
|
||||
{
|
||||
const gp_Ax3 anAxVr (gp::Origin(), gp::DZ(), gp::DX());
|
||||
const gp_Ax3 aCameraCS (gp::Origin(), -myBaseXRCamera->Direction(), -myBaseXRCamera->SideRight());
|
||||
gp_Trsf aTrsfCS;
|
||||
aTrsfCS.SetTransformation (aCameraCS, anAxVr);
|
||||
const gp_Trsf aTrsfToCamera = aTrsfCS * thePoseTrsf * aTrsfCS.Inverted();
|
||||
const gp_Trsf aTrsfCamToHead = aTrsfToCamera.Inverted();
|
||||
const gp_Dir anUpNew = theCamPosed.Up().Transformed (aTrsfCamToHead);
|
||||
const gp_Dir aDirNew = theCamPosed.Direction().Transformed (aTrsfCamToHead);
|
||||
const gp_Pnt anEyeNew = theCamPosed.Eye().Translated (aTrsfToCamera.TranslationPart().Reversed());
|
||||
myBaseXRCamera->SetUp (anUpNew);
|
||||
myBaseXRCamera->SetDirectionFromEye (aDirNew);
|
||||
myBaseXRCamera->MoveEyeTo (anEyeNew);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TurnViewXRCamera
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::TurnViewXRCamera (const gp_Trsf& theTrsfTurn)
|
||||
{
|
||||
// use current eye position as an anchor
|
||||
const Handle(Graphic3d_Camera)& aCamBase = myBaseXRCamera;
|
||||
gp_Trsf aHeadTrsfLocal;
|
||||
aHeadTrsfLocal.SetTranslationPart (myXRSession->HeadPose().TranslationPart());
|
||||
const gp_Pnt anEyeAnchor = PoseXRToWorld (aHeadTrsfLocal).TranslationPart();
|
||||
|
||||
// turn the view
|
||||
aCamBase->SetDirectionFromEye (aCamBase->Direction().Transformed (theTrsfTurn));
|
||||
|
||||
// recompute new eye
|
||||
const gp_Ax3 anAxVr (gp::Origin(), gp::DZ(), gp::DX());
|
||||
const gp_Ax3 aCameraCS (gp::Origin(), -aCamBase->Direction(), -aCamBase->SideRight());
|
||||
gp_Trsf aTrsfCS;
|
||||
aTrsfCS.SetTransformation (aCameraCS, anAxVr);
|
||||
const gp_Trsf aTrsfToCamera = aTrsfCS * aHeadTrsfLocal * aTrsfCS.Inverted();
|
||||
const gp_Pnt anEyeNew = anEyeAnchor.Translated (aTrsfToCamera.TranslationPart().Reversed());
|
||||
aCamBase->MoveEyeTo (anEyeNew);
|
||||
|
||||
SynchronizeXRBaseToPosedCamera();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetupXRPosedCamera
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::SetupXRPosedCamera()
|
||||
{
|
||||
if (!myPosedXRCamera.IsNull())
|
||||
{
|
||||
myCamera = myPosedXRCamera;
|
||||
if (myPosedXRCameraCopy.IsNull())
|
||||
{
|
||||
myPosedXRCameraCopy = new Graphic3d_Camera();
|
||||
}
|
||||
myPosedXRCameraCopy->Copy (myPosedXRCamera);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UnsetXRPosedCamera
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::UnsetXRPosedCamera()
|
||||
{
|
||||
if (myCamera == myPosedXRCamera
|
||||
&& !myBaseXRCamera.IsNull())
|
||||
{
|
||||
SynchronizeXRPosedToBaseCamera();
|
||||
myCamera = myBaseXRCamera;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DiagnosticInformation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_CView::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
|
||||
Graphic3d_DiagnosticInfo theFlags) const
|
||||
{
|
||||
if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0
|
||||
&& !myXRSession.IsNull())
|
||||
{
|
||||
TCollection_AsciiString aVendor = myXRSession->GetString (Aspect_XRSession::InfoString_Vendor);
|
||||
TCollection_AsciiString aDevice = myXRSession->GetString (Aspect_XRSession::InfoString_Device);
|
||||
TCollection_AsciiString aTracker = myXRSession->GetString (Aspect_XRSession::InfoString_Tracker);
|
||||
TCollection_AsciiString aSerial = myXRSession->GetString (Aspect_XRSession::InfoString_SerialNumber);
|
||||
TCollection_AsciiString aDisplay = TCollection_AsciiString()
|
||||
+ myXRSession->RecommendedViewport().x() + "x" + myXRSession->RecommendedViewport().y()
|
||||
+ "@" + (int )Round (myXRSession->DisplayFrequency())
|
||||
+ " [FOVy: " + (int )Round (myXRSession->FieldOfView()) + "]";
|
||||
|
||||
theDict.ChangeFromIndex (theDict.Add ("VRvendor", aVendor)) = aVendor;
|
||||
theDict.ChangeFromIndex (theDict.Add ("VRdevice", aDevice)) = aDevice;
|
||||
theDict.ChangeFromIndex (theDict.Add ("VRtracker", aTracker)) = aTracker;
|
||||
theDict.ChangeFromIndex (theDict.Add ("VRdisplay", aDisplay)) = aDisplay;
|
||||
theDict.ChangeFromIndex (theDict.Add ("VRserial", aSerial)) = aSerial;
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <TColStd_IndexedDataMapOfStringString.hxx>
|
||||
|
||||
class Aspect_XRSession;
|
||||
class Graphic3d_CView;
|
||||
class Graphic3d_GraphicDriver;
|
||||
class Graphic3d_Layer;
|
||||
@ -427,8 +428,8 @@ public:
|
||||
//! The format of returned information (e.g. key-value layout)
|
||||
//! is NOT part of this API and can be changed at any time.
|
||||
//! Thus application should not parse returned information to weed out specific parameters.
|
||||
virtual void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
|
||||
Graphic3d_DiagnosticInfo theFlags) const = 0;
|
||||
Standard_EXPORT virtual void DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
|
||||
Graphic3d_DiagnosticInfo theFlags) const = 0;
|
||||
|
||||
//! Returns string with statistic performance info.
|
||||
virtual TCollection_AsciiString StatisticInformation() const = 0;
|
||||
@ -436,6 +437,84 @@ public:
|
||||
//! Fills in the dictionary with statistic performance info.
|
||||
virtual void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
//! Return unit scale factor defined as scale factor for m (meters); 1.0 by default.
|
||||
//! Normally, view definition is unitless, however some operations like VR input requires proper units mapping.
|
||||
Standard_Real UnitFactor() const { return myUnitFactor; }
|
||||
|
||||
//! Set unit scale factor.
|
||||
Standard_EXPORT void SetUnitFactor (Standard_Real theFactor);
|
||||
|
||||
//! Return XR session.
|
||||
const Handle(Aspect_XRSession)& XRSession() const { return myXRSession; }
|
||||
|
||||
//! Set XR session.
|
||||
void SetXRSession (const Handle(Aspect_XRSession)& theSession) { myXRSession = theSession; }
|
||||
|
||||
//! Return TRUE if there is active XR session.
|
||||
Standard_EXPORT bool IsActiveXR() const;
|
||||
|
||||
//! Initialize XR session.
|
||||
Standard_EXPORT virtual bool InitXR();
|
||||
|
||||
//! Release XR session.
|
||||
Standard_EXPORT virtual void ReleaseXR();
|
||||
|
||||
//! Process input.
|
||||
Standard_EXPORT virtual void ProcessXRInput();
|
||||
|
||||
//! Compute PosedXRCamera() based on current XR head pose and make it active.
|
||||
Standard_EXPORT void SetupXRPosedCamera();
|
||||
|
||||
//! Set current camera back to BaseXRCamera() and copy temporary modifications of PosedXRCamera().
|
||||
//! Calls SynchronizeXRPosedToBaseCamera() beforehand.
|
||||
Standard_EXPORT void UnsetXRPosedCamera();
|
||||
|
||||
//! Returns transient XR camera position with tracked head orientation applied.
|
||||
const Handle(Graphic3d_Camera)& PosedXRCamera() const { return myPosedXRCamera; }
|
||||
|
||||
//! Sets transient XR camera position with tracked head orientation applied.
|
||||
void SetPosedXRCamera (const Handle(Graphic3d_Camera)& theCamera) { myPosedXRCamera = theCamera; }
|
||||
|
||||
//! Returns anchor camera definition (without tracked head orientation).
|
||||
const Handle(Graphic3d_Camera)& BaseXRCamera() const { return myBaseXRCamera; }
|
||||
|
||||
//! Sets anchor camera definition.
|
||||
void SetBaseXRCamera (const Handle(Graphic3d_Camera)& theCamera) { myBaseXRCamera = theCamera; }
|
||||
|
||||
//! Convert XR pose to world space.
|
||||
//! @param theTrsfXR [in] transformation defined in VR local coordinate system,
|
||||
//! oriented as Y-up, X-right and -Z-forward
|
||||
//! @return transformation defining orientation of XR pose in world space
|
||||
gp_Trsf PoseXRToWorld (const gp_Trsf& thePoseXR) const
|
||||
{
|
||||
const Handle(Graphic3d_Camera)& anOrigin = myBaseXRCamera;
|
||||
const gp_Ax3 anAxVr (gp::Origin(), gp::DZ(), gp::DX());
|
||||
const gp_Ax3 aCameraCS (anOrigin->Eye().XYZ(), -anOrigin->Direction(), -anOrigin->SideRight());
|
||||
gp_Trsf aTrsfCS;
|
||||
aTrsfCS.SetTransformation (aCameraCS, anAxVr);
|
||||
return aTrsfCS * thePoseXR;
|
||||
}
|
||||
|
||||
//! Recomputes PosedXRCamera() based on BaseXRCamera() and head orientation.
|
||||
Standard_EXPORT void SynchronizeXRBaseToPosedCamera();
|
||||
|
||||
//! Checks if PosedXRCamera() has been modified since SetupXRPosedCamera()
|
||||
//! and copies these modifications to BaseXRCamera().
|
||||
Standard_EXPORT void SynchronizeXRPosedToBaseCamera();
|
||||
|
||||
//! Compute camera position based on XR pose.
|
||||
Standard_EXPORT void ComputeXRPosedCameraFromBase (Graphic3d_Camera& theCam,
|
||||
const gp_Trsf& theXRTrsf) const;
|
||||
|
||||
//! Update based camera from posed camera by applying reversed transformation.
|
||||
Standard_EXPORT void ComputeXRBaseCameraFromPosed (const Graphic3d_Camera& theCamPosed,
|
||||
const gp_Trsf& thePoseTrsf);
|
||||
|
||||
//! Turn XR camera direction using current (head) eye position as anchor.
|
||||
Standard_EXPORT void TurnViewXRCamera (const gp_Trsf& theTrsfTurn);
|
||||
|
||||
public: //! @name obsolete Graduated Trihedron functionality
|
||||
|
||||
//! Returns data of a graduated trihedron
|
||||
@ -490,6 +569,13 @@ protected:
|
||||
Graphic3d_TypeOfShadingModel myShadingModel;
|
||||
Graphic3d_TypeOfVisualization myVisualization;
|
||||
|
||||
Handle(Aspect_XRSession) myXRSession;
|
||||
Handle(Graphic3d_Camera) myBackXRCamera; //!< camera projection parameters to restore after closing XR session (FOV, aspect and similar)
|
||||
Handle(Graphic3d_Camera) myBaseXRCamera; //!< neutral camera orientation defining coordinate system in which head tracking is defined
|
||||
Handle(Graphic3d_Camera) myPosedXRCamera; //!< transient XR camera orientation with tracked head orientation applied (based on myBaseXRCamera)
|
||||
Handle(Graphic3d_Camera) myPosedXRCameraCopy; //!< neutral camera orientation copy at the beginning of processing input
|
||||
Standard_Real myUnitFactor; //!< unit scale factor defined as scale factor for m (meters)
|
||||
|
||||
protected:
|
||||
|
||||
Graphic3d_GraduatedTrihedron myGTrihedronData;
|
||||
|
@ -81,6 +81,8 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
myAxialScale (1.0, 1.0, 1.0),
|
||||
myProjType (Projection_Orthographic),
|
||||
myFOVy (45.0),
|
||||
myFOVx (45.0),
|
||||
myFOV2d (180.0),
|
||||
myFOVyTan (Tan (DTR_HALF * 45.0)),
|
||||
myZNear (DEFAULT_ZNEAR),
|
||||
myZFar (DEFAULT_ZFAR),
|
||||
@ -89,7 +91,10 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
myZFocus (1.0),
|
||||
myZFocusType (FocusType_Relative),
|
||||
myIOD (0.05),
|
||||
myIODType (IODType_Relative)
|
||||
myIODType (IODType_Relative),
|
||||
myIsCustomProjMatM (false),
|
||||
myIsCustomProjMatLR(false),
|
||||
myIsCustomFrustomLR(false)
|
||||
{
|
||||
myWorldViewProjState.Initialize ((Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
|
||||
(Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
|
||||
@ -108,6 +113,8 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
myAxialScale (1.0, 1.0, 1.0),
|
||||
myProjType (Projection_Orthographic),
|
||||
myFOVy (45.0),
|
||||
myFOVx (45.0),
|
||||
myFOV2d (180.0),
|
||||
myFOVyTan (Tan (DTR_HALF * 45.0)),
|
||||
myZNear (DEFAULT_ZNEAR),
|
||||
myZFar (DEFAULT_ZFAR),
|
||||
@ -116,7 +123,10 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
myZFocus (1.0),
|
||||
myZFocusType (FocusType_Relative),
|
||||
myIOD (0.05),
|
||||
myIODType (IODType_Relative)
|
||||
myIODType (IODType_Relative),
|
||||
myIsCustomProjMatM (false),
|
||||
myIsCustomProjMatLR(false),
|
||||
myIsCustomFrustomLR(false)
|
||||
{
|
||||
myWorldViewProjState.Initialize (this);
|
||||
|
||||
@ -130,6 +140,7 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera)
|
||||
{
|
||||
SetFOVy (theOtherCamera->FOVy());
|
||||
SetFOV2d (theOtherCamera->FOV2d());
|
||||
SetZRange (theOtherCamera->ZNear(), theOtherCamera->ZFar());
|
||||
SetAspect (theOtherCamera->Aspect());
|
||||
SetScale (theOtherCamera->Scale());
|
||||
@ -137,6 +148,20 @@ void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOther
|
||||
SetIOD (theOtherCamera->GetIODType(), theOtherCamera->IOD());
|
||||
SetProjectionType (theOtherCamera->ProjectionType());
|
||||
SetTile (theOtherCamera->myTile);
|
||||
|
||||
ResetCustomProjection();
|
||||
if (theOtherCamera->IsCustomStereoProjection())
|
||||
{
|
||||
SetCustomStereoProjection (theOtherCamera->myCustomProjMatL, theOtherCamera->myCustomProjMatR);
|
||||
}
|
||||
else if (theOtherCamera->IsCustomStereoFrustum())
|
||||
{
|
||||
SetCustomStereoFrustums (theOtherCamera->myCustomFrustumL, theOtherCamera->myCustomFrustumR);
|
||||
}
|
||||
if (theOtherCamera->IsCustomMonoProjection())
|
||||
{
|
||||
SetCustomMonoProjection (theOtherCamera->myCustomProjMatM);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -419,11 +444,27 @@ void Graphic3d_Camera::SetFOVy (const Standard_Real theFOVy)
|
||||
}
|
||||
|
||||
myFOVy = theFOVy;
|
||||
myFOVx = theFOVy * myAspect;
|
||||
myFOVyTan = Tan(DTR_HALF * myFOVy);
|
||||
|
||||
InvalidateProjection();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetFOV2d
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::SetFOV2d (const Standard_Real theFOV)
|
||||
{
|
||||
if (FOV2d() == theFOV)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myFOV2d = theFOV;
|
||||
InvalidateProjection();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetZRange
|
||||
// purpose :
|
||||
@ -462,6 +503,7 @@ void Graphic3d_Camera::SetAspect (const Standard_Real theAspect)
|
||||
}
|
||||
|
||||
myAspect = theAspect;
|
||||
myFOVx = myFOVy * theAspect;
|
||||
|
||||
InvalidateProjection();
|
||||
}
|
||||
@ -871,6 +913,62 @@ const Graphic3d_Mat4& Graphic3d_Camera::ProjectionStereoRightF() const
|
||||
return UpdateProjection (myMatricesF).RProjection;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ResetCustomProjection
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::ResetCustomProjection()
|
||||
{
|
||||
if (myIsCustomFrustomLR
|
||||
|| myIsCustomProjMatLR
|
||||
|| myIsCustomProjMatM)
|
||||
{
|
||||
myIsCustomFrustomLR = false;
|
||||
myIsCustomProjMatLR = false;
|
||||
myIsCustomProjMatM = false;
|
||||
InvalidateProjection();
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCustomStereoFrustums
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::SetCustomStereoFrustums (const Aspect_FrustumLRBT<Standard_Real>& theFrustumL,
|
||||
const Aspect_FrustumLRBT<Standard_Real>& theFrustumR)
|
||||
{
|
||||
myCustomFrustumL = theFrustumL;
|
||||
myCustomFrustumR = theFrustumR;
|
||||
myIsCustomFrustomLR = true;
|
||||
myIsCustomProjMatLR = false;
|
||||
InvalidateProjection();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCustomStereoProjection
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::SetCustomStereoProjection (const Graphic3d_Mat4d& theProjL,
|
||||
const Graphic3d_Mat4d& theProjR)
|
||||
{
|
||||
myCustomProjMatL = theProjL;
|
||||
myCustomProjMatR = theProjR;
|
||||
myIsCustomProjMatLR = true;
|
||||
myIsCustomFrustomLR = false;
|
||||
InvalidateProjection();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCustomMonoProjection
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::SetCustomMonoProjection (const Graphic3d_Mat4d& theProj)
|
||||
{
|
||||
myCustomProjMatM = theProj;
|
||||
myIsCustomProjMatM = true;
|
||||
InvalidateProjection();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : UpdateProjection
|
||||
// purpose :
|
||||
@ -894,13 +992,11 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
|
||||
Elem_t aDXHalf = 0.0, aDYHalf = 0.0;
|
||||
if (IsOrthographic())
|
||||
{
|
||||
aDXHalf = aScale * Elem_t (0.5);
|
||||
aDYHalf = aScale * Elem_t (0.5);
|
||||
aDXHalf = aDYHalf = aScale * Elem_t (0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
aDXHalf = aZNear * Elem_t (myFOVyTan);
|
||||
aDYHalf = aZNear * Elem_t (myFOVyTan);
|
||||
aDXHalf = aDYHalf = aZNear * Elem_t (myFOVyTan);
|
||||
}
|
||||
|
||||
if (anAspect > 1.0)
|
||||
@ -913,10 +1009,11 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
|
||||
}
|
||||
|
||||
// sets right of frustum based on aspect ratio
|
||||
Elem_t aLeft = -aDXHalf;
|
||||
Elem_t aRight = aDXHalf;
|
||||
Elem_t aBot = -aDYHalf;
|
||||
Elem_t aTop = aDYHalf;
|
||||
Aspect_FrustumLRBT<Elem_t> anLRBT;
|
||||
anLRBT.Left = -aDXHalf;
|
||||
anLRBT.Right = aDXHalf;
|
||||
anLRBT.Bottom = -aDYHalf;
|
||||
anLRBT.Top = aDYHalf;
|
||||
|
||||
Elem_t aIOD = myIODType == IODType_Relative
|
||||
? static_cast<Elem_t> (myIOD * Distance())
|
||||
@ -931,56 +1028,83 @@ Graphic3d_Camera::TransformMatrices<Elem_t>&
|
||||
const Elem_t aDXFull = Elem_t(2) * aDXHalf;
|
||||
const Elem_t aDYFull = Elem_t(2) * aDYHalf;
|
||||
const Graphic3d_Vec2i anOffset = myTile.OffsetLowerLeft();
|
||||
aLeft = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
|
||||
aRight = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x() + myTile.TileSize.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
|
||||
aBot = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
|
||||
aTop = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y() + myTile.TileSize.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
|
||||
anLRBT.Left = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
|
||||
anLRBT.Right = -aDXHalf + aDXFull * static_cast<Elem_t> (anOffset.x() + myTile.TileSize.x()) / static_cast<Elem_t> (myTile.TotalSize.x());
|
||||
anLRBT.Bottom = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
|
||||
anLRBT.Top = -aDYHalf + aDYFull * static_cast<Elem_t> (anOffset.y() + myTile.TileSize.y()) / static_cast<Elem_t> (myTile.TotalSize.y());
|
||||
}
|
||||
|
||||
if (myIsCustomProjMatM)
|
||||
{
|
||||
theMatrices.MProjection.ConvertFrom (myCustomProjMatM);
|
||||
}
|
||||
switch (myProjType)
|
||||
{
|
||||
case Projection_Orthographic :
|
||||
OrthoProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
|
||||
break;
|
||||
|
||||
case Projection_Perspective :
|
||||
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
|
||||
break;
|
||||
|
||||
case Projection_MonoLeftEye :
|
||||
case Projection_Orthographic:
|
||||
{
|
||||
StereoEyeProj (aLeft, aRight, aBot, aTop,
|
||||
aZNear, aZFar, aIOD, aFocus,
|
||||
Standard_True, theMatrices.MProjection);
|
||||
theMatrices.LProjection = theMatrices.MProjection;
|
||||
if (!myIsCustomProjMatM)
|
||||
{
|
||||
orthoProj (theMatrices.MProjection, anLRBT, aZNear, aZFar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Projection_MonoRightEye :
|
||||
case Projection_Perspective:
|
||||
{
|
||||
StereoEyeProj (aLeft, aRight, aBot, aTop,
|
||||
aZNear, aZFar, aIOD, aFocus,
|
||||
Standard_False, theMatrices.MProjection);
|
||||
theMatrices.RProjection = theMatrices.MProjection;
|
||||
if (!myIsCustomProjMatM)
|
||||
{
|
||||
perspectiveProj (theMatrices.MProjection, anLRBT, aZNear, aZFar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Projection_Stereo :
|
||||
case Projection_MonoLeftEye:
|
||||
case Projection_MonoRightEye:
|
||||
case Projection_Stereo:
|
||||
{
|
||||
PerspectiveProj (aLeft, aRight, aBot, aTop, aZNear, aZFar, theMatrices.MProjection);
|
||||
if (!myIsCustomProjMatM)
|
||||
{
|
||||
perspectiveProj (theMatrices.MProjection, anLRBT, aZNear, aZFar);
|
||||
}
|
||||
if (myIsCustomProjMatLR)
|
||||
{
|
||||
theMatrices.LProjection.ConvertFrom (myCustomProjMatL);
|
||||
theMatrices.RProjection.ConvertFrom (myCustomProjMatR);
|
||||
}
|
||||
else if (myIsCustomFrustomLR)
|
||||
{
|
||||
anLRBT = Aspect_FrustumLRBT<Elem_t> (myCustomFrustumL).Multiplied (aZNear);
|
||||
perspectiveProj (theMatrices.LProjection, anLRBT, aZNear, aZFar);
|
||||
if (aIOD != Elem_t (0.0))
|
||||
{
|
||||
theMatrices.LProjection.Translate (NCollection_Vec3<Elem_t> (Elem_t (0.5) * aIOD, Elem_t (0.0), Elem_t (0.0)));
|
||||
}
|
||||
|
||||
StereoEyeProj (aLeft, aRight, aBot, aTop,
|
||||
aZNear, aZFar, aIOD, aFocus,
|
||||
Standard_True,
|
||||
theMatrices.LProjection);
|
||||
|
||||
StereoEyeProj (aLeft, aRight, aBot, aTop,
|
||||
aZNear, aZFar, aIOD, aFocus,
|
||||
Standard_False,
|
||||
theMatrices.RProjection);
|
||||
anLRBT = Aspect_FrustumLRBT<Elem_t> (myCustomFrustumR).Multiplied (aZNear);
|
||||
perspectiveProj (theMatrices.RProjection, anLRBT, aZNear, aZFar);
|
||||
if (aIOD != Elem_t (0.0))
|
||||
{
|
||||
theMatrices.RProjection.Translate (NCollection_Vec3<Elem_t> (Elem_t (-0.5) * aIOD, Elem_t (0.0), Elem_t (0.0)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stereoEyeProj (theMatrices.LProjection,
|
||||
anLRBT, aZNear, aZFar, aIOD, aFocus,
|
||||
Aspect_Eye_Left);
|
||||
stereoEyeProj (theMatrices.RProjection,
|
||||
anLRBT, aZNear, aZFar, aIOD, aFocus,
|
||||
Aspect_Eye_Right);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myProjType == Projection_MonoLeftEye)
|
||||
{
|
||||
theMatrices.MProjection = theMatrices.LProjection;
|
||||
}
|
||||
else if (myProjType == Projection_MonoRightEye)
|
||||
{
|
||||
theMatrices.MProjection = theMatrices.RProjection;
|
||||
}
|
||||
|
||||
return theMatrices; // for inline accessors
|
||||
}
|
||||
@ -1044,29 +1168,26 @@ void Graphic3d_Camera::InvalidateOrientation()
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : OrthoProj
|
||||
// function : orthoProj
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template <typename Elem_t>
|
||||
void Graphic3d_Camera::OrthoProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
void Graphic3d_Camera::orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
NCollection_Mat4<Elem_t>& theOutMx)
|
||||
const Elem_t theFar)
|
||||
{
|
||||
// row 0
|
||||
theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theRight - theLeft);
|
||||
theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theLRBT.Right - theLRBT.Left);
|
||||
theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (0, 2) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (0, 3) = - (theRight + theLeft) / (theRight - theLeft);
|
||||
theOutMx.ChangeValue (0, 3) = - (theLRBT.Right + theLRBT.Left) / (theLRBT.Right - theLRBT.Left);
|
||||
|
||||
// row 1
|
||||
theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (1, 1) = Elem_t (2.0) / (theTop - theBottom);
|
||||
theOutMx.ChangeValue (1, 1) = Elem_t (2.0) / (theLRBT.Top - theLRBT.Bottom);
|
||||
theOutMx.ChangeValue (1, 2) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (1, 3) = - (theTop + theBottom) / (theTop - theBottom);
|
||||
theOutMx.ChangeValue (1, 3) = - (theLRBT.Top + theLRBT.Bottom) / (theLRBT.Top - theLRBT.Bottom);
|
||||
|
||||
// row 2
|
||||
theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
|
||||
@ -1086,29 +1207,26 @@ void Graphic3d_Camera::OrthoProj (const Elem_t theLeft,
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template <typename Elem_t>
|
||||
void Graphic3d_Camera::PerspectiveProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
void Graphic3d_Camera::perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
NCollection_Mat4<Elem_t>& theOutMx)
|
||||
const Elem_t theFar)
|
||||
{
|
||||
// column 0
|
||||
theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theRight - theLeft);
|
||||
theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theLRBT.Right - theLRBT.Left);
|
||||
theOutMx.ChangeValue (1, 0) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
|
||||
|
||||
// column 1
|
||||
theOutMx.ChangeValue (0, 1) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (1, 1) = (Elem_t (2.0) * theNear) / (theTop - theBottom);
|
||||
theOutMx.ChangeValue (1, 1) = (Elem_t (2.0) * theNear) / (theLRBT.Top - theLRBT.Bottom);
|
||||
theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
|
||||
theOutMx.ChangeValue (3, 1) = Elem_t (0.0);
|
||||
|
||||
// column 2
|
||||
theOutMx.ChangeValue (0, 2) = (theRight + theLeft) / (theRight - theLeft);
|
||||
theOutMx.ChangeValue (1, 2) = (theTop + theBottom) / (theTop - theBottom);
|
||||
theOutMx.ChangeValue (0, 2) = (theLRBT.Right + theLRBT.Left) / (theLRBT.Right - theLRBT.Left);
|
||||
theOutMx.ChangeValue (1, 2) = (theLRBT.Top + theLRBT.Bottom) / (theLRBT.Top - theLRBT.Bottom);
|
||||
theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
|
||||
theOutMx.ChangeValue (3, 2) = Elem_t (-1.0);
|
||||
|
||||
@ -1124,25 +1242,22 @@ void Graphic3d_Camera::PerspectiveProj (const Elem_t theLeft,
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template <typename Elem_t>
|
||||
void Graphic3d_Camera::StereoEyeProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
void Graphic3d_Camera::stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
const Elem_t theIOD,
|
||||
const Elem_t theZFocus,
|
||||
const Standard_Boolean theIsLeft,
|
||||
NCollection_Mat4<Elem_t>& theOutMx)
|
||||
const Aspect_Eye theEyeIndex)
|
||||
{
|
||||
Elem_t aDx = theIsLeft ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
|
||||
Elem_t aDx = theEyeIndex == Aspect_Eye_Left ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
|
||||
Elem_t aDXStereoShift = aDx * theNear / theZFocus;
|
||||
|
||||
// construct eye projection matrix
|
||||
PerspectiveProj (theLeft + aDXStereoShift,
|
||||
theRight + aDXStereoShift,
|
||||
theBottom, theTop, theNear, theFar,
|
||||
theOutMx);
|
||||
Aspect_FrustumLRBT<Elem_t> aLRBT = theLRBT;
|
||||
aLRBT.Left = theLRBT.Left + aDXStereoShift;
|
||||
aLRBT.Right = theLRBT.Right + aDXStereoShift;
|
||||
perspectiveProj (theOutMx, aLRBT, theNear, theFar);
|
||||
|
||||
if (theIOD != Elem_t (0.0))
|
||||
{
|
||||
|
@ -16,6 +16,8 @@
|
||||
#ifndef _Graphic3d_Camera_HeaderFile
|
||||
#define _Graphic3d_Camera_HeaderFile
|
||||
|
||||
#include <Aspect_Eye.hxx>
|
||||
#include <Aspect_FrustumLRBT.hxx>
|
||||
#include <Graphic3d_CameraTile.hxx>
|
||||
#include <Graphic3d_Mat4d.hxx>
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
@ -185,6 +187,12 @@ public:
|
||||
//! Return a copy of orthogonalized up direction vector.
|
||||
Standard_EXPORT gp_Dir OrthogonalizedUp() const;
|
||||
|
||||
//! Right side direction.
|
||||
gp_Dir SideRight() const
|
||||
{
|
||||
return -(gp_Vec (Direction()) ^ gp_Vec (OrthogonalizedUp()));
|
||||
}
|
||||
|
||||
//! Get camera Eye position.
|
||||
//! @return camera eye location.
|
||||
const gp_Pnt& Eye() const { return myEye; }
|
||||
@ -284,15 +292,26 @@ public:
|
||||
}
|
||||
|
||||
//! Set Field Of View (FOV) in y axis for perspective projection.
|
||||
//! Field of View in x axis is automatically scaled from view aspect ratio.
|
||||
//! @param theFOVy [in] the FOV in degrees.
|
||||
Standard_EXPORT void SetFOVy (const Standard_Real theFOVy);
|
||||
|
||||
//! Get Field Of View (FOV) in y axis.
|
||||
//! @return the FOV value in degrees.
|
||||
Standard_Real FOVy() const
|
||||
{
|
||||
return myFOVy;
|
||||
}
|
||||
Standard_Real FOVy() const { return myFOVy; }
|
||||
|
||||
//! Get Field Of View (FOV) in x axis.
|
||||
//! @return the FOV value in degrees.
|
||||
Standard_Real FOVx() const { return myFOVx; }
|
||||
|
||||
//! Get Field Of View (FOV) restriction for 2D on-screen elements; 180 degrees by default.
|
||||
//! When 2D FOV is smaller than FOVy or FOVx, 2D elements defined within offset from view corner
|
||||
//! will be extended to fit into specified 2D FOV.
|
||||
//! This can be useful to make 2D elements sharply visible, like in case of HMD normally having extra large FOVy.
|
||||
Standard_Real FOV2d() const { return myFOV2d; }
|
||||
|
||||
//! Set Field Of View (FOV) restriction for 2D on-screen elements.
|
||||
Standard_EXPORT void SetFOV2d (Standard_Real theFOV);
|
||||
|
||||
//! Estimate Z-min and Z-max planes of projection volume to match the
|
||||
//! displayed objects. The methods ensures that view volume will
|
||||
@ -427,6 +446,24 @@ public:
|
||||
//! @return values in form of gp_Pnt (Width, Height, Depth).
|
||||
Standard_EXPORT gp_XYZ ViewDimensions (const Standard_Real theZValue) const;
|
||||
|
||||
//! Return offset to the view corner in NDC space within dimension X for 2d on-screen elements, which is normally 0.5.
|
||||
//! Can be clamped when FOVx exceeds FOV2d.
|
||||
Standard_Real NDC2dOffsetX() const
|
||||
{
|
||||
return myFOV2d >= myFOVx
|
||||
? 0.5
|
||||
: 0.5 * myFOV2d / myFOVx;
|
||||
}
|
||||
|
||||
//! Return offset to the view corner in NDC space within dimension X for 2d on-screen elements, which is normally 0.5.
|
||||
//! Can be clamped when FOVy exceeds FOV2d.
|
||||
Standard_Real NDC2dOffsetY() const
|
||||
{
|
||||
return myFOV2d >= myFOVy
|
||||
? 0.5
|
||||
: 0.5 * myFOV2d / myFOVy;
|
||||
}
|
||||
|
||||
//! Calculate WCS frustum planes for the camera projection volume.
|
||||
//! Frustum is a convex volume determined by six planes directing
|
||||
//! inwards.
|
||||
@ -552,6 +589,32 @@ public:
|
||||
//! The matrix will be updated on request.
|
||||
Standard_EXPORT void InvalidateOrientation();
|
||||
|
||||
public:
|
||||
|
||||
//! Unset all custom frustums and projection matrices.
|
||||
Standard_EXPORT void ResetCustomProjection();
|
||||
|
||||
//! Return TRUE if custom stereo frustums are set.
|
||||
bool IsCustomStereoFrustum() const { return myIsCustomFrustomLR; }
|
||||
|
||||
//! Set custom stereo frustums.
|
||||
//! These can be retrieved from APIs like OpenVR.
|
||||
Standard_EXPORT void SetCustomStereoFrustums (const Aspect_FrustumLRBT<Standard_Real>& theFrustumL,
|
||||
const Aspect_FrustumLRBT<Standard_Real>& theFrustumR);
|
||||
|
||||
//! Return TRUE if custom stereo projection matrices are set.
|
||||
bool IsCustomStereoProjection() const { return myIsCustomProjMatLR; }
|
||||
|
||||
//! Set custom stereo projection matrices.
|
||||
Standard_EXPORT void SetCustomStereoProjection (const Graphic3d_Mat4d& theProjL,
|
||||
const Graphic3d_Mat4d& theProjR);
|
||||
|
||||
//! Return TRUE if custom projection matrix is set.
|
||||
bool IsCustomMonoProjection() const { return myIsCustomProjMatM; }
|
||||
|
||||
//! Set custom projection matrix.
|
||||
Standard_EXPORT void SetCustomMonoProjection (const Graphic3d_Mat4d& theProj);
|
||||
|
||||
//! Dumps the content of me into the stream
|
||||
Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
|
||||
|
||||
@ -572,68 +635,44 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
//! Compose orthographic projection matrix for
|
||||
//! the passed camera volume mapping.
|
||||
//! @param theLeft [in] the left mapping (clipping) coordinate.
|
||||
//! @param theRight [in] the right mapping (clipping) coordinate.
|
||||
//! @param theBottom [in] the bottom mapping (clipping) coordinate.
|
||||
//! @param theTop [in] the top mapping (clipping) coordinate.
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate.
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate.
|
||||
//! @param theOutMx [out] the projection matrix.
|
||||
//! Compose orthographic projection matrix for the passed camera volume mapping.
|
||||
//! @param theOutMx [out] the projection matrix
|
||||
//! @param theLRBT [in] the left/right/bottom/top mapping (clipping) coordinates
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate
|
||||
template <typename Elem_t>
|
||||
static void
|
||||
OrthoProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
NCollection_Mat4<Elem_t>& theOutMx);
|
||||
static void orthoProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar);
|
||||
|
||||
//! Compose perspective projection matrix for
|
||||
//! the passed camera volume mapping.
|
||||
//! @param theLeft [in] the left mapping (clipping) coordinate.
|
||||
//! @param theRight [in] the right mapping (clipping) coordinate.
|
||||
//! @param theBottom [in] the bottom mapping (clipping) coordinate.
|
||||
//! @param theTop [in] the top mapping (clipping) coordinate.
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate.
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate.
|
||||
//! @param theOutMx [out] the projection matrix.
|
||||
//! Compose perspective projection matrix for the passed camera volume mapping.
|
||||
//! @param theOutMx [out] the projection matrix
|
||||
//! @param theLRBT [in] the left/right/bottom/top mapping (clipping) coordinates
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate
|
||||
template <typename Elem_t>
|
||||
static void
|
||||
PerspectiveProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
NCollection_Mat4<Elem_t>& theOutMx);
|
||||
static void perspectiveProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar);
|
||||
|
||||
//! Compose projection matrix for L/R stereo eyes.
|
||||
//! @param theLeft [in] the left mapping (clipping) coordinate.
|
||||
//! @param theRight [in] the right mapping (clipping) coordinate.
|
||||
//! @param theBottom [in] the bottom mapping (clipping) coordinate.
|
||||
//! @param theTop [in] the top mapping (clipping) coordinate.
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate.
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate.
|
||||
//! @param theIOD [in] the Intraocular distance.
|
||||
//! @param theZFocus [in] the z coordinate of off-axis
|
||||
//! projection plane with zero parallax.
|
||||
//! @param theIsLeft [in] boolean flag to choose between L/R eyes.
|
||||
//! @param theOutMx [out] the projection matrix.
|
||||
//! @param theOutMx [out] the projection matrix
|
||||
//! @param theLRBT [in] the left/right/bottom/top mapping (clipping) coordinates
|
||||
//! @param theNear [in] the near mapping (clipping) coordinate
|
||||
//! @param theFar [in] the far mapping (clipping) coordinate
|
||||
//! @param theIOD [in] the Intraocular distance
|
||||
//! @param theZFocus [in] the z coordinate of off-axis projection plane with zero parallax
|
||||
//! @param theEyeIndex [in] choose between L/R eyes
|
||||
template <typename Elem_t>
|
||||
static void
|
||||
StereoEyeProj (const Elem_t theLeft,
|
||||
const Elem_t theRight,
|
||||
const Elem_t theBottom,
|
||||
const Elem_t theTop,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
const Elem_t theIOD,
|
||||
const Elem_t theZFocus,
|
||||
const Standard_Boolean theIsLeft,
|
||||
NCollection_Mat4<Elem_t>& theOutMx);
|
||||
static void stereoEyeProj (NCollection_Mat4<Elem_t>& theOutMx,
|
||||
const Aspect_FrustumLRBT<Elem_t>& theLRBT,
|
||||
const Elem_t theNear,
|
||||
const Elem_t theFar,
|
||||
const Elem_t theIOD,
|
||||
const Elem_t theZFocus,
|
||||
const Aspect_Eye theEyeIndex);
|
||||
|
||||
//! Construct "look at" orientation transformation.
|
||||
//! Reference point differs for perspective and ortho modes
|
||||
@ -684,6 +723,8 @@ private:
|
||||
|
||||
Projection myProjType; //!< Projection type used for rendering.
|
||||
Standard_Real myFOVy; //!< Field Of View in y axis.
|
||||
Standard_Real myFOVx; //!< Field Of View in x axis.
|
||||
Standard_Real myFOV2d; //!< Field Of View limit for 2d on-screen elements
|
||||
Standard_Real myFOVyTan; //!< Field Of View as Tan(DTR_HALF * myFOVy)
|
||||
Standard_Real myZNear; //!< Distance to near clipping plane.
|
||||
Standard_Real myZFar; //!< Distance to far clipping plane.
|
||||
@ -698,6 +739,15 @@ private:
|
||||
|
||||
Graphic3d_CameraTile myTile;//!< Tile defining sub-area for drawing
|
||||
|
||||
Graphic3d_Mat4d myCustomProjMatM;
|
||||
Graphic3d_Mat4d myCustomProjMatL;
|
||||
Graphic3d_Mat4d myCustomProjMatR;
|
||||
Aspect_FrustumLRBT<Standard_Real> myCustomFrustumL; //!< left custom frustum
|
||||
Aspect_FrustumLRBT<Standard_Real> myCustomFrustumR; //!< right custom frustum
|
||||
Standard_Boolean myIsCustomProjMatM; //!< flag indicating usage of custom projection matrix
|
||||
Standard_Boolean myIsCustomProjMatLR; //!< flag indicating usage of custom stereo projection matrices
|
||||
Standard_Boolean myIsCustomFrustomLR; //!< flag indicating usage of custom stereo frustums
|
||||
|
||||
mutable TransformMatrices<Standard_Real> myMatricesD;
|
||||
mutable TransformMatrices<Standard_ShortReal> myMatricesF;
|
||||
|
||||
|
@ -134,8 +134,10 @@ public:
|
||||
WhitePoint (1.f),
|
||||
// stereoscopic parameters
|
||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||
HmdFov2d (30.0f),
|
||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||
ToReverseStereo (Standard_False),
|
||||
ToMirrorComposer (Standard_True),
|
||||
//
|
||||
StatsPosition (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i (20, 20))),
|
||||
ChartPosition (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_RIGHT_UPPER, Graphic3d_Vec2i (20, 20))),
|
||||
@ -225,10 +227,12 @@ public:
|
||||
Standard_ShortReal WhitePoint; //!< white point value used in filmic tone mapping (path tracing), 1.0 by default
|
||||
|
||||
Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
|
||||
Standard_ShortReal HmdFov2d; //!< sharp field of view range in degrees for displaying on-screen 2D elements, 30.0 by default;
|
||||
Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
|
||||
Graphic3d_Mat4 AnaglyphLeft; //!< left anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
|
||||
Graphic3d_Mat4 AnaglyphRight; //!< right anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
|
||||
Standard_Boolean ToReverseStereo; //!< flag to reverse stereo pair, FALSE by default
|
||||
Standard_Boolean ToMirrorComposer; //!< if output device is an external composer - mirror rendering results in window in addition to sending frame to composer, TRUE by default
|
||||
|
||||
Handle(Graphic3d_TransformPers) StatsPosition; //!< location of stats, upper-left position by default
|
||||
Handle(Graphic3d_TransformPers) ChartPosition; //!< location of stats chart, upper-right position by default
|
||||
|
@ -27,6 +27,7 @@ enum Graphic3d_StereoMode
|
||||
Graphic3d_StereoMode_SideBySide, //!< horizontal pair
|
||||
Graphic3d_StereoMode_OverUnder, //!< vertical pair
|
||||
Graphic3d_StereoMode_SoftPageFlip, //!< software PageFlip for shutter glasses, should NOT be used!
|
||||
Graphic3d_StereoMode_OpenVR, //!< OpenVR (HMD)
|
||||
Graphic3d_StereoMode_NB //!< the number of modes
|
||||
};
|
||||
|
||||
|
@ -364,7 +364,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
|
||||
{
|
||||
const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale;
|
||||
const gp_Dir aSide = aForward.Crossed (theCamera->Up());
|
||||
const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * 0.5 - anOffsetX);
|
||||
const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * theCamera->NDC2dOffsetX() - anOffsetX);
|
||||
if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
|
||||
{
|
||||
aCenter += aDeltaX;
|
||||
@ -377,7 +377,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
|
||||
if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
|
||||
{
|
||||
const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale;
|
||||
const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * 0.5 - anOffsetY);
|
||||
const gp_XYZ aDeltaY = theCamera->Up().XYZ() * (Abs(aViewDim.Y()) * theCamera->NDC2dOffsetY() - anOffsetY);
|
||||
if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
|
||||
{
|
||||
aCenter += aDeltaY;
|
||||
@ -408,7 +408,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
|
||||
gp_XYZ aCenter (0.0, 0.0, -aFocus);
|
||||
if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0)
|
||||
{
|
||||
aCenter.SetX (-aViewDim.X() * 0.5 + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
|
||||
aCenter.SetX (-aViewDim.X() * theCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale);
|
||||
if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0)
|
||||
{
|
||||
aCenter.SetX (-aCenter.X());
|
||||
@ -416,7 +416,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera,
|
||||
}
|
||||
if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0)
|
||||
{
|
||||
aCenter.SetY (-aViewDim.Y() * 0.5 + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
|
||||
aCenter.SetY (-aViewDim.Y() * theCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale);
|
||||
if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0)
|
||||
{
|
||||
aCenter.SetY (-aCenter.Y());
|
||||
|
@ -40,10 +40,11 @@ proc Visualization:toolkits { } {
|
||||
;# Autres UDs a prendre.
|
||||
;#
|
||||
proc Visualization:ressources { } {
|
||||
return [list \
|
||||
[list both r Textures {}] \
|
||||
[list both r Shaders {}] \
|
||||
]
|
||||
return [list \
|
||||
[list both r Textures {}] \
|
||||
[list both r Shaders {}] \
|
||||
[list both r XRResources {}] \
|
||||
]
|
||||
}
|
||||
;#
|
||||
;# Nom du module
|
||||
|
@ -4067,6 +4067,22 @@ void OpenGl_Context::SetPolygonOffset (const Graphic3d_PolygonOffset& theOffset)
|
||||
myPolygonOffset = theOffset;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCamera
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Context::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
|
||||
{
|
||||
myCamera = theCamera;
|
||||
if (!theCamera.IsNull())
|
||||
{
|
||||
ProjectionState.SetCurrent (theCamera->ProjectionMatrixF());
|
||||
WorldViewState .SetCurrent (theCamera->OrientationMatrixF());
|
||||
ApplyProjectionMatrix();
|
||||
ApplyWorldViewMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ApplyModelWorldMatrix
|
||||
// purpose :
|
||||
|
@ -136,6 +136,7 @@ template<typename theBaseClass_t> struct OpenGl_TmplCore45;
|
||||
typedef OpenGl_TmplCore45<OpenGl_GlCore44Back> OpenGl_GlCore45Back;
|
||||
typedef OpenGl_TmplCore45<OpenGl_GlCore44> OpenGl_GlCore45;
|
||||
|
||||
class Graphic3d_Camera;
|
||||
class Graphic3d_PresentationAttributes;
|
||||
class OpenGl_Aspects;
|
||||
class OpenGl_FrameBuffer;
|
||||
@ -678,6 +679,12 @@ public:
|
||||
//! Returns currently applied polygon offset parameters.
|
||||
const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; }
|
||||
|
||||
//! Returns camera object.
|
||||
const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
|
||||
|
||||
//! Sets camera object to the context and update matrices.
|
||||
Standard_EXPORT void SetCamera (const Handle(Graphic3d_Camera)& theCamera);
|
||||
|
||||
//! Applies matrix into shader manager stored in ModelWorldState to OpenGl.
|
||||
//! In "model -> world -> view -> projection" it performs:
|
||||
//! model -> world
|
||||
@ -1143,6 +1150,7 @@ private: // context info
|
||||
|
||||
private: //! @name fields tracking current state
|
||||
|
||||
Handle(Graphic3d_Camera) myCamera; //!< active camera object
|
||||
Handle(OpenGl_FrameStats) myFrameStats; //!< structure accumulating frame statistics
|
||||
Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program
|
||||
Handle(OpenGl_TextureSet) myActiveTextures; //!< currently bound textures
|
||||
|
@ -389,7 +389,7 @@ void OpenGl_FrameStatsPrs::Render (const Handle(OpenGl_Workspace)& theWorkspace)
|
||||
aCtx->WorldViewState.Push();
|
||||
if (!myCountersTrsfPers.IsNull())
|
||||
{
|
||||
myCountersTrsfPers->Apply (theWorkspace->View()->Camera(),
|
||||
myCountersTrsfPers->Apply (aCtx->Camera(),
|
||||
aCtx->ProjectionState.Current(), aCtx->WorldViewState.ChangeCurrent(),
|
||||
aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theW
|
||||
const Standard_Integer aHeight = theWorkspace->Height();
|
||||
|
||||
// Take into account Transform Persistence
|
||||
aContext->ModelWorldState.SetCurrent (aTransMode.Compute (theWorkspace->View()->Camera(), aProjection, aWorldView, aWidth, aHeight));
|
||||
aContext->ModelWorldState.SetCurrent (aTransMode.Compute (aContext->Camera(), aProjection, aWorldView, aWidth, aHeight));
|
||||
aContext->ApplyModelViewMatrix();
|
||||
|
||||
anAxis.Arrow.Render (theWorkspace);
|
||||
|
@ -2979,6 +2979,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
}
|
||||
case Graphic3d_StereoMode_QuadBuffer:
|
||||
case Graphic3d_StereoMode_SoftPageFlip:
|
||||
case Graphic3d_StereoMode_OpenVR:
|
||||
default:
|
||||
{
|
||||
/*const Handle(OpenGl_ShaderProgram)& aProgram = myStereoPrograms[Graphic3d_StereoMode_QuadBuffer];
|
||||
|
@ -439,7 +439,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
|
||||
{
|
||||
aCtx->WorldViewState.Push();
|
||||
OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
|
||||
myTrsfPers->Apply (theWorkspace->View()->Camera(),
|
||||
myTrsfPers->Apply (aCtx->Camera(),
|
||||
aCtx->ProjectionState.Current(), aWorldView,
|
||||
aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
|
||||
|
||||
|
@ -333,7 +333,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
|
||||
|
||||
if (myText->HasPlane() && myText->HasOwnAnchorPoint())
|
||||
{
|
||||
myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
|
||||
myOrientationMatrix = aCtx->Camera()->OrientationMatrix();
|
||||
// reset translation part
|
||||
myOrientationMatrix.ChangeValue (0, 3) = 0.0;
|
||||
myOrientationMatrix.ChangeValue (1, 3) = 0.0;
|
||||
|
@ -61,6 +61,7 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
|
||||
myFboColorFormat (GL_SRGB8_ALPHA8), // note that GL_SRGB8 is not required to be renderable, unlike GL_RGB8, GL_RGBA8, GL_SRGB8_ALPHA8
|
||||
myFboDepthFormat (GL_DEPTH24_STENCIL8),
|
||||
myToFlipOutput (Standard_False),
|
||||
//
|
||||
myFrameCounter (0),
|
||||
myHasFboBlit (Standard_True),
|
||||
myToDisableOIT (Standard_False),
|
||||
@ -111,6 +112,7 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
|
||||
myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
|
||||
myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
|
||||
myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
|
||||
myXrSceneFbo = new OpenGl_FrameBuffer();
|
||||
myOpenGlFBO = new OpenGl_FrameBuffer();
|
||||
myOpenGlFBO2 = new OpenGl_FrameBuffer();
|
||||
myRaytraceFBO1[0] = new OpenGl_FrameBuffer();
|
||||
@ -182,6 +184,7 @@ void OpenGl_View::releaseSrgbResources (const Handle(OpenGl_Context)& theCtx)
|
||||
myImmediateSceneFbos[1] ->Release (theCtx.get());
|
||||
myImmediateSceneFbosOit[0]->Release (theCtx.get());
|
||||
myImmediateSceneFbosOit[1]->Release (theCtx.get());
|
||||
myXrSceneFbo ->Release (theCtx.get());
|
||||
myOpenGlFBO ->Release (theCtx.get());
|
||||
myOpenGlFBO2 ->Release (theCtx.get());
|
||||
myFullScreenQuad .Release (theCtx.get());
|
||||
@ -209,6 +212,7 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
|
||||
{
|
||||
myPBREnvironment->Release (theCtx.get());
|
||||
}
|
||||
ReleaseXR();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@ -826,6 +830,7 @@ void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructu
|
||||
void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
|
||||
Graphic3d_DiagnosticInfo theFlags) const
|
||||
{
|
||||
base_type::DiagnosticInformation (theDict, theFlags);
|
||||
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
|
||||
if (!myWorkspace->Activate()
|
||||
|| aCtx.IsNull())
|
||||
|
@ -523,6 +523,7 @@ protected: //! @name Rendering properties
|
||||
Handle(OpenGl_FrameBuffer) myMainSceneFbosOit[2]; //!< Additional buffers for transparent draw of main layer.
|
||||
Handle(OpenGl_FrameBuffer) myImmediateSceneFbos[2]; //!< Additional buffers for immediate layer in stereo mode.
|
||||
Handle(OpenGl_FrameBuffer) myImmediateSceneFbosOit[2]; //!< Additional buffers for transparency draw of immediate layer.
|
||||
Handle(OpenGl_FrameBuffer) myXrSceneFbo; //!< additional FBO (without MSAA) for submitting to XR
|
||||
OpenGl_VertexBuffer myFullScreenQuad; //!< Vertices for full-screen quad rendering.
|
||||
OpenGl_VertexBuffer myFullScreenQuadFlip;
|
||||
Standard_Boolean myToFlipOutput; //!< Flag to draw result image upside-down
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <OpenGl_GlCore11.hxx>
|
||||
|
||||
#include <Aspect_XRSession.hxx>
|
||||
#include <Graphic3d_GraphicDriver.hxx>
|
||||
#include <Graphic3d_StructureManager.hxx>
|
||||
#include <Graphic3d_TextureParams.hxx>
|
||||
@ -158,7 +159,8 @@ void OpenGl_View::Redraw()
|
||||
return;
|
||||
}
|
||||
|
||||
myWindow->SetSwapInterval();
|
||||
// implicitly disable VSync when using HMD composer (can be mirrored in window for debugging)
|
||||
myWindow->SetSwapInterval (IsActiveXR());
|
||||
|
||||
++myFrameCounter;
|
||||
const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
|
||||
@ -186,10 +188,22 @@ void OpenGl_View::Redraw()
|
||||
OpenGl_FrameBuffer* aFrameBuffer = myFBO.get();
|
||||
bool toSwap = aCtx->IsRender()
|
||||
&& !aCtx->caps->buffersNoSwap
|
||||
&& aFrameBuffer == NULL;
|
||||
&& aFrameBuffer == NULL
|
||||
&& (!IsActiveXR() || myRenderParams.ToMirrorComposer);
|
||||
|
||||
Standard_Integer aSizeX = myWindow->Width();
|
||||
Standard_Integer aSizeY = myWindow->Height();
|
||||
if (aFrameBuffer != NULL)
|
||||
{
|
||||
aSizeX = aFrameBuffer->GetVPSizeX();
|
||||
aSizeY = aFrameBuffer->GetVPSizeY();
|
||||
}
|
||||
else if (IsActiveXR())
|
||||
{
|
||||
aSizeX = myXRSession->RecommendedViewport().x();
|
||||
aSizeY = myXRSession->RecommendedViewport().y();
|
||||
}
|
||||
|
||||
const Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWindow->Width();
|
||||
const Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myWindow->Height();
|
||||
const Standard_Integer aRendSizeX = Standard_Integer(myRenderParams.RenderResolutionScale * aSizeX + 0.5f);
|
||||
const Standard_Integer aRendSizeY = Standard_Integer(myRenderParams.RenderResolutionScale * aSizeY + 0.5f);
|
||||
if (aSizeX < 1
|
||||
@ -275,14 +289,33 @@ void OpenGl_View::Redraw()
|
||||
myMainSceneFbos [1]->Release (aCtx.operator->());
|
||||
myImmediateSceneFbos[0]->Release (aCtx.operator->());
|
||||
myImmediateSceneFbos[1]->Release (aCtx.operator->());
|
||||
myXrSceneFbo ->Release (aCtx.operator->());
|
||||
myMainSceneFbos [0]->ChangeViewport (0, 0);
|
||||
myMainSceneFbos [1]->ChangeViewport (0, 0);
|
||||
myImmediateSceneFbos[0]->ChangeViewport (0, 0);
|
||||
myImmediateSceneFbos[1]->ChangeViewport (0, 0);
|
||||
myXrSceneFbo ->ChangeViewport (0, 0);
|
||||
}
|
||||
|
||||
bool hasXRBlitFbo = false;
|
||||
if (aProjectType == Graphic3d_Camera::Projection_Stereo
|
||||
&& IsActiveXR()
|
||||
&& myMainSceneFbos[0]->IsValid())
|
||||
{
|
||||
if (aNbSamples != 0
|
||||
|| aSizeX != aRendSizeX)
|
||||
{
|
||||
hasXRBlitFbo = myXrSceneFbo->InitLazy (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, 0);
|
||||
if (!hasXRBlitFbo)
|
||||
{
|
||||
TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! VR FBO "
|
||||
+ printFboFormat (myXrSceneFbo) + " initialization has failed";
|
||||
aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aProjectType == Graphic3d_Camera::Projection_Stereo
|
||||
&& myMainSceneFbos[0]->IsValid())
|
||||
{
|
||||
const bool wasFailedMain1 = checkWasFailedFbo (myMainSceneFbos[1], myMainSceneFbos[0]);
|
||||
if (!myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0])
|
||||
@ -326,6 +359,11 @@ void OpenGl_View::Redraw()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasXRBlitFbo)
|
||||
{
|
||||
myXrSceneFbo->Release (aCtx.get());
|
||||
myXrSceneFbo->ChangeViewport (0, 0);
|
||||
}
|
||||
|
||||
// process PBR environment
|
||||
if (myShadingModel == Graphic3d_TOSM_PBR
|
||||
@ -500,7 +538,18 @@ void OpenGl_View::Redraw()
|
||||
myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL
|
||||
};
|
||||
|
||||
if (!myTransientDrawToFront)
|
||||
if (IsActiveXR())
|
||||
{
|
||||
// use single frame for both views - caching main scene content makes no sense
|
||||
// when head position is expected to be updated each frame redraw with high accuracy
|
||||
aMainFbos[1] = aMainFbos[0];
|
||||
aMainFbosOit[1] = aMainFbosOit[0];
|
||||
anImmFbos[0] = aMainFbos[0];
|
||||
anImmFbos[1] = aMainFbos[1];
|
||||
anImmFbosOit[0] = aMainFbosOit[0];
|
||||
anImmFbosOit[1] = aMainFbosOit[1];
|
||||
}
|
||||
else if (!myTransientDrawToFront)
|
||||
{
|
||||
anImmFbos [0] = aMainFbos [0];
|
||||
anImmFbos [1] = aMainFbos [1];
|
||||
@ -539,6 +588,23 @@ void OpenGl_View::Redraw()
|
||||
aCtx->SwapBuffers();
|
||||
}
|
||||
|
||||
if (IsActiveXR())
|
||||
{
|
||||
// push Left frame to HMD display composer
|
||||
OpenGl_FrameBuffer* anXRFbo = hasXRBlitFbo ? myXrSceneFbo.get() : aMainFbos[0];
|
||||
if (anXRFbo != aMainFbos[0])
|
||||
{
|
||||
blitBuffers (aMainFbos[0], anXRFbo); // resize or resolve MSAA samples
|
||||
}
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGL;
|
||||
#else
|
||||
const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGLES;
|
||||
#endif
|
||||
myXRSession->SubmitEye ((void* )(size_t )anXRFbo->ColorTexture()->TextureId(),
|
||||
aGraphicsLib, Aspect_ColorSpace_sRGB, Aspect_Eye_Left);
|
||||
}
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
|
||||
#endif
|
||||
@ -555,7 +621,29 @@ void OpenGl_View::Redraw()
|
||||
toSwap = false;
|
||||
}
|
||||
|
||||
if (anImmFbos[0] != NULL)
|
||||
if (IsActiveXR())
|
||||
{
|
||||
// push Right frame to HMD display composer
|
||||
OpenGl_FrameBuffer* anXRFbo = hasXRBlitFbo ? myXrSceneFbo.get() : aMainFbos[1];
|
||||
if (anXRFbo != aMainFbos[1])
|
||||
{
|
||||
blitBuffers (aMainFbos[1], anXRFbo); // resize or resolve MSAA samples
|
||||
}
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGL;
|
||||
#else
|
||||
const Aspect_GraphicsLibrary aGraphicsLib = Aspect_GraphicsLibrary_OpenGLES;
|
||||
#endif
|
||||
myXRSession->SubmitEye ((void* )(size_t )anXRFbo->ColorTexture()->TextureId(),
|
||||
aGraphicsLib, Aspect_ColorSpace_sRGB, Aspect_Eye_Right);
|
||||
::glFinish();
|
||||
|
||||
if (myRenderParams.ToMirrorComposer)
|
||||
{
|
||||
blitBuffers (anXRFbo, aFrameBuffer, myToFlipOutput);
|
||||
}
|
||||
}
|
||||
else if (anImmFbos[0] != NULL)
|
||||
{
|
||||
aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), 1.0f);
|
||||
drawStereoPair (aFrameBuffer);
|
||||
@ -657,6 +745,7 @@ void OpenGl_View::RedrawImmediate()
|
||||
if (!myWorkspace->Activate())
|
||||
return;
|
||||
|
||||
// no special handling of HMD display, since it will force full Redraw() due to no frame caching (myBackBufferRestored)
|
||||
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
|
||||
if (!myTransientDrawToFront
|
||||
|| !myBackBufferRestored
|
||||
@ -872,9 +961,11 @@ bool OpenGl_View::redrawImmediate (const Graphic3d_Camera::Projection theProject
|
||||
const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
|
||||
GLboolean toCopyBackToFront = GL_FALSE;
|
||||
if (theDrawFbo == theReadFbo
|
||||
&& theDrawFbo != NULL)
|
||||
&& theDrawFbo != NULL
|
||||
&& theDrawFbo->IsValid())
|
||||
{
|
||||
myBackBufferRestored = Standard_False;
|
||||
theDrawFbo->BindBuffer (aCtx);
|
||||
}
|
||||
else if (theReadFbo != NULL
|
||||
&& theReadFbo->IsValid()
|
||||
@ -993,10 +1084,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
}
|
||||
|
||||
myLocalOrigin.SetCoord (0.0, 0.0, 0.0);
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
|
||||
aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
aContext->SetCamera (myCamera);
|
||||
if (aManager->ModelWorldState().Index() == 0)
|
||||
{
|
||||
aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
|
||||
@ -1042,7 +1130,7 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
// if the view is scaled normal vectors are scaled to unit
|
||||
// length for correct displaying of shaded objects
|
||||
const gp_Pnt anAxialScale = myCamera->AxialScale();
|
||||
const gp_Pnt anAxialScale = aContext->Camera()->AxialScale();
|
||||
if (anAxialScale.X() != 1.F ||
|
||||
anAxialScale.Y() != 1.F ||
|
||||
anAxialScale.Z() != 1.F)
|
||||
@ -1060,12 +1148,12 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
|
||||
// Redraw 3d scene
|
||||
if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
|
||||
{
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
|
||||
aContext->ProjectionState.SetCurrent (aContext->Camera()->ProjectionStereoLeftF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
}
|
||||
else if (theProjection == Graphic3d_Camera::Projection_MonoRightEye)
|
||||
{
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
|
||||
aContext->ProjectionState.SetCurrent (aContext->Camera()->ProjectionStereoRightF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
}
|
||||
|
||||
|
@ -809,11 +809,12 @@ void OpenGl_Window::Init()
|
||||
// function : SetSwapInterval
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Window::SetSwapInterval()
|
||||
void OpenGl_Window::SetSwapInterval (Standard_Boolean theToForceNoSync)
|
||||
{
|
||||
if (mySwapInterval != myGlContext->caps->swapInterval)
|
||||
const Standard_Integer aSwapInterval = theToForceNoSync ? 0 : myGlContext->caps->swapInterval;
|
||||
if (mySwapInterval != aSwapInterval)
|
||||
{
|
||||
mySwapInterval = myGlContext->caps->swapInterval;
|
||||
mySwapInterval = aSwapInterval;
|
||||
myGlContext->SetSwapInterval (mySwapInterval);
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
Standard_EXPORT virtual Standard_Boolean Activate();
|
||||
|
||||
//! Sets swap interval for this window according to the context's settings.
|
||||
Standard_EXPORT void SetSwapInterval();
|
||||
Standard_EXPORT void SetSwapInterval (Standard_Boolean theToForceNoSync);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -390,11 +390,12 @@ void OpenGl_Window::Init()
|
||||
// function : SetSwapInterval
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Window::SetSwapInterval()
|
||||
void OpenGl_Window::SetSwapInterval (Standard_Boolean theToForceNoSync)
|
||||
{
|
||||
if (mySwapInterval != myGlContext->caps->swapInterval)
|
||||
const Standard_Integer aSwapInterval = theToForceNoSync ? 0 : myGlContext->caps->swapInterval;
|
||||
if (mySwapInterval != aSwapInterval)
|
||||
{
|
||||
mySwapInterval = myGlContext->caps->swapInterval;
|
||||
mySwapInterval = aSwapInterval;
|
||||
myGlContext->SetSwapInterval (mySwapInterval);
|
||||
}
|
||||
}
|
||||
|
@ -85,15 +85,18 @@ public:
|
||||
//! Empties all the tables, removes all selections...
|
||||
Standard_EXPORT void Clear();
|
||||
|
||||
//! returns the Sensitivity of picking
|
||||
Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
|
||||
|
||||
//! Returns the pixel tolerance.
|
||||
Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
|
||||
//! Returns custom pixel tolerance value.
|
||||
Standard_Integer CustomPixelTolerance() const { return myTolerances.CustomTolerance(); }
|
||||
|
||||
//! Sets the pixel tolerance <theTolerance>.
|
||||
Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
|
||||
|
||||
//! Returns the largest sensitivity of picking
|
||||
Standard_Real Sensitivity() const { return myTolerances.Tolerance(); }
|
||||
|
||||
//! Returns the largest pixel tolerance.
|
||||
Standard_Integer PixelTolerance() const { return myTolerances.Tolerance(); }
|
||||
|
||||
//! Sorts the detected entites by priority and distance.
|
||||
//! to be redefined if other criterion are used...
|
||||
Standard_EXPORT void SortResult();
|
||||
|
@ -2,6 +2,7 @@ TKernel
|
||||
TKMath
|
||||
CSF_user32
|
||||
CSF_advapi32
|
||||
CSF_OpenVR
|
||||
CSF_OpenGlLibs
|
||||
CSF_advapi32
|
||||
CSF_user32
|
||||
|
@ -233,6 +233,7 @@ void V3d_View::Update() const
|
||||
myIsInvalidatedImmediate = Standard_False;
|
||||
myView->Update();
|
||||
myView->Compute();
|
||||
AutoZFit();
|
||||
myView->Redraw();
|
||||
}
|
||||
|
||||
@ -618,8 +619,6 @@ void V3d_View::SetFront()
|
||||
|
||||
aCamera->SetUp (gp_Dir (xu, yu, zu));
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SwitchSetFront = !SwitchSetFront;
|
||||
|
||||
ImmediateUpdate();
|
||||
@ -675,8 +674,6 @@ void V3d_View::Rotate (const Standard_Real ax,
|
||||
|
||||
aCamera->Transform (aTrsf);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -733,8 +730,6 @@ void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Stan
|
||||
|
||||
aCamera->Transform (aTrsf);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -803,8 +798,6 @@ void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
|
||||
|
||||
aCamera->Transform (aRotation);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -840,8 +833,6 @@ void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
|
||||
|
||||
aCamera->Transform (aRotation);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -892,8 +883,6 @@ void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standa
|
||||
|
||||
aCamera->Transform (aTrsf);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -948,8 +937,6 @@ void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
|
||||
|
||||
aCamera->Transform (aRotation);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -983,8 +970,6 @@ void V3d_View::SetTwist(const Standard_Real angle)
|
||||
aCamera->SetUp (gp_Dir (myYscreenAxis));
|
||||
aCamera->Transform (aTrsf);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1004,8 +989,6 @@ void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard
|
||||
|
||||
SetTwist (aTwistBefore);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SetImmediateUpdate (wasUpdateEnabled);
|
||||
|
||||
ImmediateUpdate();
|
||||
@ -1036,8 +1019,6 @@ void V3d_View::SetDepth(const Standard_Real Depth)
|
||||
aCamera->SetCenter (aCameraCenter);
|
||||
}
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1058,8 +1039,6 @@ void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Sta
|
||||
|
||||
SetTwist(aTwistBefore);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SetImmediateUpdate (wasUpdateEnabled);
|
||||
|
||||
ImmediateUpdate();
|
||||
@ -1108,8 +1087,6 @@ void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
|
||||
|
||||
Panning (anOriginVCS.X(), anOriginVCS.Y());
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1127,8 +1104,6 @@ void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_
|
||||
|
||||
SetTwist (aTwistBefore);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SetImmediateUpdate (wasUpdateEnabled);
|
||||
|
||||
ImmediateUpdate();
|
||||
@ -1154,8 +1129,6 @@ void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, cons
|
||||
|
||||
aCamera->SetUp (gp_Dir (myYscreenAxis));
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1179,8 +1152,6 @@ void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
|
||||
|
||||
aCamera->SetUp (gp_Dir (myYscreenAxis));
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1209,9 +1180,6 @@ void V3d_View::SetViewMappingDefault()
|
||||
void V3d_View::ResetViewOrientation()
|
||||
{
|
||||
Camera()->CopyOrientationData (myDefaultCamera);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1222,9 +1190,6 @@ void V3d_View::ResetViewOrientation()
|
||||
void V3d_View::ResetViewMapping()
|
||||
{
|
||||
Camera()->CopyMappingData (myDefaultCamera);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1236,8 +1201,6 @@ void V3d_View::Reset (const Standard_Boolean theToUpdate)
|
||||
{
|
||||
Camera()->Copy (myDefaultCamera);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SwitchSetFront = Standard_False;
|
||||
|
||||
if (myImmediateUpdate || theToUpdate)
|
||||
@ -1272,8 +1235,6 @@ void V3d_View::SetSize (const Standard_Real theSize)
|
||||
|
||||
aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1375,8 +1336,6 @@ void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theTo
|
||||
aCamera->SetCenter (myCamStartOpCenter);
|
||||
aCamera->SetScale (aCamera->Scale() / aCoef);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1394,8 +1353,6 @@ void V3d_View::SetScale( const Standard_Real Coef )
|
||||
aCamera->SetAspect (myDefaultCamera->Aspect());
|
||||
aCamera->SetScale (aDefaultScale / Coef);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -1408,8 +1365,6 @@ void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, co
|
||||
V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
|
||||
|
||||
Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
|
||||
|
||||
AutoZFit();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@ -1463,8 +1418,6 @@ void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, con
|
||||
return;
|
||||
}
|
||||
|
||||
AutoZFit();
|
||||
|
||||
if (myImmediateUpdate || theToUpdate)
|
||||
{
|
||||
Update();
|
||||
@ -1588,7 +1541,6 @@ void V3d_View::WindowFit (const Standard_Integer theMinXp,
|
||||
|
||||
Translate (aCamera, aPanVec.X(), -aPanVec.Y());
|
||||
Scale (aCamera, aUSize, aVSize);
|
||||
AutoZFit();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2491,8 +2443,6 @@ void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
|
||||
aCamera->SetScale (aCamera->Scale() / aCoef);
|
||||
Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
SetImmediateUpdate (wasUpdateEnabled);
|
||||
|
||||
ImmediateUpdate();
|
||||
@ -2545,8 +2495,6 @@ void V3d_View::FitAll(const Standard_Real theXmin,
|
||||
Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
|
||||
Scale (aCamera, aFitSizeU, aFitSizeV);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -2828,7 +2776,6 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
|
||||
{
|
||||
aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
|
||||
}
|
||||
AutoZFit();
|
||||
|
||||
// render immediate structures into back buffer rather than front
|
||||
const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
|
||||
|
@ -67,8 +67,6 @@ void V3d_View::Move (const Standard_Real Dx,
|
||||
+ Dz * gp_Pnt (ZX, ZY, ZZ).XYZ()
|
||||
);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -86,8 +84,6 @@ void V3d_View::Move (const Standard_Real theLength, const Standard_Boolean theSt
|
||||
aCamera->SetEye (myCamStartOpEye);
|
||||
aCamera->SetEye (aCamera->Eye().XYZ() + theLength * myDefaultViewAxis.XYZ());
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -149,8 +145,6 @@ void V3d_View::Translate (const Standard_Real Dx,
|
||||
- Dz * myZscreenAxis.XYZ()
|
||||
);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
||||
@ -205,7 +199,5 @@ void V3d_View::Translate (const Standard_Real theLength, const Standard_Boolean
|
||||
gp_Pnt aNewCenter (myCamStartOpCenter.XYZ() - myDefaultViewAxis.XYZ() * theLength);
|
||||
aCamera->SetCenter (aNewCenter);
|
||||
|
||||
AutoZFit();
|
||||
|
||||
ImmediateUpdate();
|
||||
}
|
||||
|
@ -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"
|
||||
|
9
src/XRResources/FILES
Normal file
9
src/XRResources/FILES
Normal file
@ -0,0 +1,9 @@
|
||||
srcinc:::occtvr_actions.json
|
||||
srcinc:::occtvr_bindings_generic.json
|
||||
srcinc:::occtvr_bindings_holographic_hmd.json
|
||||
srcinc:::occtvr_bindings_index_hmd.json
|
||||
srcinc:::occtvr_bindings_rift.json
|
||||
srcinc:::occtvr_bindings_vive.json
|
||||
srcinc:::occtvr_bindings_vive_controller.json
|
||||
srcinc:::occtvr_bindings_vive_cosmos.json
|
||||
srcinc:::occtvr_bindings_vive_pro.json
|
225
src/XRResources/occtvr_actions.json
Normal file
225
src/XRResources/occtvr_actions.json
Normal file
@ -0,0 +1,225 @@
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"name": "/actions/generic_head/in/headset_on_head",
|
||||
"type": "boolean",
|
||||
"requirement": "optional"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/pose_base",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/pose_base",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/pose_front",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/pose_front",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/pose_handgrip",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/pose_handgrip",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/pose_tip",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/pose_tip",
|
||||
"type": "pose"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/out/haptic",
|
||||
"type": "vibration"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/out/haptic",
|
||||
"type": "vibration"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/appmenu_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/appmenu_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/sysmenu_click",
|
||||
"type": "boolean",
|
||||
"requirement": "optional"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/sysmenu_click",
|
||||
"type": "boolean",
|
||||
"requirement": "optional"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/trigger_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/trigger_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/trigger_pull",
|
||||
"type": "vector1"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/trigger_pull",
|
||||
"type": "vector1"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/grip_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/grip_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/trackpad_position",
|
||||
"type": "vector2"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/trackpad_position",
|
||||
"type": "vector2"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/trackpad_touch",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/trackpad_touch",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/trackpad_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/trackpad_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/thumbstick_position",
|
||||
"type": "vector2"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/thumbstick_position",
|
||||
"type": "vector2"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/thumbstick_touch",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/thumbstick_touch",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left/in/thumbstick_click",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right/in/thumbstick_click",
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"action_sets": [
|
||||
{
|
||||
"name": "/actions/generic_head",
|
||||
"usage": "single"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_left",
|
||||
"usage": "leftright"
|
||||
},
|
||||
{
|
||||
"name": "/actions/generic_right",
|
||||
"usage": "leftright"
|
||||
}
|
||||
],
|
||||
"default_bindings": [
|
||||
{
|
||||
"controller_type": "vive_controller",
|
||||
"binding_url": "occtvr_bindings_vive_controller.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "generic",
|
||||
"binding_url": "occtvr_bindings_generic.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "holographic_controller",
|
||||
"binding_url": "occtvr_bindings_holographic_hmd.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "indexhmd",
|
||||
"binding_url": "occtvr_bindings_index_hmd.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "rift",
|
||||
"binding_url": "occtvr_bindings_rift.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "vive",
|
||||
"binding_url": "occtvr_bindings_vive.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "vive_cosmos",
|
||||
"binding_url": "occtvr_bindings_vive_cosmos.json"
|
||||
},
|
||||
{
|
||||
"controller_type": "vive_pro",
|
||||
"binding_url": "occtvr_bindings_vive_pro.json"
|
||||
}
|
||||
],
|
||||
"localization": [
|
||||
{
|
||||
"language_tag": "en_US",
|
||||
"/actions/generic_head/in/headset_on_head": "Headset is on head",
|
||||
"/actions/generic_left/in/appmenu_click": "Left app menu",
|
||||
"/actions/generic_left/in/sysmenu_click": "Left system menu",
|
||||
"/actions/generic_left/in/trigger_click": "Left trigger click",
|
||||
"/actions/generic_left/in/trigger_pull": "Left trigger squeeze",
|
||||
"/actions/generic_left/in/grip_click": "Left hand full grip",
|
||||
"/actions/generic_left/in/pose_base": "Left hand base",
|
||||
"/actions/generic_left/in/pose_front": "Left hand front",
|
||||
"/actions/generic_left/in/pose_handgrip": "Left handgrip pose",
|
||||
"/actions/generic_left/in/pose_tip": "Left forefinger tip",
|
||||
"/actions/generic_left/in/trackpad_position": "Left trackpad position",
|
||||
"/actions/generic_left/in/trackpad_touch": "Left trackpad touch",
|
||||
"/actions/generic_left/in/trackpad_click": "Left trackpad click",
|
||||
"/actions/generic_left/in/thumbstick_position": "Left thumbstick position",
|
||||
"/actions/generic_left/in/thumbstick_touch": "Left thumbstick touch",
|
||||
"/actions/generic_left/in/thumbstick_click": "Left thumbstick click",
|
||||
"/actions/generic_left/out/haptic": "Left hand haptic",
|
||||
"/actions/generic_right/in/appmenu_click": "Right app menu",
|
||||
"/actions/generic_right/in/sysmenu_click": "Right system menu",
|
||||
"/actions/generic_right/in/trigger_click": "Right trigger click",
|
||||
"/actions/generic_right/in/trigger_pull": "Right trigger squeeze",
|
||||
"/actions/generic_right/in/grip_click": "Right hand full grip",
|
||||
"/actions/generic_right/in/pose_base": "Right hand base",
|
||||
"/actions/generic_right/in/pose_front": "Right hand front",
|
||||
"/actions/generic_right/in/pose_handgrip": "Right handgrip pose",
|
||||
"/actions/generic_right/in/pose_tip": "Right forefinger tip",
|
||||
"/actions/generic_right/in/trackpad_position": "Right trackpad position",
|
||||
"/actions/generic_right/in/trackpad_touch": "Right trackpad touch",
|
||||
"/actions/generic_right/in/trackpad_click": "Right trackpad click",
|
||||
"/actions/generic_right/in/thumbstick_position": "Right thumbstick position",
|
||||
"/actions/generic_right/in/thumbstick_touch": "Right thumbstick touch",
|
||||
"/actions/generic_right/in/thumbstick_click": "Right thumbstick click",
|
||||
"/actions/generic_right/out/haptic": "Right hand haptic"
|
||||
}
|
||||
]
|
||||
}
|
87
src/XRResources/occtvr_bindings_generic.json
Normal file
87
src/XRResources/occtvr_bindings_generic.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_left": {
|
||||
"haptics": [
|
||||
{
|
||||
"output": "/actions/generic_left/out/haptic",
|
||||
"path": "/user/hand/left/output/haptic"
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/appmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/application_menu"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/trigger_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/trigger"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/trackpad_click" },
|
||||
"touch": { "output": "/actions/generic_left/in/trackpad_touch" },
|
||||
"position": { "output": "/actions/generic_left/in/trackpad_position" }
|
||||
},
|
||||
"mode": "trackpad",
|
||||
"path": "/user/hand/left/input/trackpad"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/grip_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/grip"
|
||||
}
|
||||
]
|
||||
},
|
||||
"/actions/generic_right": {
|
||||
"haptics": [
|
||||
{
|
||||
"output": "/actions/generic_right/out/haptic",
|
||||
"path": "/user/hand/right/output/haptic"
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/appmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/application_menu"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/trigger_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/trigger"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/trackpad_click" },
|
||||
"touch": { "output": "/actions/generic_right/in/trackpad_touch" },
|
||||
"position": { "output": "/actions/generic_right/in/trackpad_position" }
|
||||
},
|
||||
"mode": "trackpad",
|
||||
"path": "/user/hand/right/input/trackpad"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/grip_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/grip"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "generic",
|
||||
"description": "Standard Open CASCADE Technology VR bindings for a generic controller",
|
||||
"name": "OCCT VR bindings for a generic controller"
|
||||
}
|
18
src/XRResources/occtvr_bindings_holographic_hmd.json
Normal file
18
src/XRResources/occtvr_bindings_holographic_hmd.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "holographic_hmd",
|
||||
"description": "",
|
||||
"name": "holographic_hmd defaults"
|
||||
}
|
18
src/XRResources/occtvr_bindings_index_hmd.json
Normal file
18
src/XRResources/occtvr_bindings_index_hmd.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "indexhmd",
|
||||
"description": "",
|
||||
"name": "index hmd defaults"
|
||||
}
|
18
src/XRResources/occtvr_bindings_rift.json
Normal file
18
src/XRResources/occtvr_bindings_rift.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "rift",
|
||||
"description": "",
|
||||
"name": "rift defaults"
|
||||
}
|
18
src/XRResources/occtvr_bindings_vive.json
Normal file
18
src/XRResources/occtvr_bindings_vive.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "vive",
|
||||
"description": "",
|
||||
"name": "vive defaults"
|
||||
}
|
139
src/XRResources/occtvr_bindings_vive_controller.json
Normal file
139
src/XRResources/occtvr_bindings_vive_controller.json
Normal file
@ -0,0 +1,139 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_left": {
|
||||
"haptics": [
|
||||
{
|
||||
"output": "/actions/generic_left/out/haptic",
|
||||
"path": "/user/hand/left/output/haptic"
|
||||
}
|
||||
],
|
||||
"poses": [
|
||||
{
|
||||
"output": "/actions/generic_left/in/pose_base",
|
||||
"path": "/user/hand/left/pose/base"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_left/in/pose_front",
|
||||
"path": "/user/hand/left/pose/front"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_left/in/pose_handgrip",
|
||||
"path": "/user/hand/left/pose/handgrip"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_left/in/pose_tip",
|
||||
"path": "/user/hand/left/pose/tip"
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/appmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/application_menu"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/trigger_click" },
|
||||
"pull": { "output": "/actions/generic_left/in/trigger_pull" }
|
||||
},
|
||||
"mode": "trigger",
|
||||
"path": "/user/hand/left/input/trigger"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/trackpad_click" },
|
||||
"touch": { "output": "/actions/generic_left/in/trackpad_touch" },
|
||||
"position": { "output": "/actions/generic_left/in/trackpad_position" }
|
||||
},
|
||||
"mode": "trackpad",
|
||||
"path": "/user/hand/left/input/trackpad"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/grip_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/grip"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_left/in/sysmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/left/input/system"
|
||||
}
|
||||
]
|
||||
},
|
||||
"/actions/generic_right": {
|
||||
"haptics": [
|
||||
{
|
||||
"output": "/actions/generic_right/out/haptic",
|
||||
"path": "/user/hand/right/output/haptic"
|
||||
}
|
||||
],
|
||||
"poses": [
|
||||
{
|
||||
"output": "/actions/generic_right/in/pose_base",
|
||||
"path": "/user/hand/right/pose/base"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_right/in/pose_front",
|
||||
"path": "/user/hand/right/pose/front"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_right/in/pose_handgrip",
|
||||
"path": "/user/hand/right/pose/handgrip"
|
||||
},
|
||||
{
|
||||
"output": "/actions/generic_right/in/pose_tip",
|
||||
"path": "/user/hand/right/pose/tip"
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/appmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/application_menu"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/trigger_click" },
|
||||
"pull": { "output": "/actions/generic_right/in/trigger_pull" }
|
||||
},
|
||||
"mode": "trigger",
|
||||
"path": "/user/hand/right/input/trigger"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/trackpad_click" },
|
||||
"touch": { "output": "/actions/generic_right/in/trackpad_touch" },
|
||||
"position": { "output": "/actions/generic_right/in/trackpad_position" }
|
||||
},
|
||||
"mode": "trackpad",
|
||||
"path": "/user/hand/right/input/trackpad"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/grip_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/grip"
|
||||
},
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_right/in/sysmenu_click" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/hand/right/input/system"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "vive_controller",
|
||||
"description": "Standard Open CASCADE Technology VR bindings for the Vive controller",
|
||||
"name": "OCCT VR bindings for the Vive controller"
|
||||
}
|
18
src/XRResources/occtvr_bindings_vive_cosmos.json
Normal file
18
src/XRResources/occtvr_bindings_vive_cosmos.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "vive_cosmos",
|
||||
"description": "",
|
||||
"name": "vive cosmos hmd defaults",
|
||||
}
|
18
src/XRResources/occtvr_bindings_vive_pro.json
Normal file
18
src/XRResources/occtvr_bindings_vive_pro.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"bindings": {
|
||||
"/actions/generic_head": {
|
||||
"sources": [
|
||||
{
|
||||
"inputs": {
|
||||
"click": { "output": "/actions/generic_head/in/headset_on_head" }
|
||||
},
|
||||
"mode": "button",
|
||||
"path": "/user/head/proximity"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"controller_type": "vive_pro",
|
||||
"description": "",
|
||||
"name": "vive_pro defaults"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user