Parameters with the same name as class members are ripe for introducing bugs. The fact that the "this->" syntax is optional creates confusion for maintaining programmers who can only guess at the intention.
235 lines
6.1 KiB
C++
235 lines
6.1 KiB
C++
#include "StatisticsTabController.h"
|
|
#include <QQuickWindow>
|
|
#include "../overlaycontroller.h"
|
|
|
|
// application namespace
|
|
namespace advsettings {
|
|
|
|
void StatisticsTabController::initStage1() {
|
|
}
|
|
|
|
void StatisticsTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) {
|
|
this->parent = var_parent;
|
|
this->widget = var_widget;
|
|
}
|
|
|
|
void StatisticsTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed) {
|
|
vr::Compositor_CumulativeStats pStats;
|
|
vr::VRCompositor()->GetCumulativeStats(&pStats, sizeof(vr::Compositor_CumulativeStats));
|
|
if (pStats.m_nPid != m_cumStats.m_nPid) {
|
|
m_cumStats = pStats;
|
|
m_droppedFramesOffset = 0;
|
|
m_reprojectedFramesOffset = 0;
|
|
m_timedOutOffset = 0;
|
|
m_totalRatioPresentedOffset = 0;
|
|
m_totalRatioReprojectedOffset = 0;
|
|
}
|
|
m_cumStats = pStats;
|
|
|
|
auto& m = devicePoses->mDeviceToAbsoluteTracking.m;
|
|
|
|
// Hmd Distance //
|
|
if (lastPosTimer == 0) {
|
|
if (devicePoses[0].bPoseIsValid && devicePoses[0].eTrackingResult == vr::TrackingResult_Running_OK) {
|
|
if (!lastHmdPosValid) {
|
|
lastHmdPosValid = true;
|
|
} else {
|
|
auto delta = std::sqrt(std::pow(m[0][3] - lastHmdPos[0], 2) /*+ std::pow(m[1][3] - lastHmdPos[1], 2)*/ + std::pow(m[2][3] - lastHmdPos[2], 2));
|
|
if (delta >= 0.01f) {
|
|
m_hmdDistanceMoved += delta;
|
|
}
|
|
}
|
|
lastHmdPos[0] = m[0][3];
|
|
lastHmdPos[1] = m[1][3];
|
|
lastHmdPos[2] = m[2][3];
|
|
} else {
|
|
lastHmdPosValid = false;
|
|
}
|
|
}
|
|
|
|
// Controller speeds //
|
|
if (leftSpeed > m_leftControllerMaxSpeed) {
|
|
m_leftControllerMaxSpeed = leftSpeed;
|
|
}
|
|
if (rightSpeed > m_rightControllerMaxSpeed) {
|
|
m_rightControllerMaxSpeed = rightSpeed;
|
|
}
|
|
|
|
// Hmd Rotation //
|
|
/*
|
|
| Intrinsic y-x'-z" rotation matrix:
|
|
| cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy |
|
|
| cp*sr | cp*cr |-sp |
|
|
| cy*sp*sr-cr*sy | cr*cy*sp+sr*sy | cp*cy |
|
|
|
|
yaw = atan2(cp*sy, cp*cy) [pi, -pi], CCW
|
|
pitch = -asin(-sp) [pi/2, -pi/2]
|
|
roll = atan2(cp*sr, cp*cr) [pi, -pi], CW
|
|
*/
|
|
|
|
double yawRaw = 0.0;
|
|
double yaw = 0.0;
|
|
bool rotationChanged = false;
|
|
if (devicePoses[0].bPoseIsValid && devicePoses[0].eTrackingResult == vr::TrackingResult_Running_OK) {
|
|
yawRaw = std::atan2(m[0][2], m[2][2]);
|
|
if (yawRaw < 0.0f) {
|
|
yawRaw += 2 * M_PI; // map to [0, 2*pi], CCW
|
|
}
|
|
yaw = yawRaw - rotationOffset;
|
|
if (yaw < 0.0) {
|
|
yaw = 2 * M_PI + yaw;
|
|
}
|
|
if (rotationResetFlag) {
|
|
rotationDir = 0;
|
|
rotationCounter = 0;
|
|
rotationOffset = yawRaw;
|
|
rotationResetFlag = false;
|
|
lastYaw = -1.0f;
|
|
rotationChanged = true;
|
|
} else if (lastYaw < 0.0f && yaw > 0.0) {
|
|
lastYaw = yaw;
|
|
rotationChanged = true;
|
|
if (yaw <= M_PI) {
|
|
rotationDir = 1;
|
|
} else {
|
|
rotationDir = -1;
|
|
}
|
|
} else if (std::abs(lastYaw - yaw) >= 0.01 && yaw > 0.0) {
|
|
auto diff = yaw - lastYaw;
|
|
int mode = 0;
|
|
if (std::abs(diff) > M_PI) {
|
|
if (diff < -M_PI) { // CCW overflow
|
|
mode = 1;
|
|
} else if (diff > M_PI) { // CW overflow
|
|
mode = -1;
|
|
}
|
|
} else {
|
|
if (lastYaw < 0.0 && yaw > 0.0) {
|
|
mode = 1;
|
|
} else if (lastYaw > 0.0 && yaw < 0.0) {
|
|
mode = -1;
|
|
}
|
|
}
|
|
if (mode > 0) {
|
|
if (rotationCounter == 0 && rotationDir <= 0) {
|
|
rotationDir = 1;
|
|
} else {
|
|
rotationCounter++;
|
|
}
|
|
} else if (mode < 0) {
|
|
if (rotationCounter == 0 && rotationDir >= 0) {
|
|
rotationDir = -1;
|
|
} else {
|
|
rotationCounter--;
|
|
}
|
|
}
|
|
lastYaw = yaw;
|
|
rotationChanged = true;
|
|
}
|
|
} else {
|
|
lastYaw = -1;
|
|
}
|
|
|
|
if (rotationChanged) {
|
|
m_hmdRotation = (float)rotationCounter;
|
|
if (rotationDir > 0) {
|
|
m_hmdRotation += yaw / (2 * M_PI);
|
|
} else if (rotationDir < 0) {
|
|
m_hmdRotation += -1.0f + yaw / (2 * M_PI);
|
|
}
|
|
}
|
|
if (lastPosTimer == 0) {
|
|
lastPosTimer = 10;
|
|
} else {
|
|
lastPosTimer--;
|
|
}
|
|
}
|
|
|
|
float StatisticsTabController::hmdDistanceMoved() const {
|
|
return m_hmdDistanceMoved;
|
|
}
|
|
|
|
float StatisticsTabController::hmdRotations() const {
|
|
return m_hmdRotation;
|
|
}
|
|
|
|
float StatisticsTabController::rightControllerMaxSpeed() const {
|
|
return m_rightControllerMaxSpeed;
|
|
}
|
|
|
|
float StatisticsTabController::leftControllerMaxSpeed() const {
|
|
return m_leftControllerMaxSpeed;
|
|
}
|
|
|
|
unsigned StatisticsTabController::presentedFrames() const {
|
|
return m_cumStats.m_nNumFramePresents - m_presentedFramesOffset;
|
|
}
|
|
|
|
unsigned StatisticsTabController::droppedFrames() const {
|
|
return m_cumStats.m_nNumDroppedFrames - m_droppedFramesOffset;
|
|
}
|
|
|
|
unsigned StatisticsTabController::reprojectedFrames() const {
|
|
return m_cumStats.m_nNumReprojectedFrames - m_reprojectedFramesOffset;
|
|
}
|
|
|
|
unsigned StatisticsTabController::timedOut() const {
|
|
return m_cumStats.m_nNumTimedOut - m_timedOutOffset;
|
|
}
|
|
|
|
float StatisticsTabController::totalReprojectedRatio() const {
|
|
float totalFrames = (float)(m_cumStats.m_nNumFramePresents - m_totalRatioPresentedOffset);
|
|
float reprojectedFrames = (float)(m_cumStats.m_nNumReprojectedFrames - m_totalRatioReprojectedOffset);
|
|
if (totalFrames != 0.0f) {
|
|
return reprojectedFrames / totalFrames;
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
void StatisticsTabController::statsDistanceResetClicked() {
|
|
lastHmdPosValid = false;
|
|
if (m_hmdDistanceMoved != 0.0) {
|
|
m_hmdDistanceMoved = 0.0;
|
|
}
|
|
}
|
|
|
|
void StatisticsTabController::statsRotationResetClicked() {
|
|
rotationResetFlag = true;
|
|
}
|
|
|
|
void StatisticsTabController::statsLeftControllerSpeedResetClicked() {
|
|
if (m_leftControllerMaxSpeed != 0.0) {
|
|
m_leftControllerMaxSpeed = 0.0;
|
|
}
|
|
}
|
|
|
|
void StatisticsTabController::statsRightControllerSpeedResetClicked() {
|
|
if (m_rightControllerMaxSpeed != 0.0) {
|
|
m_rightControllerMaxSpeed = 0.0;
|
|
}
|
|
}
|
|
|
|
void StatisticsTabController::presentedFramesResetClicked() {
|
|
m_presentedFramesOffset = m_cumStats.m_nNumFramePresents;
|
|
}
|
|
|
|
void StatisticsTabController::droppedFramesResetClicked() {
|
|
m_droppedFramesOffset = m_cumStats.m_nNumDroppedFrames;
|
|
}
|
|
|
|
void StatisticsTabController::reprojectedFramesResetClicked() {
|
|
m_reprojectedFramesOffset = m_cumStats.m_nNumReprojectedFrames;
|
|
}
|
|
|
|
void StatisticsTabController::timedOutResetClicked() {
|
|
m_timedOutOffset = m_cumStats.m_nNumTimedOut;
|
|
}
|
|
|
|
void StatisticsTabController::totalRatioResetClicked() {
|
|
m_totalRatioPresentedOffset = m_cumStats.m_nNumFramePresents;
|
|
m_totalRatioReprojectedOffset = m_cumStats.m_nNumReprojectedFrames;
|
|
}
|
|
|
|
} // namespace advconfig
|