Skip to content

Commit 97b8f36

Browse files
authored
Merge pull request #74 from elvissteinjr/overlay-interaction-toggle
Activate laser pointer when controller is pointing the at the overlay using the tip matrix
2 parents dcf9518 + ef66335 commit 97b8f36

File tree

3 files changed

+171
-6
lines changed

3 files changed

+171
-6
lines changed

L4D2VR/sdk/vector.h

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,13 +404,24 @@ class VMatrix
404404
{
405405
public:
406406

407-
VMatrix();
407+
VMatrix()
408+
{
409+
}
410+
408411
VMatrix(
409412
vec_t m00, vec_t m01, vec_t m02, vec_t m03,
410413
vec_t m10, vec_t m11, vec_t m12, vec_t m13,
411414
vec_t m20, vec_t m21, vec_t m22, vec_t m23,
412415
vec_t m30, vec_t m31, vec_t m32, vec_t m33
413-
);
416+
)
417+
{
418+
Init(
419+
m00, m01, m02, m03,
420+
m10, m11, m12, m13,
421+
m20, m21, m22, m23,
422+
m30, m31, m32, m33
423+
);
424+
}
414425

415426
// Creates a matrix where the X axis = forward
416427
// the Y axis = left, and the Z axis = up
@@ -426,7 +437,28 @@ class VMatrix
426437
vec_t m10, vec_t m11, vec_t m12, vec_t m13,
427438
vec_t m20, vec_t m21, vec_t m22, vec_t m23,
428439
vec_t m30, vec_t m31, vec_t m32, vec_t m33
429-
);
440+
)
441+
{
442+
m[0][0] = m00;
443+
m[0][1] = m01;
444+
m[0][2] = m02;
445+
m[0][3] = m03;
446+
447+
m[1][0] = m10;
448+
m[1][1] = m11;
449+
m[1][2] = m12;
450+
m[1][3] = m13;
451+
452+
m[2][0] = m20;
453+
m[2][1] = m21;
454+
m[2][2] = m22;
455+
m[2][3] = m23;
456+
457+
m[3][0] = m30;
458+
m[3][1] = m31;
459+
m[3][2] = m32;
460+
m[3][3] = m33;
461+
}
430462

431463

432464
// Initialize from a 3x4
@@ -529,7 +561,30 @@ class VMatrix
529561
VMatrix &operator=(const VMatrix &mOther);
530562

531563
// Multiply two matrices (out = this * vm).
532-
void MatrixMul(const VMatrix &vm, VMatrix &out) const;
564+
void MatrixMul(const VMatrix &vm, VMatrix &out) const
565+
{
566+
out.Init(
567+
m[0][0]*vm.m[0][0] + m[0][1]*vm.m[1][0] + m[0][2]*vm.m[2][0] + m[0][3]*vm.m[3][0],
568+
m[0][0]*vm.m[0][1] + m[0][1]*vm.m[1][1] + m[0][2]*vm.m[2][1] + m[0][3]*vm.m[3][1],
569+
m[0][0]*vm.m[0][2] + m[0][1]*vm.m[1][2] + m[0][2]*vm.m[2][2] + m[0][3]*vm.m[3][2],
570+
m[0][0]*vm.m[0][3] + m[0][1]*vm.m[1][3] + m[0][2]*vm.m[2][3] + m[0][3]*vm.m[3][3],
571+
572+
m[1][0]*vm.m[0][0] + m[1][1]*vm.m[1][0] + m[1][2]*vm.m[2][0] + m[1][3]*vm.m[3][0],
573+
m[1][0]*vm.m[0][1] + m[1][1]*vm.m[1][1] + m[1][2]*vm.m[2][1] + m[1][3]*vm.m[3][1],
574+
m[1][0]*vm.m[0][2] + m[1][1]*vm.m[1][2] + m[1][2]*vm.m[2][2] + m[1][3]*vm.m[3][2],
575+
m[1][0]*vm.m[0][3] + m[1][1]*vm.m[1][3] + m[1][2]*vm.m[2][3] + m[1][3]*vm.m[3][3],
576+
577+
m[2][0]*vm.m[0][0] + m[2][1]*vm.m[1][0] + m[2][2]*vm.m[2][0] + m[2][3]*vm.m[3][0],
578+
m[2][0]*vm.m[0][1] + m[2][1]*vm.m[1][1] + m[2][2]*vm.m[2][1] + m[2][3]*vm.m[3][1],
579+
m[2][0]*vm.m[0][2] + m[2][1]*vm.m[1][2] + m[2][2]*vm.m[2][2] + m[2][3]*vm.m[3][2],
580+
m[2][0]*vm.m[0][3] + m[2][1]*vm.m[1][3] + m[2][2]*vm.m[2][3] + m[2][3]*vm.m[3][3],
581+
582+
m[3][0]*vm.m[0][0] + m[3][1]*vm.m[1][0] + m[3][2]*vm.m[2][0] + m[3][3]*vm.m[3][0],
583+
m[3][0]*vm.m[0][1] + m[3][1]*vm.m[1][1] + m[3][2]*vm.m[2][1] + m[3][3]*vm.m[3][1],
584+
m[3][0]*vm.m[0][2] + m[3][1]*vm.m[1][2] + m[3][2]*vm.m[2][2] + m[3][3]*vm.m[3][2],
585+
m[3][0]*vm.m[0][3] + m[3][1]*vm.m[1][3] + m[3][2]*vm.m[2][3] + m[3][3]*vm.m[3][3]
586+
);
587+
}
533588

