An update will be applied January 25th, between 12PM and 1:00PM EST (UTC -5:00). The site may be slow during that time.

Commit eb6bf099 authored by Ken Martin's avatar Ken Martin
Browse files

update openvr support to better handle events

Includes support for trackpad event data

Fix for new steam vr version that adds many events causing
delays in butten response.

Fixes picking when using multisamples.

Better hardware picking by starting at the center pick point
and working out.

New menthods in the menuwidget and rep to rename/remove menu items

Remap next pose control to left trigger so as to not overload
the grip buttons.

Handle higlighting of picked lines and polylines better.

Fix issues with the panel representation when it is called
before the controllers have been loaded.

Fix an issue when hardware line width was being forced by the
render window to a different value.

Better handling of pose for unloaded or untracked devices.
parent 14f65676
......@@ -175,10 +175,29 @@ public:
this->WorldOrientation[3] = p[3];
}
void GetTrackPadPosition(double v[2]) const {
v[0] = this->TrackPadPosition[0];
v[1] = this->TrackPadPosition[1];
}
const double *GetTrackPadPosition() const {
return this->TrackPadPosition;
}
void SetTrackPadPosition(const double p[2])
{
this->TrackPadPosition[0] = p[0];
this->TrackPadPosition[1] = p[1];
}
void SetTrackPadPosition(double x, double y)
{
this->TrackPadPosition[0] = x;
this->TrackPadPosition[1] = y;
}
protected:
double WorldPosition[3];
double WorldOrientation[4];
double WorldDirection[3];
double TrackPadPosition[2];
vtkEventDataDevice3D() {}
~vtkEventDataDevice3D() override {}
......
......@@ -161,7 +161,7 @@ void vtkOpenVRCamera::Render(vtkRenderer *ren)
if (this->LeftEye)
{
// Left Eye
if (win->GetMultiSamples())
if (win->GetMultiSamples() && !ren->GetSelector())
{
glEnable( GL_MULTISAMPLE );
}
......@@ -176,7 +176,7 @@ void vtkOpenVRCamera::Render(vtkRenderer *ren)
else
{
// right eye
if (win->GetMultiSamples())
if (win->GetMultiSamples() && !ren->GetSelector())
{
glEnable( GL_MULTISAMPLE );
}
......
......@@ -94,20 +94,35 @@ int vtkOpenVRHardwarePicker::PickProp(
int *size = renderer->GetSize();
sel->SetArea(size[0]/2 - 2, size[1]/2 - 2, size[0]/2 + 1, size[1]/2 + 1);
sel->SetArea(size[0]/2 - 5, size[1]/2 - 5, size[0]/2 + 5, size[1]/2 + 5);
if (this->Selection)
{
this->Selection->Delete();
}
this->Selection = sel->Select();
this->Selection = nullptr;
if (sel->CaptureBuffers())
{
unsigned int outPos[2];
unsigned int inPos[2] = {size[0]/2, size[1]/2};
// find the data closest to the center
vtkHardwareSelector::PixelInformation pinfo =
sel->GetPixelInformation(inPos, 5, outPos);
if (pinfo.Valid)
{
this->Selection = sel->GenerateSelection(outPos[0], outPos[1], outPos[0], outPos[1]);
}
}
// this->Selection = sel->Select();
// sel->SetArea(0, 0, size[0]-1, size[1]-1);
renWin->SetTrackHMD(true);
this->InvokeEvent(vtkCommand::EndPickEvent, this->Selection);
if (this->Selection->GetNode(0))
if (this->Selection && this->Selection->GetNode(0))
{
return 1;
}
......
......@@ -1020,11 +1020,27 @@ void vtkOpenVRInteractorStyle::ShowPickCell(vtkCell *cell, vtkProp3D *prop)
this->PickActor->GetProperty()->SetColor(this->PickColor);
int nedges = cell->GetNumberOfEdges();
for (int edgenum = 0; edgenum < nedges; ++edgenum)
if (nedges)
{
for (int edgenum = 0; edgenum < nedges; ++edgenum)
{
vtkCell *edge = cell->GetEdge(edgenum);
vtkPoints *pts = edge->GetPoints();
int npts = edge->GetNumberOfPoints();
lines->InsertNextCell(npts);
for (int ep = 0; ep < npts; ++ep)
{
vtkIdType newpt = pdpts->InsertNextPoint(pts->GetPoint(ep));
lines->InsertCellPoint(newpt);
}
}
}
else if (cell->GetCellType() == VTK_LINE ||
cell->GetCellType() == VTK_POLY_LINE)
{
vtkCell *edge = cell->GetEdge(edgenum);
vtkPoints *pts = edge->GetPoints();
int npts = edge->GetNumberOfPoints();
vtkPoints *pts = cell->GetPoints();
int npts = cell->GetNumberOfPoints();
lines->InsertNextCell(npts);
for (int ep = 0; ep < npts; ++ep)
{
......@@ -1032,8 +1048,13 @@ void vtkOpenVRInteractorStyle::ShowPickCell(vtkCell *cell, vtkProp3D *prop)
lines->InsertCellPoint(newpt);
}
}
pd->SetPoints(pdpts);
pd->SetLines(lines);
else
{
return;
}
pd->SetPoints(pdpts.Get());
pd->SetLines(lines.Get());
if (prop)
{
......
......@@ -81,11 +81,6 @@ void vtkOpenVRMenuRepresentation::PushFrontMenuItem(
const char *text,
vtkCommand *cmd)
{
// if (this->Menus.find(text) != this->Menus.end())
// {
// return;
// }
vtkOpenVRMenuRepresentation::InternalElement *el =
new vtkOpenVRMenuRepresentation::InternalElement();
el->TextActor->SetInput(text);
......@@ -95,6 +90,42 @@ void vtkOpenVRMenuRepresentation::PushFrontMenuItem(
this->Modified();
}
void vtkOpenVRMenuRepresentation::RenameMenuItem(
const char *name, const char *text)
{
for (auto itr : this->Menus)
{
if (itr->Name == name)
{
itr->TextActor->SetInput(text);
}
}
}
void vtkOpenVRMenuRepresentation::RemoveMenuItem(
const char *name)
{
for (auto itr = this->Menus.begin(); itr != this->Menus.end(); ++itr)
{
if ((*itr)->Name == name)
{
delete *itr;
this->Menus.erase(itr);
return;
}
}
}
void vtkOpenVRMenuRepresentation::RemoveAllMenuItems()
{
while (this->Menus.size() > 0)
{
auto itr = this->Menus.begin();
delete *itr;
this->Menus.erase(itr);
}
}
void vtkOpenVRMenuRepresentation::StartComplexInteraction(
vtkRenderWindowInteractor *,
vtkAbstractWidget *,
......
......@@ -85,11 +85,15 @@ public:
int RenderOverlay(vtkViewport*) override;
//@}
//@{
/**
* Method to add items to the menu, called by the menu widget
* Methods to add/remove items to the menu, called by the menu widget
*/
void PushFrontMenuItem(const char *name, const char *text, vtkCommand *cmd);
void RenameMenuItem(const char *name, const char *text);
void RemoveMenuItem(const char *name);
void RemoveAllMenuItems();
//@}
vtkGetMacro(CurrentOption, double);
......
......@@ -105,6 +105,49 @@ void vtkOpenVRMenuWidget::PushFrontMenuItem(
this->Modified();
}
void vtkOpenVRMenuWidget::RenameMenuItem(
const char *name, const char *text)
{
for (auto itr : this->Menus)
{
if (itr->Name == name)
{
itr->Text = text;
}
}
static_cast<vtkOpenVRMenuRepresentation *>(this->WidgetRep)->
RenameMenuItem(name, text);
}
void vtkOpenVRMenuWidget::RemoveMenuItem(
const char *name)
{
for (auto itr = this->Menus.begin(); itr != this->Menus.end(); ++itr)
{
if ((*itr)->Name == name)
{
delete *itr;
this->Menus.erase(itr);
return;
}
}
static_cast<vtkOpenVRMenuRepresentation *>(this->WidgetRep)->
RemoveMenuItem(name);
}
void vtkOpenVRMenuWidget::RemoveAllMenuItems()
{
while (this->Menus.size() > 0)
{
auto itr = this->Menus.begin();
delete *itr;
this->Menus.erase(itr);
}
static_cast<vtkOpenVRMenuRepresentation *>(this->WidgetRep)->
RemoveAllMenuItems();
}
void vtkOpenVRMenuWidget::EventCallback(
vtkObject *,
unsigned long,
......
......@@ -77,7 +77,15 @@ public:
void AddTooltip(vtkProp *prop, vtkStdString* str);
void AddTooltip(vtkProp *prop, const char* str);
void PushFrontMenuItem(const char * name, const char *text, vtkCommand *cmd);
//@{
/**
* Methods to add/remove items to the menu, called by the menu widget
*/
void PushFrontMenuItem(const char *name, const char *text, vtkCommand *cmd);
void RenameMenuItem(const char *name, const char *text);
void RemoveMenuItem(const char *name);
void RemoveAllMenuItems();
//@}
void Show(vtkEventData *ed);
void ShowSubMenu(vtkOpenVRMenuWidget *);
......
......@@ -390,44 +390,50 @@ void vtkOpenVRPanelRepresentation::ComputeMatrix(vtkRenderer *ren)
if (this->CoordinateSystem == LeftController)
{
vr::TrackedDevicePose_t &tdPose =
rw->GetTrackedDevicePose(vtkEventDataDevice::LeftController);
double pos[3];
double ppos[3];
double wxyz[4];
double wdir[3];
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
->ConvertPoseToWorldCoordinates(tdPose, pos, wxyz, ppos, wdir);
double scale = rw->GetPhysicalScale();
this->TempTransform->Identity();
this->TempTransform->PreMultiply();
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
this->TempTransform->Scale(scale, scale, scale);
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
vr::TrackedDevicePose_t *tdPose;
rw->GetTrackedDevicePose(vtkEventDataDevice::LeftController, &tdPose);
if (tdPose && tdPose->bPoseIsValid)
{
double pos[3];
double ppos[3];
double wxyz[4];
double wdir[3];
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
->ConvertPoseToWorldCoordinates(*tdPose, pos, wxyz, ppos, wdir);
double scale = rw->GetPhysicalScale();
this->TempTransform->Identity();
this->TempTransform->PreMultiply();
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
this->TempTransform->Scale(scale, scale, scale);
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
}
}
if (this->CoordinateSystem == RightController)
{
vr::TrackedDevicePose_t &tdPose =
rw->GetTrackedDevicePose(vtkEventDataDevice::RightController);
double pos[3];
double ppos[3];
double wxyz[4];
double wdir[3];
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
->ConvertPoseToWorldCoordinates(tdPose, pos, wxyz, ppos, wdir);
double scale = rw->GetPhysicalScale();
this->TempTransform->Identity();
this->TempTransform->PreMultiply();
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
this->TempTransform->Scale(scale, scale, scale);
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
vr::TrackedDevicePose_t *tdPose;
rw->GetTrackedDevicePose(vtkEventDataDevice::RightController, &tdPose);
if (tdPose && tdPose->bPoseIsValid)
{
double pos[3];
double ppos[3];
double wxyz[4];
double wdir[3];
static_cast<vtkOpenVRRenderWindowInteractor *>(rw->GetInteractor())
->ConvertPoseToWorldCoordinates(*tdPose, pos, wxyz, ppos, wdir);
double scale = rw->GetPhysicalScale();
this->TempTransform->Identity();
this->TempTransform->PreMultiply();
this->TempTransform->Translate(pos[0], pos[1], pos[2]);
this->TempTransform->Scale(scale, scale, scale);
this->TempTransform->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
this->TextActor->GetUserMatrix()->DeepCopy(this->TempTransform->GetMatrix());
}
}
}
}
......
......@@ -275,6 +275,8 @@ vtkOpenVRModel *vtkOpenVRRenderWindow::FindOrLoadRenderModel(
void vtkOpenVRRenderWindow::RenderModels()
{
glEnable(GL_DEPTH_TEST);
bool bIsInputCapturedByAnotherProcess =
this->HMD->IsInputFocusCapturedByAnotherProcess();
......@@ -630,10 +632,13 @@ void vtkOpenVRRenderWindow::Initialize (void)
this->OpenGLInit();
// this->OpenGLInit();
// some classes override the ivar in a getter :-(
this->MaximumHardwareLineWidth = this->HelperWindow->GetMaximumHardwareLineWidth();
glDepthRange(0., 1.);
// make sure vsync is off
// this->HelperWindow->SetSwapControl(0);
m_strDriver = "No Driver";
m_strDisplay = "No Display";
......@@ -736,8 +741,13 @@ vtkOpenVRModel *vtkOpenVRRenderWindow::GetTrackedDeviceModel(vtkEventDataDevice
return nullptr;
}
vr::TrackedDevicePose_t &vtkOpenVRRenderWindow::GetTrackedDevicePose(vtkEventDataDevice dev)
void vtkOpenVRRenderWindow::GetTrackedDevicePose(
vtkEventDataDevice dev, vr::TrackedDevicePose_t **pose)
{
vr::TrackedDeviceIndex_t idx = this->GetTrackedDeviceIndexForDevice(dev);
return this->GetTrackedDevicePose(idx);
*pose = nullptr;
if (idx < vr::k_unMaxTrackedDeviceCount)
{
*pose = &(this->TrackedDevicePose[idx]);
}
}
......@@ -124,7 +124,7 @@ public:
/**
* Get the most recent pose corresponding to the tracked device
*/
vr::TrackedDevicePose_t &GetTrackedDevicePose(vtkEventDataDevice idx);
void GetTrackedDevicePose(vtkEventDataDevice idx, vr::TrackedDevicePose_t **pose);
vr::TrackedDevicePose_t &GetTrackedDevicePose(vr::TrackedDeviceIndex_t idx) {
return this->TrackedDevicePose[idx]; };
......
......@@ -282,7 +282,8 @@ void vtkOpenVRRenderWindowInteractor::DoOneEvent(vtkOpenVRRenderWindow *renWin,
{
result = pHMD->PollNextEvent(&event, sizeof(vr::VREvent_t));
if (result)
// process all pending events
while (result)
{
vr::TrackedDeviceIndex_t tdi = event.trackedDeviceIndex;
......@@ -337,6 +338,17 @@ void vtkOpenVRRenderWindowInteractor::DoOneEvent(vtkOpenVRRenderWindow *renWin,
break;
case vr::EVRButtonId::k_EButton_Axis0:
ed->SetInput(vtkEventDataDeviceInput::TrackPad);
vr::VRControllerState_t cstate;
pHMD->GetControllerState(tdi, &cstate, sizeof(cstate));
for (unsigned int i = 0; i < vr::k_unControllerStateAxisCount; i++)
{
if (pHMD->GetInt32TrackedDeviceProperty(tdi,
static_cast<vr::ETrackedDeviceProperty>(vr::ETrackedDeviceProperty::Prop_Axis0Type_Int32 + i))
== vr::EVRControllerAxisType::k_eControllerAxis_TrackPad)
{
ed->SetTrackPadPosition(cstate.rAxis[i].x,cstate.rAxis[i].y);
}
}
break;
case vr::EVRButtonId::k_EButton_Grip:
ed->SetInput(vtkEventDataDeviceInput::Grip);
......@@ -375,6 +387,8 @@ void vtkOpenVRRenderWindowInteractor::DoOneEvent(vtkOpenVRRenderWindow *renWin,
//----------------------------------------------------------------------------
}
}
result = pHMD->PollNextEvent(&event, sizeof(vr::VREvent_t));
}
// for each controller create mouse move event
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment