Skip to content

Commit

Permalink
Making WaveVR controllers support haptics feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
daoshengmu committed Nov 8, 2019
1 parent 3a5a1bc commit 9a28f98
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,14 @@ BrowserWorld::Draw() {
m.context->Update();
m.externalVR->PullBrowserState();

const uint32_t count = m.controllers->GetControllerCount();
for (uint32_t i = 0; i < count; ++i) {
float pulseStart = 0, pulseDuration = 0, pulseIntensity = 0;
uint64_t inputFrameID = 0;
m.externalVR->GetHapticState(i, inputFrameID, pulseStart, pulseDuration, pulseIntensity);
m.controllers->SetHapticsFeedback(i, inputFrameID, pulseDuration + pulseStart, pulseIntensity);
}

m.CheckExitImmersive();
if (m.splashAnimation) {
DrawSplashAnimation();
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/cpp/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ Controller::operator=(const Controller& aController) {
numButtons = aController.numButtons;
memcpy(immersiveAxes, aController.immersiveAxes, sizeof(immersiveAxes));
numAxes = aController.numAxes;
numHaptics = aController.numHaptics;
inputFrameID = aController.inputFrameID;
pulseDuration = aController.pulseDuration;
pulseIntensity = aController.pulseIntensity;
leftHanded = aController.leftHanded;
inDeadZone = aController.inDeadZone;
lastHoverEvent = aController.lastHoverEvent;
Expand Down Expand Up @@ -91,6 +95,10 @@ Controller::Reset() {
numButtons = 0;
memset(immersiveAxes, 0, sizeof(immersiveAxes));
numAxes = 0;
numHaptics = 0;
inputFrameID = 0;
pulseDuration = 0.0f;
pulseIntensity = 0.0f;
leftHanded = false;
inDeadZone = true;
lastHoverEvent = 0.0;
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/cpp/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ struct Controller {
uint32_t numButtons;
float immersiveAxes[kControllerMaxAxes];
uint32_t numAxes;
uint32_t numHaptics;
float inputFrameID;
float pulseDuration;
float pulseIntensity;

bool leftHanded;
bool inDeadZone;
double lastHoverEvent;
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/cpp/ControllerContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,36 @@ ControllerContainer::SetAxes(const int32_t aControllerIndex, const float* aData,
}
}

void
ControllerContainer::SetHapticsCount(const int32_t aControllerIndex, const uint32_t aNumHaptics) {
if (!m.Contains(aControllerIndex)) {
return;
}
m.list[aControllerIndex].numHaptics = aNumHaptics;
}

void
ControllerContainer::SetHapticsFeedback(const int32_t aControllerIndex, const uint64_t aInputFrameID,
const float aPulseDuration, const float aPulseIntensity) {
if (!m.Contains(aControllerIndex)) {
return;
}
m.list[aControllerIndex].inputFrameID = aInputFrameID;
m.list[aControllerIndex].pulseDuration = aPulseDuration;
m.list[aControllerIndex].pulseIntensity = aPulseIntensity;
}

void
ControllerContainer::GetHapticsFeedback(const int32_t aControllerIndex, uint64_t & aInputFrameID,
float& aPulseDuration, float& aPulseIntensity) {
if (!m.Contains(aControllerIndex)) {
return;
}
aInputFrameID = m.list[aControllerIndex].inputFrameID;
aPulseDuration = m.list[aControllerIndex].pulseDuration;
aPulseIntensity = m.list[aControllerIndex].pulseIntensity;
}

void
ControllerContainer::SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) {
if (!m.Contains(aControllerIndex)) {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/ControllerContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class ControllerContainer : public crow::ControllerDelegate {
void SetButtonCount(const int32_t aControllerIndex, const uint32_t aNumButtons) override;
void SetButtonState(const int32_t aControllerIndex, const Button aWhichButton, const int32_t aImmersiveIndex, const bool aPressed, const bool aTouched, const float aImmersiveTrigger = -1.0f) override;
void SetAxes(const int32_t aControllerIndex, const float* aData, const uint32_t aLength) override;
void SetHapticsCount(const int32_t aControllerIndex, const uint32_t aNumHaptics) override;
void SetHapticsFeedback(const int32_t aControllerIndex, const uint64_t aInputFrameID, const float aPulseDuration, const float aPulseIntensity) override;
void GetHapticsFeedback(const int32_t aControllerIndex, uint64_t &aInputFrameID, float& aPulseDuration, float& aPulseIntensity) override;
void SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) override;
void SetTouchPosition(const int32_t aControllerIndex, const float aTouchX, const float aTouchY) override;
void EndTouch(const int32_t aControllerIndex) override;
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/cpp/ControllerDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class ControllerDelegate {
virtual void SetButtonCount(const int32_t aControllerIndex, const uint32_t aNumButtons) = 0;
virtual void SetButtonState(const int32_t aControllerIndex, const Button aWhichButton, const int32_t aImmersiveIndex, const bool aPressed, const bool aTouched, const float aImmersiveTrigger = -1.0f) = 0;
virtual void SetAxes(const int32_t aControllerIndex, const float* aData, const uint32_t aLength) = 0;
virtual void SetHapticsCount(const int32_t aControllerIndex, const uint32_t aNumHaptics) = 0;
virtual void SetHapticsFeedback(const int32_t aControllerIndex, const uint64_t aInputFrameID, const float aPulseDuration, const float aPulseIntensity) = 0;
virtual void GetHapticsFeedback(const int32_t aControllerIndex, uint64_t & aInputFrameID, float& aPulseDuration, float& aPulseIntensity) = 0;
virtual void SetLeftHanded(const int32_t aControllerIndex, const bool aLeftHanded) = 0;
virtual void SetTouchPosition(const int32_t aControllerIndex, const float aTouchX, const float aTouchY) = 0;
virtual void EndTouch(const int32_t aControllerIndex) = 0;
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/cpp/ExternalVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ ExternalVR::PushFramePoses(const vrb::Matrix& aHeadTransform, const std::vector<
for (int i = 0; i< controller.numAxes; ++i) {
immersiveController.axisValue[i] = controller.immersiveAxes[i];
}
immersiveController.numHaptics = controller.numHaptics;
immersiveController.hand = controller.leftHanded ? mozilla::gfx::ControllerHand::Left : mozilla::gfx::ControllerHand::Right;

const uint16_t flags = GetControllerCapabilityFlags(controller.deviceCapabilities);
Expand Down Expand Up @@ -489,6 +490,20 @@ ExternalVR::GetFrameResult(int32_t& aSurfaceHandle, int32_t& aTextureWidth, int3
aTextureHeight = (int32_t)m.browser.layerState[0].layer_stereo_immersive.textureSize.height;
}

void
ExternalVR::GetHapticState(uint32_t aControllerIndex, uint64_t& aInputFrameID, float& aPulseStart,
float& aPulseDuration, float& aPulseIntensity) const {
for (uint32_t i = 0; i < mozilla::gfx::kVRHapticsMaxCount; ++i) {
if (m.browser.hapticState[i].controllerIndex == aControllerIndex) {
aInputFrameID = m.browser.hapticState[i].inputFrameID;
aPulseDuration = m.browser.hapticState[i].pulseDuration;
aPulseStart = m.browser.hapticState[i].pulseStart;
aPulseIntensity = m.browser.hapticState[i].pulseIntensity;
return;
}
}
}

void
ExternalVR::StopPresenting() {
m.system.displayState.presentingGeneration++;
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/ExternalVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class ExternalVR : public ImmersiveDisplay {
int32_t& aTextureHeight,
device::EyeRect& aLeftEye,
device::EyeRect& aRightEye) const;
void GetHapticState(uint32_t aControllerIndex, uint64_t& aInputFrameID, float& aPulseStart,
float& aPulseDuration, float& aPulseIntensity) const;
void StopPresenting();
void SetSourceBrowser(VRBrowserType aBrowser);
ExternalVR();
Expand Down
22 changes: 22 additions & 0 deletions app/src/wavevr/cpp/DeviceDelegateWaveVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ struct DeviceDelegateWaveVR::State {
int32_t gripPressedCount;
vrb::Matrix transform;
ElbowModel::HandEnum hand;
bool doingVibration = false;

Controller()
: index(-1)
, type(WVR_DeviceType_Controller_Right)
Expand Down Expand Up @@ -350,6 +352,26 @@ struct DeviceDelegateWaveVR::State {
delegate->EndTouch(controller.index);
}
delegate->SetAxes(controller.index, immersiveAxes, kNumAxes);
delegate->SetHapticsCount(controller.index, 1);

uint64_t inputFrameID = 0;
float pulseDuration = 0.0f, pulseIntensity = 0.0f;
delegate->GetHapticsFeedback(controller.index, inputFrameID, pulseDuration, pulseIntensity);
if (inputFrameID == 0 || pulseDuration <= 0 ) {
// Stopping haptics feedback.
if (controller.doingVibration) {
WVR_TriggerVibration(controller.type, WVR_InputId_Max, 0.0f, 0);
controller.doingVibration = false;
}
} else if (pulseIntensity > 0.0f) {
controller.doingVibration = true;
// THe duration time unit needs to be transformed from milliseconds to microseconds.
// The gamepad extensions API does not yet have independent control
// of frequency and intensity. It only has vibration value (0.0 ~ 1.0).
// In this WaveVR SDK, the value makes more sense to be intensity because frequency can't
// < 1.0 here.
WVR_TriggerVibration(controller.type, WVR_InputId_Max, pulseDuration * 1000.0f, 1, pulseIntensity > 0.5f ? WVR_Intensity_Normal : WVR_Intensity_Strong);
}
}
}
};
Expand Down

0 comments on commit 9a28f98

Please sign in to comment.