534589
// Add two matrices.
535590
const VMatrix &operator+=(const VMatrix &other);

L4D2VR/vr.cpp

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,13 @@ void VR::ProcessMenuInput()
415415
{
416416
vr::VROverlayHandle_t currentOverlay = m_Game->m_EngineClient->IsInGame() ? m_HUDHandle : m_MainMenuHandle;
417417

418+
// Check if left or right hand controller is pointing at the overlay
419+
const bool isHoveringOverlay = CheckOverlayIntersectionForController(currentOverlay, vr::TrackedControllerRole_LeftHand) ||
420+
CheckOverlayIntersectionForController(currentOverlay, vr::TrackedControllerRole_RightHand);
421+
418422
// Overlays can't process action inputs if the laser is active, so
419-
// only activate laser if the controller is aiming forward.
420-
if (abs(m_RightControllerAngAbs.x) < 45 || abs(m_LeftControllerAngAbs.x) < 45)
423+
// only activate laser if a controller is pointing at the overlay
424+
if (isHoveringOverlay)
421425
{
422426
vr::VROverlay()->SetOverlayFlag(currentOverlay, vr::VROverlayFlags_MakeOverlaysInteractiveIfVisible, true);
423427

@@ -716,6 +720,108 @@ void VR::ProcessInput()
716720
}
717721
}
718722

