Diff
Modified: trunk/Source/WebCore/ChangeLog (230427 => 230428)
--- trunk/Source/WebCore/ChangeLog 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/ChangeLog 2018-04-09 14:40:51 UTC (rev 230428)
@@ -1,3 +1,62 @@
+2018-04-03 Sergio Villar Senin <svil...@igalia.com>
+
+ [OpenVR][WebVR] Retrieve FrameData in WebVR's rAF
+ https://bugs.webkit.org/show_bug.cgi?id=184265
+
+ Reviewed by Žan Doberšek.
+
+ VRFrameData contains all the required information to properly render a VR scene like view
+ and projection matrices, pose data (position & orientation) and linear & angular velocity
+ among others. The getFrameData() call must be issued inside a WebVR's own
+ requestAnimationFrame.
+
+ * Modules/webvr/VRDisplay.cpp:
+ (WebCore::VRDisplay::getFrameData const):
+ (WebCore::VRDisplay::getPose const):
+ (WebCore::VRDisplay::requestAnimationFrame):
+ (WebCore::VRDisplay::cancelAnimationFrame):
+ * Modules/webvr/VRDisplay.h:
+ * Modules/webvr/VREyeParameters.h:
+ (WebCore::VREyeParameters::rawOffset const): Required to compute view matrices.
+ * Modules/webvr/VRFrameData.cpp:
+ (WebCore::matrixToArray):
+ (WebCore::VRFrameData::leftProjectionMatrix const):
+ (WebCore::VRFrameData::leftViewMatrix const):
+ (WebCore::VRFrameData::rightProjectionMatrix const):
+ (WebCore::VRFrameData::rightViewMatrix const):
+ (WebCore::projectionMatrixFromFieldOfView):
+ (WebCore::rotationMatrixFromQuaternion):
+ (WebCore::applyHeadToEyeTransform):
+ (WebCore::VRFrameData::update):
+ (WebCore::VRFrameData::timestamp const): Deleted.
+ * Modules/webvr/VRFrameData.h:
+ (WebCore::VRFrameData::timestamp const):
+ * Modules/webvr/VRPose.cpp:
+ (WebCore::optionalFloat3ToJSCArray):
+ (WebCore::VRPose::position const):
+ (WebCore::VRPose::linearVelocity const):
+ (WebCore::VRPose::linearAcceleration const):
+ (WebCore::VRPose::orientation const):
+ (WebCore::VRPose::angularVelocity const):
+ (WebCore::VRPose::angularAcceleration const):
+ * Modules/webvr/VRPose.h:
+ (WebCore::VRPose::create):
+ (WebCore::VRPose::update):
+ (WebCore::VRPose::VRPose):
+ * platform/vr/VRPlatformDisplay.h:
+ (WebCore::VRPlatformTrackingInfo::Quaternion::Quaternion):
+ (WebCore::VRPlatformTrackingInfo::Quaternion::conjugate):
+ (WebCore::VRPlatformTrackingInfo::Quaternion::operator*):
+ (WebCore::VRPlatformTrackingInfo::Float3::Float3): Just a group of 3 floats used to store
+ both velocity and acceleration in a format which is very convenient to later generate JSC
+ arrays.
+ (WebCore::VRPlatformTrackingInfo::clear):
+ * platform/vr/openvr/VRPlatformDisplayOpenVR.cpp:
+ (WebCore::VRPlatformDisplayOpenVR::VRPlatformDisplayOpenVR):
+ (WebCore::rotationMatrixToQuaternion):
+ (WebCore::VRPlatformDisplayOpenVR::getTrackingInfo):
+ * platform/vr/openvr/VRPlatformDisplayOpenVR.h:
+
2018-04-09 Michael Catanzaro <mcatanz...@igalia.com>
[GTK] WaylandCompositorDisplay leaks its wl_display
Modified: trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplay.cpp 2018-04-09 14:40:51 UTC (rev 230428)
@@ -26,8 +26,12 @@
#include "config.h"
#include "VRDisplay.h"
+#include "Chrome.h"
+#include "Page.h"
+#include "ScriptedAnimationController.h"
#include "VRDisplayCapabilities.h"
#include "VREyeParameters.h"
+#include "VRFrameData.h"
#include "VRLayerInit.h"
#include "VRPlatformDisplay.h"
#include "VRPose.h"
@@ -85,14 +89,19 @@
return eye == VREye::Left ? *m_leftEyeParameters : *m_rightEyeParameters;
}
-bool VRDisplay::getFrameData(VRFrameData&) const
+bool VRDisplay::getFrameData(VRFrameData& frameData) const
{
- return false;
+ if (!m_capabilities->hasPosition() || !m_capabilities->hasOrientation())
+ return false;
+
+ // FIXME: ensure that this is only called inside WebVR's rAF.
+ frameData.update(m_display->getTrackingInfo(), getEyeParameters(VREye::Left), getEyeParameters(VREye::Right), m_depthNear, m_depthFar);
+ return true;
}
Ref<VRPose> VRDisplay::getPose() const
{
- return VRPose::create();
+ return VRPose::create(m_display->getTrackingInfo());
}
void VRDisplay::resetPose()
@@ -99,13 +108,28 @@
{
}
-long VRDisplay::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&)
+uint32_t VRDisplay::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&& callback)
{
- return 0;
+ if (!m_scriptedAnimationController) {
+ auto* document = downcast<Document>(scriptExecutionContext());
+#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
+ // FIXME: Get the display id of the HMD as it should use the HMD native refresh rate.
+ PlatformDisplayID displayID = document->page() ? document->page()->chrome().displayID() : 0;
+ m_scriptedAnimationController = ScriptedAnimationController::create(*document, displayID);
+#else
+ m_scriptedAnimationController = ScriptedAnimationController::create(*document, 0);
+#endif
+ }
+
+ return m_scriptedAnimationController->registerCallback(WTFMove(callback));
}
-void VRDisplay::cancelAnimationFrame(unsigned)
+void VRDisplay::cancelAnimationFrame(uint32_t id)
{
+ if (!m_scriptedAnimationController)
+ return;
+
+ m_scriptedAnimationController->cancelCallback(id);
}
void VRDisplay::requestPresent(const Vector<VRLayerInit>&, Ref<DeferredPromise>&&)
Modified: trunk/Source/WebCore/Modules/webvr/VRDisplay.h (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRDisplay.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRDisplay.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -34,6 +34,7 @@
namespace WebCore {
class RequestAnimationFrameCallback;
+class ScriptedAnimationController;
class VRDisplayCapabilities;
class VREyeParameters;
class VRFrameData;
@@ -72,8 +73,8 @@
double depthFar() const { return m_depthFar; }
void setDepthFar(double depthFar) { m_depthFar = depthFar; }
- long requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
- void cancelAnimationFrame(unsigned);
+ uint32_t requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
+ void cancelAnimationFrame(uint32_t);
void requestPresent(const Vector<VRLayerInit>&, Ref<DeferredPromise>&&);
void exitPresent(Ref<DeferredPromise>&&);
@@ -111,6 +112,8 @@
double m_depthNear { 0.01 }; // Default value from the specs.
double m_depthFar { 10000 }; // Default value from the specs.
+
+ RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webvr/VREyeParameters.h (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VREyeParameters.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VREyeParameters.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -43,6 +43,7 @@
}
Ref<Float32Array> offset() const;
+ const FloatPoint3D& rawOffset() const { return m_offset; }
const VRFieldOfView& fieldOfView() const;
Modified: trunk/Source/WebCore/Modules/webvr/VRFrameData.cpp (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRFrameData.cpp 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRFrameData.cpp 2018-04-09 14:40:51 UTC (rev 230428)
@@ -25,6 +25,8 @@
#include "config.h"
#include "VRFrameData.h"
+#include "VREyeParameters.h"
+#include "VRPlatformDisplay.h"
#include "VRPose.h"
namespace WebCore {
@@ -34,29 +36,31 @@
{
}
-double VRFrameData::timestamp() const
+static Ref<Float32Array> matrixToArray(const TransformationMatrix& matrix)
{
- return 0;
+ TransformationMatrix::FloatMatrix4 columnMajorMatrix;
+ matrix.toColumnMajorFloatArray(columnMajorMatrix);
+ return Float32Array::create(columnMajorMatrix, 16).releaseNonNull();
}
-Float32Array* VRFrameData::leftProjectionMatrix() const
+Ref<Float32Array> VRFrameData::leftProjectionMatrix() const
{
- return nullptr;
+ return matrixToArray(m_leftProjectionMatrix);
}
-Float32Array* VRFrameData::leftViewMatrix() const
+Ref<Float32Array> VRFrameData::leftViewMatrix() const
{
- return nullptr;
+ return matrixToArray(m_leftViewMatrix);
}
-Float32Array* VRFrameData::rightProjectionMatrix() const
+Ref<Float32Array> VRFrameData::rightProjectionMatrix() const
{
- return nullptr;
+ return matrixToArray(m_rightProjectionMatrix);
}
-Float32Array* VRFrameData::rightViewMatrix() const
+Ref<Float32Array> VRFrameData::rightViewMatrix() const
{
- return nullptr;
+ return matrixToArray(m_rightViewMatrix);
}
const VRPose& VRFrameData::pose() const
@@ -64,4 +68,76 @@
return m_pose;
}
+static TransformationMatrix projectionMatrixFromFieldOfView(const VRFieldOfView& fov, double depthNear, double depthFar)
+{
+ double upTan = tan(deg2rad(fov.upDegrees()));
+ double downTan = tan(deg2rad(fov.downDegrees()));
+ double leftTan = tan(deg2rad(fov.leftDegrees()));
+ double rightTan = tan(deg2rad(fov.rightDegrees()));
+
+ double xScale = 2 / (leftTan + rightTan);
+ double yScale = 2 / (upTan + downTan);
+
+ TransformationMatrix projectionMatrix;
+ projectionMatrix.setM11(xScale);
+ projectionMatrix.setM22(yScale);
+ projectionMatrix.setM32((upTan - downTan) * yScale * 0.5);
+ projectionMatrix.setM31(-((leftTan - rightTan) * xScale * 0.5));
+ projectionMatrix.setM33((depthNear + depthFar) / (depthNear - depthFar));
+ projectionMatrix.setM34(-1);
+ projectionMatrix.setM43((2 * depthFar * depthNear) / (depthNear - depthFar));
+ projectionMatrix.setM44(0);
+
+ return projectionMatrix;
+}
+
+// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
+static TransformationMatrix rotationMatrixFromQuaternion(const VRPlatformTrackingInfo::Quaternion& quaternion)
+{
+ double magnitude = (quaternion.x * quaternion.x) + (quaternion.y * quaternion.y) + (quaternion.z * quaternion.z) + (quaternion.w * quaternion.w);
+ VRPlatformTrackingInfo::Quaternion normalizedQuaternion(quaternion.x / magnitude, quaternion.y / magnitude, quaternion.z / magnitude, quaternion.w / magnitude);
+ double x2 = normalizedQuaternion.x * normalizedQuaternion.x;
+ double y2 = normalizedQuaternion.y * normalizedQuaternion.y;
+ double z2 = normalizedQuaternion.z * normalizedQuaternion.z;
+ double w2 = normalizedQuaternion.w * normalizedQuaternion.w;
+ double xy = normalizedQuaternion.x * normalizedQuaternion.y;
+ double zw = normalizedQuaternion.z * normalizedQuaternion.w;
+ double xz = normalizedQuaternion.x * normalizedQuaternion.z;
+ double yw = normalizedQuaternion.y * normalizedQuaternion.w;
+ double yz = normalizedQuaternion.y * normalizedQuaternion.z;
+ double xw = normalizedQuaternion.x * normalizedQuaternion.w;
+
+ return TransformationMatrix(
+ x2 - y2 - z2 + w2, 2.0 * (xy - zw), 2.0 * (xz + yw), 0,
+ 2.0 * (xy + zw), -x2 + y2 - z2 + w2, 2.0 * (yz - xw), 0,
+ 2.0 * (xz - yw), 2.0 * (yz + xw), -x2 - y2 + z2 + w2, 0,
+ 0, 0, 0, 1);
+}
+
+static void applyHeadToEyeTransform(TransformationMatrix& matrix, const FloatPoint3D& translation)
+{
+ matrix.setM41(matrix.m41() - translation.x());
+ matrix.setM42(matrix.m42() - translation.y());
+ matrix.setM43(matrix.m43() - translation.z());
+}
+
+void VRFrameData::update(const VRPlatformTrackingInfo& trackingInfo, const VREyeParameters& leftEye, const VREyeParameters& rightEye, double depthNear, double depthFar)
+{
+ m_leftProjectionMatrix = projectionMatrixFromFieldOfView(leftEye.fieldOfView(), depthNear, depthFar);
+ m_rightProjectionMatrix = projectionMatrixFromFieldOfView(rightEye.fieldOfView(), depthNear, depthFar);
+
+ m_timestamp = trackingInfo.timestamp;
+ m_pose->update(trackingInfo);
+
+ auto rotationMatrix = rotationMatrixFromQuaternion(trackingInfo.orientation.value_or(VRPlatformTrackingInfo::Quaternion(0, 0, 0, 1)));
+ FloatPoint3D position = trackingInfo.position.value_or(FloatPoint3D(0, 0, 0));
+ rotationMatrix.translate3d(-position.x(), -position.y(), -position.z());
+
+ m_leftViewMatrix = rotationMatrix;
+ applyHeadToEyeTransform(m_leftViewMatrix, leftEye.rawOffset());
+
+ m_rightViewMatrix = rotationMatrix;
+ applyHeadToEyeTransform(m_rightViewMatrix, rightEye.rawOffset());
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webvr/VRFrameData.h (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRFrameData.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRFrameData.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -24,12 +24,15 @@
*/
#pragma once
+#include "TransformationMatrix.h"
#include <_javascript_Core/Float32Array.h>
#include <wtf/RefCounted.h>
namespace WebCore {
+class VREyeParameters;
class VRPose;
+struct VRPlatformTrackingInfo;
class VRFrameData : public RefCounted<VRFrameData> {
public:
@@ -38,20 +41,27 @@
return adoptRef(*new VRFrameData);
}
- double timestamp() const;
+ double timestamp() const { return m_timestamp; }
- Float32Array* leftProjectionMatrix() const;
- Float32Array* leftViewMatrix() const;
+ Ref<Float32Array> leftProjectionMatrix() const;
+ Ref<Float32Array> leftViewMatrix() const;
- Float32Array* rightProjectionMatrix() const;
- Float32Array* rightViewMatrix() const;
+ Ref<Float32Array> rightProjectionMatrix() const;
+ Ref<Float32Array> rightViewMatrix() const;
const VRPose& pose() const;
+ void update(const VRPlatformTrackingInfo&, const VREyeParameters& leftEye, const VREyeParameters& rightEye, double depthNear, double depthFar);
+
private:
VRFrameData();
+ double m_timestamp { 0 };
Ref<VRPose> m_pose;
+ TransformationMatrix m_leftProjectionMatrix;
+ TransformationMatrix m_rightProjectionMatrix;
+ TransformationMatrix m_leftViewMatrix;
+ TransformationMatrix m_rightViewMatrix;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webvr/VRPose.cpp (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRPose.cpp 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRPose.cpp 2018-04-09 14:40:51 UTC (rev 230428)
@@ -27,36 +27,52 @@
namespace WebCore {
-VRPose::VRPose() = default;
+static RefPtr<Float32Array> optionalFloat3ToJSCArray(const std::optional<VRPlatformTrackingInfo::Float3>& data)
+{
+ if (!data)
+ return nullptr;
-Float32Array* VRPose::position() const
+ return Float32Array::create(data->data, 3).releaseNonNull();
+}
+
+RefPtr<Float32Array> VRPose::position() const
{
- return nullptr;
+ if (!m_trackingInfo.position)
+ return nullptr;
+
+ auto& position = *m_trackingInfo.position;
+ float positionData[3] = { position.x(), position.y(), position.z() };
+ return Float32Array::create(positionData, 3).releaseNonNull();
}
-Float32Array* VRPose::linearVelocity() const
+RefPtr<Float32Array> VRPose::linearVelocity() const
{
- return nullptr;
+ return optionalFloat3ToJSCArray(m_trackingInfo.linearVelocity);
}
-Float32Array* VRPose::linearAcceleration() const
+RefPtr<Float32Array> VRPose::linearAcceleration() const
{
- return nullptr;
+ return optionalFloat3ToJSCArray(m_trackingInfo.linearAcceleration);
}
-Float32Array* VRPose::orientation() const
+RefPtr<Float32Array> VRPose::orientation() const
{
- return nullptr;
+ if (!m_trackingInfo.orientation)
+ return nullptr;
+
+ auto& orientation = *m_trackingInfo.orientation;
+ float orientationData[4] = { orientation.x, orientation.y, orientation.z, orientation.w };
+ return Float32Array::create(orientationData, 4).releaseNonNull();
}
-Float32Array* VRPose::angularVelocity() const
+RefPtr<Float32Array> VRPose::angularVelocity() const
{
- return nullptr;
+ return optionalFloat3ToJSCArray(m_trackingInfo.angularVelocity);
}
-Float32Array* VRPose::angularAcceleration() const
+RefPtr<Float32Array> VRPose::angularAcceleration() const
{
- return nullptr;
+ return optionalFloat3ToJSCArray(m_trackingInfo.angularAcceleration);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webvr/VRPose.h (230427 => 230428)
--- trunk/Source/WebCore/Modules/webvr/VRPose.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/Modules/webvr/VRPose.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -24,6 +24,7 @@
*/
#pragma once
+#include "VRPlatformDisplay.h"
#include <_javascript_Core/Float32Array.h>
#include <wtf/RefCounted.h>
@@ -36,16 +37,30 @@
return adoptRef(*new VRPose);
}
- Float32Array* position() const;
- Float32Array* linearVelocity() const;
- Float32Array* linearAcceleration() const;
+ static Ref<VRPose> create(const VRPlatformTrackingInfo& trackingInfo)
+ {
+ return adoptRef(*new VRPose(trackingInfo));
+ }
- Float32Array* orientation() const;
- Float32Array* angularVelocity() const;
- Float32Array* angularAcceleration() const;
+ RefPtr<Float32Array> position() const;
+ RefPtr<Float32Array> linearVelocity() const;
+ RefPtr<Float32Array> linearAcceleration() const;
+ RefPtr<Float32Array> orientation() const;
+ RefPtr<Float32Array> angularVelocity() const;
+ RefPtr<Float32Array> angularAcceleration() const;
+
+ void update(const VRPlatformTrackingInfo& trackingInfo) { m_trackingInfo = trackingInfo; };
+
private:
- VRPose();
+ VRPose() = default;
+
+ VRPose(const VRPlatformTrackingInfo& trackingInfo)
+ : m_trackingInfo(trackingInfo)
+ {
+ }
+
+ VRPlatformTrackingInfo m_trackingInfo;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/vr/VRPlatformDisplay.h (230427 => 230428)
--- trunk/Source/WebCore/platform/vr/VRPlatformDisplay.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/platform/vr/VRPlatformDisplay.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -103,9 +103,64 @@
std::optional<TransformationMatrix> m_sittingToStandingTransform;
};
+struct VRPlatformTrackingInfo {
+ struct Quaternion {
+ Quaternion()
+ : x(0), y(0), z(0), w(1) { }
+
+ Quaternion(float x, float y, float z, float w)
+ : x(x), y(y), z(z), w(w) { }
+
+ Quaternion& conjugate()
+ {
+ x *= -1;
+ y *= -1;
+ z *= -1;
+ return *this;
+ }
+
+ Quaternion& operator*(float factor)
+ {
+ x *= factor;
+ y *= factor;
+ z *= factor;
+ w *= factor;
+ return *this;
+ }
+ float x, y, z, w;
+ };
+
+ struct Float3 {
+ Float3(float a, float b, float c)
+ : data { a, b, c } { }
+
+ float data[3];
+ };
+
+ void clear()
+ {
+ timestamp = 0;
+ position = std::nullopt;
+ orientation = std::nullopt;
+ angularAcceleration = std::nullopt;
+ angularVelocity = std::nullopt;
+ linearAcceleration = std::nullopt;
+ linearVelocity = std::nullopt;
+ }
+
+ std::optional<Quaternion> orientation;
+ std::optional<FloatPoint3D> position;
+ std::optional<Float3> angularAcceleration;
+ std::optional<Float3> angularVelocity;
+ std::optional<Float3> linearAcceleration;
+ std::optional<Float3> linearVelocity;
+ double timestamp { 0 };
+};
+
class VRPlatformDisplay {
public:
virtual VRPlatformDisplayInfo getDisplayInfo() = 0;
+ virtual VRPlatformTrackingInfo getTrackingInfo() = 0;
virtual ~VRPlatformDisplay() = default;
WeakPtr<VRPlatformDisplay> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
Modified: trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.cpp (230427 => 230428)
--- trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.cpp 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.cpp 2018-04-09 14:40:51 UTC (rev 230428)
@@ -50,6 +50,8 @@
// FIXME: We're assuming an HTC Vive HMD here. Get this info from OpenVR?.
m_displayInfo.setCapabilityFlags(VRDisplayCapabilityFlag::None | VRDisplayCapabilityFlag::Position | VRDisplayCapabilityFlag::Orientation | VRDisplayCapabilityFlag::ExternalDisplay | VRDisplayCapabilityFlag::Present);
+ m_compositor->SetTrackingSpace(vr::TrackingUniverseSeated);
+
updateEyeParameters();
updateStageParameters();
}
@@ -99,6 +101,63 @@
m_displayInfo.setPlayAreaBounds(FloatSize(playAreaWidth, playAreaDepth));
}
+// FIXME: we might want to generalize this function for other backends.
+static VRPlatformTrackingInfo::Quaternion rotationMatrixToQuaternion(const float (&matrix)[3][4])
+{
+ // See https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf.
+ VRPlatformTrackingInfo::Quaternion quaternion;
+ float trace;
+ if (matrix[2][2] < 0) {
+ if (matrix[0][0] > matrix[1][1]) {
+ trace = 1 + matrix[0][0] - matrix[1][1] - matrix[2][2];
+ quaternion = { trace, matrix[0][1]+matrix[1][0], matrix[2][0]+matrix[0][2], matrix[1][2] - matrix[2][1] };
+ } else {
+ trace = 1 - matrix[0][0] + matrix[1][1] - matrix[2][2];
+ quaternion = { matrix[0][1]+matrix[1][0], trace, matrix[1][2]+matrix[2][1], matrix[2][0] - matrix[0][2] };
+ }
+ } else {
+ if (matrix[0][0] < -matrix[1][1]) {
+ trace = 1 - matrix[0][0] - matrix[1][1] + matrix[2][2];
+ quaternion = { matrix[2][0]+matrix[0][2], matrix[1][2]+matrix[2][1], trace , matrix[0][1] - matrix[1][0] };
+ } else {
+ trace = 1 + matrix[0][0] + matrix[1][1] + matrix[2][2];
+ quaternion = { matrix[1][2] - matrix[2][1], matrix[2][0] - matrix[0][2], matrix[0][1] - matrix[1][0], trace };
+ }
+ }
+ return quaternion * (0.5 / sqrt(trace));
+}
+
+VRPlatformTrackingInfo VRPlatformDisplayOpenVR::getTrackingInfo()
+{
+ vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
+
+ m_compositor->WaitGetPoses(nullptr, 0, poses, vr::k_unMaxTrackedDeviceCount);
+
+ m_trackingInfo.clear();
+
+ vr::Compositor_FrameTiming timing;
+ timing.m_nSize = sizeof(vr::Compositor_FrameTiming);
+ m_compositor->GetFrameTiming(&timing);
+ m_trackingInfo.timestamp = timing.m_flSystemTimeInSeconds;
+
+ if (!poses[vr::k_unTrackedDeviceIndex_Hmd].bDeviceIsConnected
+ || !poses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid
+ || poses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult != vr::TrackingResult_Running_OK) {
+ // FIXME: Init some data maybe???.
+ return m_trackingInfo;
+ }
+
+ const auto& HMDPose = poses[vr::k_unTrackedDeviceIndex_Hmd];
+ const auto& transform = HMDPose.mDeviceToAbsoluteTracking;
+ m_trackingInfo.orientation = rotationMatrixToQuaternion(transform.m);
+ m_trackingInfo.orientation->conjugate();
+ m_trackingInfo.position = FloatPoint3D(transform.m[0][3], transform.m[1][3], transform.m[2][3]);
+ m_trackingInfo.angularVelocity = VRPlatformTrackingInfo::Float3(HMDPose.vAngularVelocity.v[0], HMDPose.vAngularVelocity.v[1], HMDPose.vAngularVelocity.v[2]);
+ m_trackingInfo.linearVelocity = VRPlatformTrackingInfo::Float3(HMDPose.vVelocity.v[0], HMDPose.vVelocity.v[1], HMDPose.vVelocity.v[2]);
+
+ return m_trackingInfo;
+}
+
}; // namespace WebCore
#endif // USE(OPENVR)
Modified: trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.h (230427 => 230428)
--- trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.h 2018-04-09 13:56:21 UTC (rev 230427)
+++ trunk/Source/WebCore/platform/vr/openvr/VRPlatformDisplayOpenVR.h 2018-04-09 14:40:51 UTC (rev 230428)
@@ -34,6 +34,7 @@
~VRPlatformDisplayOpenVR() = default;
VRPlatformDisplayInfo getDisplayInfo() override { return m_displayInfo; }
+ VRPlatformTrackingInfo getTrackingInfo() override;
private:
VRPlatformDisplayInfo::FieldOfView computeFieldOfView(vr::Hmd_Eye);
@@ -47,6 +48,7 @@
vr::IVRCompositor* m_compositor;
VRPlatformDisplayInfo m_displayInfo;
+ VRPlatformTrackingInfo m_trackingInfo;
};
}; // namespace WebCore