Skip to content

Commit

Permalink
Initial raypicking work
Browse files Browse the repository at this point in the history
  • Loading branch information
kwahoo2 committed Feb 21, 2021
1 parent 4d2a0e4 commit 79c7e00
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
65 changes: 56 additions & 9 deletions src/Gui/CoinXRWidget.cpp
Expand Up @@ -113,6 +113,7 @@ CoinXRWidget::~CoinXRWidget()
instance.destroy();
instance = nullptr;
}

delete m_sceneManager;
format().setDefaultFormat(oldFormat);
doneCurrent();
Expand All @@ -126,8 +127,7 @@ void CoinXRWidget::setBackgroundColor(const SbColor &Col)

void CoinXRWidget::setSceneGraph(SoNode *sceneGraph)
{
sGrp[0]->replaceChild(scene, sceneGraph);
sGrp[1]->replaceChild(scene, sceneGraph);
wSep->replaceChild(scene, sceneGraph);
scene = sceneGraph;
}

Expand Down Expand Up @@ -173,8 +173,6 @@ void CoinXRWidget::paintGL()
if (quit) {
return;
}
makeCurrent();

GLint oldfb;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);

Expand Down Expand Up @@ -232,8 +230,8 @@ void CoinXRWidget::paintGL()
swapchain.releaseSwapchainImage(xr::SwapchainImageReleaseInfo{});

update(); //schedule QOpenGL composition
doneCurrent();
}
updateXrGui();
qint64 et = eTimer.nsecsElapsed();
eTimer.restart();

Expand Down Expand Up @@ -647,9 +645,31 @@ void CoinXRWidget::prepareScene()

scene = new SoSeparator(0); // Placeholder.

wSep = new SoSeparator;
worldTransform = new SoTransform(); //use for navigation in the world
transfMod = new SoTransform(); //modifier of transformation

wSep->addChild(worldTransform);
wSep->addChild(scene);

//ray for picking objects
rayVtxs = new SoVertexProperty();
rayVtxs->vertex.set1Value(0, 0, 0, 0); // Set first vertex, later update to center of the controller
rayVtxs->vertex.set1Value(1, 0, 0, 1); // Set second vertex, later update to point of intersection ray with hit object
rayLine = new SoLineSet();
rayLine->vertexProperty = rayVtxs;
SoBaseColor * rayCol = new SoBaseColor; //blue sphere to show intersection point
rayCol->rgb = SbColor(1, 0, 0);
rSep = new SoSeparator();
rSep->addChild(rayCol);
rSep->addChild(rayLine); //only one controller will shoot the ray
sphTrans = new SoTranslation;
sphTrans->translation.setValue(0, 0, 0);
rSep->addChild(sphTrans);
raySph = new SoSphere;
raySph->radius.setValue(0.02f);
rSep->addChild(raySph);

xr::for_each_side_index([&](uint32_t eyeIndex) {
rootScene[eyeIndex] = new SoSeparator;
cGrp[eyeIndex] = new SoGroup();
Expand Down Expand Up @@ -686,9 +706,11 @@ void CoinXRWidget::prepareScene()
con1Sep[eyeIndex]->addChild(stickRotat[1]);
con1Sep[eyeIndex]->addChild(conStick[1]);

//add ray for picking objects for each eye
sGrp[eyeIndex]->addChild(rSep);

//add scene
sGrp[eyeIndex]->addChild(worldTransform);
sGrp[eyeIndex]->addChild(scene);
sGrp[eyeIndex]->addChild(wSep);

});

Expand Down Expand Up @@ -876,7 +898,7 @@ void CoinXRWidget::updateXrControls()
//float mat21 = 2*qy*qz+2*qx*qw;
float mat22 = 1-2*qx*qx-2*qy*qy;

