Update for 3Dconnexion NavLib integration (#18433)

* Fixed QuickZoom crash & picking in ortho view

* Fixed QuickZoom for high DPI screens

* Fixed return value for SetHitLookFrom

Co-authored-by: Benjamin Nauck <benjamin@nauck.se>

* Removed whitespace from GetPointerPosition

Co-authored-by: Benjamin Nauck <benjamin@nauck.se>

---------

Co-authored-by: Patryk Skowroński <pskowronski@3dconnexion.com>
Co-authored-by: Benjamin Nauck <benjamin@nauck.se>
This commit is contained in:
Patryk Skowroński
2024-12-13 15:41:11 +01:00
committed by GitHub
parent 7c3164ff61
commit ad419828b0
3 changed files with 71 additions and 43 deletions

View File

@@ -161,5 +161,7 @@ private:
mutable std::array<SbVec2f, hitTestingResolution> hitTestPattern;
mutable bool patternInitialized;
std::vector<std::string> exportedCommandSets;
mutable bool wasPointerPick = false;
double orthoNearDistance = 0.0;
};
#endif

View File

@@ -101,11 +101,16 @@ long NavlibInterface::GetPointerPosition(navlib::point_t& position) const
QPoint viewPoint = currentView.pView3d->mapFromGlobal(QCursor::pos());
viewPoint.setY(currentView.pView3d->height() - viewPoint.y());
double scaling = inventorViewer->devicePixelRatio();
viewPoint *= scaling;
SbVec3f worldPosition =
inventorViewer->getPointOnFocalPlane(SbVec2s(viewPoint.x(), viewPoint.y()));
std::copy(worldPosition.getValue(), worldPosition.getValue() + 3, &position.x);
wasPointerPick = true;
return 0;
}
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
@@ -269,34 +274,8 @@ long NavlibInterface::SetCameraMatrix(const navlib::matrix_t& matrix)
pCamera->orientation = SbRotation(cameraMatrix);
pCamera->position.setValue(matrix(3, 0), matrix(3, 1), matrix(3, 2));
const Gui::View3DInventorViewer* inventorViewer = currentView.pView3d->getViewer();
SoGetBoundingBoxAction action(inventorViewer->getSoRenderManager()->getViewportRegion());
action.apply(inventorViewer->getSceneGraph());
const SbBox3f boundingBox = action.getBoundingBox();
SbVec3f modelCenter = boundingBox.getCenter();
const float modelRadius = (boundingBox.getMin() - modelCenter).length();
navlib::bool_t isPerspective;
GetIsViewPerspective(isPerspective);
if (!isPerspective) {
cameraMatrix.inverse().multVecMatrix(modelCenter, modelCenter);
const float nearDist = -(modelRadius + modelCenter.getValue()[2]);
const float farDist = nearDist + 2.0f * modelRadius;
if (nearDist < 0.0f) {
pCamera->nearDistance.setValue(nearDist);
pCamera->farDistance.setValue(-nearDist);
}
else {
pCamera->nearDistance.setValue(-farDist);
pCamera->farDistance.setValue(farDist);
}
}
pCamera->touch();
return 0;
}
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
@@ -348,11 +327,16 @@ long NavlibInterface::GetViewExtents(navlib::box_t& extents) const
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
const SbViewVolume viewVolume = pCamera->getViewVolume(pCamera->aspectRatio.getValue());
const float halfHeight = viewVolume.getHeight() / 2.0f;
const float halfWidth = viewVolume.getWidth() / 2.0f;
const float farDistance = viewVolume.nearToFar + viewVolume.nearDist;
const double halfHeight = static_cast<double>(viewVolume.getHeight() / 2.0f);
const double halfWidth = static_cast<double>(viewVolume.getWidth() / 2.0f);
const double halfDepth = 1.0e8;
extents = {-halfWidth, -halfHeight, -farDistance, halfWidth, halfHeight, farDistance};
extents = {-halfWidth,
-halfHeight,
-halfDepth,
halfWidth,
halfHeight,
halfDepth};
return 0;
}
@@ -390,6 +374,7 @@ long NavlibInterface::SetViewExtents(const navlib::box_t& extents)
GetViewExtents(oldExtents);
pCamera->scaleHeight(extents.max.x / oldExtents.max.x);
orthoNearDistance = pCamera->nearDistance.getValue();
return 0;
}

View File

@@ -136,29 +136,50 @@ long NavlibInterface::GetHitLookAt(navlib::point_t& position) const
pCamera->orientation.getValue().getValue(cameraMatrix);
// Initialize the samples array if it wasn't done before
// Initialize the samples array if it wasn't done before
initializePattern();
navlib::bool_t isPerspective;
GetIsViewPerspective(isPerspective);
for (uint32_t i = 0; i < hitTestingResolution; i++) {
// Scale the sample like it was defined in camera space (placed on XY plane)
SbVec3f transform(
hitTestPattern[i][0] * ray.radius, hitTestPattern[i][1] * ray.radius, 0.0f);
// Apply the model-view transform to a sample (only the rotation)
cameraMatrix.multVecMatrix(transform, transform);
SbVec3f origin;
// Calculate origin of current hit-testing ray
SbVec3f newOrigin = ray.origin + transform;
if (wasPointerPick) {
origin = ray.origin;
}
else {
// Scale the sample like it was defined in camera space (placed on XY plane)
SbVec3f transform(hitTestPattern[i][0] * ray.radius,
hitTestPattern[i][1] * ray.radius,
0.0f);
// Apply the model-view transform to a sample (only the rotation)
cameraMatrix.multVecMatrix(transform, transform);
// Calculate origin of current hit-testing ray
origin = ray.origin + transform;
}
// Perform the hit-test
rayPickAction.setRay(newOrigin, ray.direction);
if (isPerspective) {
rayPickAction.setRay(origin,
ray.direction,
pCamera->nearDistance.getValue(),
pCamera->farDistance.getValue());
}
else {
rayPickAction.setRay(origin, ray.direction);
}
rayPickAction.apply(pSceneGraph);
SoPickedPoint* pickedPoint = rayPickAction.getPickedPoint();
// Check if there was a hit
if (pickedPoint != nullptr) {
SbVec3f hitPoint = pickedPoint->getPoint();
float distance = (newOrigin - hitPoint).length();
float distance = (origin - hitPoint).length();
// Save hit of the lowest depth
if (distance < minLength) {
@@ -166,6 +187,11 @@ long NavlibInterface::GetHitLookAt(navlib::point_t& position) const
closestHitPoint = hitPoint;
}
}
if (wasPointerPick) {
wasPointerPick = false;
break;
}
}
if (minLength < MAX_FLOAT) {
@@ -219,7 +245,22 @@ long NavlibInterface::SetHitDirection(const navlib::vector_t& direction)
long NavlibInterface::SetHitLookFrom(const navlib::point_t& eye)
{
ray.origin.setValue(eye.x, eye.y, eye.z);
navlib::bool_t isPerspective;
GetIsViewPerspective(isPerspective);
if (isPerspective) {
ray.origin.setValue(eye.x, eye.y, eye.z);
}
else {
auto pCamera = getCamera<SoCamera*>();
if (pCamera == nullptr) {
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
}
SbVec3f position = pCamera->position.getValue();
ray.origin = position + orthoNearDistance * ray.direction;
}
return 0;
}