Bug 1299932 - Part 3: Handle OpenVR controller position and orientation; r=kip

MozReview-Commit-ID: FyneJ5JfeNE

--HG--
extra : rebase_source : afd91ee94416285441397e6f51d6031c40fa5513
This commit is contained in:
Daosheng Mu 2016-10-24 18:09:11 +08:00
Родитель b3d0fb146a
Коммит 4d84c1a5cc
7 изменённых файлов: 97 добавлений и 1 удалений

Просмотреть файл

@ -186,3 +186,16 @@ VRControllerHost::GetButtonPressed()
{
return mButtonPressed;
}
void
VRControllerHost::SetPose(const dom::GamepadPoseState& aPose)
{
mPose = aPose;
}
const dom::GamepadPoseState&
VRControllerHost::GetPose()
{
return mPose;
}

Просмотреть файл

@ -16,6 +16,7 @@
#include "mozilla/EnumeratedArray.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/dom/GamepadPoseState.h"
namespace mozilla {
namespace layers {
@ -92,6 +93,8 @@ public:
uint32_t GetIndex();
void SetButtonPressed(uint64_t aBit);
uint64_t GetButtonPressed();
void SetPose(const dom::GamepadPoseState& aPose);
const dom::GamepadPoseState& GetPose();
protected:
explicit VRControllerHost(VRDeviceType aType);
@ -102,6 +105,7 @@ protected:
uint32_t mIndex;
// The current button pressed bit of button mask.
uint64_t mButtonPressed;
dom::GamepadPoseState mPose;
};
} // namespace gfx

Просмотреть файл

@ -94,6 +94,10 @@ VRManager::VRManager()
mManagers.AppendElement(mgr);
}
#endif
// Enable gamepad extensions while VR is enabled.
if (gfxPrefs::VREnabled()) {
Preferences::SetBool("dom.gamepad.extensions.enabled", true);
}
}
VRManager::~VRManager()

Просмотреть файл

@ -113,3 +113,15 @@ VRControllerManager::NewAxisMove(uint32_t aIndex, uint32_t aAxis,
MOZ_ASSERT(vm);
vm->NotifyGamepadChange<dom::GamepadAxisInformation>(a);
}
void
VRControllerManager::NewPoseState(uint32_t aIndex,
const dom::GamepadPoseState& aPose)
{
dom::GamepadPoseInformation a(aIndex, dom::GamepadServiceType::VR,
aPose);
VRManager* vm = VRManager::Get();
MOZ_ASSERT(vm);
vm->NotifyGamepadChange<dom::GamepadPoseInformation>(a);
}

Просмотреть файл

@ -20,6 +20,10 @@ namespace mozilla {
namespace layers {
class PTextureParent;
}
namespace dom {
enum class GamepadMappingType : uint32_t;
struct GamepadPoseState;
}
namespace gfx {
class VRLayerParent;
class VRDisplayHost;
@ -252,6 +256,7 @@ public:
virtual void ScanForDevices() = 0;
void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed);
void NewAxisMove(uint32_t aIndex, uint32_t aAxis, double aValue);
void NewPoseState(uint32_t aIndex, const dom::GamepadPoseState& aPose);
void AddGamepad(const char* aID, uint32_t aMapping,
uint32_t aNumButtons, uint32_t aNumAxes);
void RemoveGamepad(uint32_t aIndex);
@ -269,6 +274,9 @@ private:
uint64_t aButtonPressed) = 0;
virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
float aValue) = 0;
virtual void HandlePoseTracking(uint32_t aControllerIdx,
const dom::GamepadPoseState& aPose,
VRControllerHost* aController) = 0;
};
} // namespace gfx

Просмотреть файл

@ -490,7 +490,7 @@ VRControllerOpenVR::VRControllerOpenVR()
MOZ_COUNT_CTOR_INHERITED(VRControllerOpenVR, VRControllerHost);
mControllerInfo.mControllerName.AssignLiteral("OpenVR HMD");
#ifdef MOZ_GAMEPAD
mControllerInfo.mMappingType = static_cast<uint32_t>(dom::GamepadMappingType::_empty);
mControllerInfo.mMappingType = static_cast<uint32_t>(GamepadMappingType::_empty);
#else
mControllerInfo.mMappingType = 0;
#endif
@ -583,6 +583,9 @@ VRControllerManagerOpenVR::HandleInput()
MOZ_ASSERT(mVRSystem);
vr::TrackedDevicePose_t poses[vr::k_unMaxTrackedDeviceCount];
mVRSystem->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, 0.0f,
poses, vr::k_unMaxTrackedDeviceCount);
// Process OpenVR controller state
for (uint32_t i = 0; i < mOpenVRController.Length(); ++i) {
controller = mOpenVRController[i];
@ -605,6 +608,44 @@ VRControllerManagerOpenVR::HandleInput()
HandleAxisMove(controller->GetIndex(), axis,
state.rAxis[gOpenVRAxes[axis]].x);
}
// Start to process pose
const ::vr::TrackedDevicePose_t& pose = poses[controller->GetTrackedIndex()];
if (pose.bDeviceIsConnected && pose.bPoseIsValid &&
pose.eTrackingResult == vr::TrackingResult_Running_OK) {
gfx::Matrix4x4 m;
// NOTE! mDeviceToAbsoluteTracking is a 3x4 matrix, not 4x4. But
// because of its arrangement, we can copy the 12 elements in and
// then transpose them to the right place. We do this so we can
// pull out a Quaternion.
memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(float) * 12);
m.Transpose();
gfx::Quaternion rot;
rot.SetFromRotationMatrix(m);
rot.Invert();
GamepadPoseState poseState;
poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
poseState.orientation[0] = rot.x;
poseState.orientation[1] = rot.y;
poseState.orientation[2] = rot.z;
poseState.orientation[3] = rot.w;
poseState.angularVelocity[0] = pose.vAngularVelocity.v[0];
poseState.angularVelocity[1] = pose.vAngularVelocity.v[1];
poseState.angularVelocity[2] = pose.vAngularVelocity.v[2];
poseState.flags |= GamepadCapabilityFlags::Cap_Position;
poseState.position[0] = m._41;
poseState.position[1] = m._42;
poseState.position[2] = m._43;
poseState.linearVelocity[0] = pose.vVelocity.v[0];
poseState.linearVelocity[1] = pose.vVelocity.v[1];
poseState.linearVelocity[2] = pose.vVelocity.v[2];
HandlePoseTracking(controller->GetIndex(), poseState, controller);
}
}
}
@ -644,6 +685,17 @@ VRControllerManagerOpenVR::HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxi
}
}
void
VRControllerManagerOpenVR::HandlePoseTracking(uint32_t aControllerIdx,
const GamepadPoseState& aPose,
VRControllerHost* aController)
{
if (aPose != aController->GetPose()) {
aController->SetPose(aPose);
NewPoseState(aControllerIdx, aPose);
}
}
void
VRControllerManagerOpenVR::GetControllers(nsTArray<RefPtr<VRControllerHost>>& aControllerResult)
{

Просмотреть файл

@ -124,6 +124,9 @@ private:
uint64_t aButtonPressed) override;
virtual void HandleAxisMove(uint32_t aControllerIdx, uint32_t aAxis,
float aValue) override;
virtual void HandlePoseTracking(uint32_t aControllerIdx,
const dom::GamepadPoseState& aPose,
VRControllerHost* aController) override;
bool mOpenVRInstalled;
nsTArray<RefPtr<impl::VRControllerOpenVR>> mOpenVRController;