if (i == 0){
if (i == primaryConId){
SbVec3f step = SbVec3f(0.0f, 0.0f, 0.0f);
float z0 = mat02;
float z1 = mat12;
Expand All @@ -885,7 +907,7 @@ void CoinXRWidget::updateXrControls()
worldTransform->translation.setValue(worldTransform->translation.getValue() + step);

}
if (i == 1){
if (i == secondaryConId){
transfMod->center.setValue(conpos[i]);
SbVec3f conXaxis = SbVec3f(mat00, mat10, mat20);
SbVec3f conZaxis = SbVec3f(mat02, mat12, mat22);
Expand All @@ -896,6 +918,7 @@ void CoinXRWidget::updateXrControls()
padrot.scaleAngle(0.5f * movSpeed);
transfMod->rotation.setValue(padrot);
worldTransform->combineRight(transfMod);
rayAxis = conZaxis;
}

//XRInteraction
Expand All @@ -904,6 +927,30 @@ void CoinXRWidget::updateXrControls()
mXRi->resumeThread();
}

void CoinXRWidget::updateXrGui()
{

//picking ray
SbVec3f startVec = conTrans[secondaryConId]->translation.getValue();
SbVec3f endVec = conTrans[secondaryConId]->translation.getValue() - rayAxis;
SoRayPickAction conPickAction(vpReg);
conPickAction.setRay(startVec, - rayAxis, //direction is reversed controller Z axis
nearPlane, farPlane);

rayVtxs->vertex.set1Value(0, startVec);
rayVtxs->vertex.set1Value(1, endVec);

conPickAction.apply(wSep); //traverse only the world, avoid picking controller gizmos or other non-world objects
const SoPickedPoint *pickedPoint = conPickAction.getPickedPoint();

if (pickedPoint != nullptr)
{
SbVec3f pickedPCoords = pickedPoint->getPoint();
sphTrans->translation.setValue(pickedPCoords);
rayVtxs->vertex.set1Value(1, pickedPCoords);
}
}

void CoinXRWidget::endXrFrame()
{
xr::FrameEndInfo frameEndInfo{ frameState.predictedDisplayTime, xr::EnvironmentBlendMode::Opaque };
Expand Down
20 changes: 20 additions & 0 deletions src/Gui/CoinXRWidget.h
Expand Up @@ -90,8 +90,17 @@
#include <Inventor/nodes/SoScale.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoTransform.h>

#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoVertexProperty.h>
#include <Inventor/nodes/SoScale.h>
#include <Inventor/SbViewportRegion.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/nodes/SoBaseColor.h>

#include "XRInteraction.h"

//QOpenGLWidget is a modern replacement for QGLWidget, it performs offscreen rendering
Expand All @@ -102,6 +111,7 @@ class CoinXRWidget : public QOpenGLWidget , protected QOpenGLFunctions_4_5_Core
SoSeparator *rootScene[2];
SoFrustumCamera *camera[2];
SoNode *scene;
SoSeparator *wSep;
SoTranslation *camTrans[2];
SoGroup *cGrp[2];
SoGroup *sGrp[2];
Expand All @@ -117,6 +127,13 @@ class CoinXRWidget : public QOpenGLWidget , protected QOpenGLFunctions_4_5_Core
QSurfaceFormat oldFormat;
SoSeparator *conMenuSep;

SoSeparator *rSep;
SoVertexProperty *rayVtxs;
SoLineSet *rayLine;
SbVec3f rayAxis;
SoSphere *raySph;
SoTranslation *sphTrans;

bool quit{ false };
static const uint32_t hands = 2;
uint32_t m_nRenderWidth;
Expand Down Expand Up @@ -152,6 +169,8 @@ class CoinXRWidget : public QOpenGLWidget , protected QOpenGLFunctions_4_5_Core
float scaleMod;
float currTriggerVal[hands];
QElapsedTimer eTimer; //measure time of frame
uint32_t primaryConId = 0; //left one one most systemes
uint32_t secondaryConId = 1;

std::vector<xr::CompositionLayerBaseHeader*> layersPointers;

Expand All @@ -169,6 +188,7 @@ class CoinXRWidget : public QOpenGLWidget , protected QOpenGLFunctions_4_5_Core
void updateXrControls();
void onSessionStateChanged(const xr::EventDataSessionStateChanged& sessionStateChangedEvent);

void updateXrGui();
//XRInteraction
XRInteraction *mXRi;

Expand Down

0 comments on commit 79c7e00

Please sign in to comment.