723+
VMatrix VR::VMatrixFromHmdMatrix(const vr::HmdMatrix34_t &hmdMat)
724+
{
725+
// VMatrix has a different implicit coordinate system than HmdMatrix34_t, but this function does not convert between them
726+
VMatrix vMat(
727+
hmdMat.m[0][0], hmdMat.m[1][0], hmdMat.m[2][0], 0.0f,
728+
hmdMat.m[0][1], hmdMat.m[1][1], hmdMat.m[2][1], 0.0f,
729+
hmdMat.m[0][2], hmdMat.m[1][2], hmdMat.m[2][2], 0.0f,
730+
hmdMat.m[0][3], hmdMat.m[1][3], hmdMat.m[2][3], 1.0f
731+
);
732+
733+
return vMat;
734+
}
735+
736+
vr::HmdMatrix34_t VR::VMatrixToHmdMatrix(const VMatrix &vMat)
737+
{
738+
vr::HmdMatrix34_t hmdMat = {0};
739+
740+
hmdMat.m[0][0] = vMat.m[0][0];
741+
hmdMat.m[1][0] = vMat.m[0][1];
742+
hmdMat.m[2][0] = vMat.m[0][2];
743+
744+
hmdMat.m[0][1] = vMat.m[1][0];
745+
hmdMat.m[1][1] = vMat.m[1][1];
746+
hmdMat.m[2][1] = vMat.m[1][2];
747+
748+
hmdMat.m[0][2] = vMat.m[2][0];
749+
hmdMat.m[1][2] = vMat.m[2][1];
750+
hmdMat.m[2][2] = vMat.m[2][2];
751+
752+
hmdMat.m[0][3] = vMat.m[3][0];
753+
hmdMat.m[1][3] = vMat.m[3][1];
754+
hmdMat.m[2][3] = vMat.m[3][2];
755+
756+
return hmdMat;
757+
}
758+
759+
vr::HmdMatrix34_t VR::GetControllerTipMatrix(vr::ETrackedControllerRole controllerRole)
760+
{
761+
vr::VRInputValueHandle_t inputValue = vr::k_ulInvalidInputValueHandle;
762+
763+
if (controllerRole == vr::TrackedControllerRole_RightHand)
764+
{
765+
m_Input->GetInputSourceHandle("/user/hand/right", &inputValue);
766+
}
767+
else if (controllerRole == vr::TrackedControllerRole_LeftHand)
768+
{
769+
m_Input->GetInputSourceHandle("/user/hand/left", &inputValue);
770+
}
771+
772+
if (inputValue != vr::k_ulInvalidInputValueHandle)
773+
{
774+
char buffer[vr::k_unMaxPropertyStringSize];
775+
776+
m_System->GetStringTrackedDeviceProperty(vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(controllerRole), vr::Prop_RenderModelName_String,
777+
buffer, vr::k_unMaxPropertyStringSize);
778+
779+
vr::RenderModel_ControllerMode_State_t controllerState = {0};
780+
vr::RenderModel_ComponentState_t componentState = {0};
781+
782+
if (vr::VRRenderModels()->GetComponentStateForDevicePath(buffer, vr::k_pch_Controller_Component_Tip, inputValue, &controllerState, &componentState))
783+
{
784+
return componentState.mTrackingToComponentLocal;
785+
}
786+
}
787+
788+
// Not a hand controller role or tip lookup failed, return identity
789+
const vr::HmdMatrix34_t identity =
790+
{
791+
1.0f, 0.0f, 0.0f, 0.0f,
792+
0.0f, 1.0f, 0.0f, 0.0f,
793+
0.0f, 0.0f, 1.0f, 0.0f
794+
};
795+
796+
return identity;
797+
}
798+
799+
bool VR::CheckOverlayIntersectionForController(vr::VROverlayHandle_t overlayHandle, vr::ETrackedControllerRole controllerRole)
800+
{
801+
vr::TrackedDeviceIndex_t deviceIndex = m_System->GetTrackedDeviceIndexForControllerRole(controllerRole);
802+
803+
if (deviceIndex == vr::k_unTrackedDeviceIndexInvalid)
804+
return false;
805+
806+
vr::TrackedDevicePose_t &controllerPose = m_Poses[deviceIndex];
807+
808+
if (!controllerPose.bPoseIsValid)
809+
return false;
810+
811+
VMatrix controllerVMatrix = VMatrixFromHmdMatrix(controllerPose.mDeviceToAbsoluteTracking);
812+
VMatrix tipVMatrix = VMatrixFromHmdMatrix(GetControllerTipMatrix(controllerRole));
813+
tipVMatrix.MatrixMul(controllerVMatrix, controllerVMatrix);
814+
815+
vr::VROverlayIntersectionParams_t params = {0};
816+
vr::VROverlayIntersectionResults_t results = {0};
817+
818+
params.eOrigin = vr::VRCompositor()->GetTrackingSpace();
819+
params.vSource = { controllerVMatrix.m[3][0], controllerVMatrix.m[3][1], controllerVMatrix.m[3][2]};
820+
params.vDirection = {-controllerVMatrix.m[2][0], -controllerVMatrix.m[2][1], -controllerVMatrix.m[2][2]};
821+
822+
return m_Overlay->ComputeOverlayIntersection(overlayHandle, &params, &results);
823+
}
824+
719825
QAngle VR::GetRightControllerAbsAngle()
720826
{
721827
return m_RightControllerAngAbs;

L4D2VR/vr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ class VR
196196
void GetViewParameters();
197197
void ProcessMenuInput();
198198
void ProcessInput();
199+
VMatrix VMatrixFromHmdMatrix(const vr::HmdMatrix34_t &hmdMat);
200+
vr::HmdMatrix34_t VMatrixToHmdMatrix(const VMatrix &vMat);
201+
vr::HmdMatrix34_t GetControllerTipMatrix(vr::ETrackedControllerRole controllerRole);
202+
bool CheckOverlayIntersectionForController(vr::VROverlayHandle_t overlayHandle, vr::ETrackedControllerRole controllerRole);
199203
QAngle GetRightControllerAbsAngle();
200204
Vector GetRightControllerAbsPos();
201205
Vector GetRecommendedViewmodelAbsPos();

0 commit comments

Comments
 (0)