diff --git a/src/Gui/3Dconnexion/navlib/NavlibInterface.h b/src/Gui/3Dconnexion/navlib/NavlibInterface.h index e7f7ae795d..b78a745503 100644 --- a/src/Gui/3Dconnexion/navlib/NavlibInterface.h +++ b/src/Gui/3Dconnexion/navlib/NavlibInterface.h @@ -161,5 +161,7 @@ private: mutable std::array hitTestPattern; mutable bool patternInitialized; std::vector exportedCommandSets; + mutable bool wasPointerPick = false; + double orthoNearDistance = 0.0; }; #endif \ No newline at end of file diff --git a/src/Gui/3Dconnexion/navlib/NavlibNavigation.cpp b/src/Gui/3Dconnexion/navlib/NavlibNavigation.cpp index 5acd45cd36..df24487cf7 100644 --- a/src/Gui/3Dconnexion/navlib/NavlibNavigation.cpp +++ b/src/Gui/3Dconnexion/navlib/NavlibNavigation.cpp @@ -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(viewVolume.getHeight() / 2.0f); + const double halfWidth = static_cast(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; } diff --git a/src/Gui/3Dconnexion/navlib/NavlibPivot.cpp b/src/Gui/3Dconnexion/navlib/NavlibPivot.cpp index 1b8ed7524b..8c0ac446e7 100644 --- a/src/Gui/3Dconnexion/navlib/NavlibPivot.cpp +++ b/src/Gui/3Dconnexion/navlib/NavlibPivot.cpp @@ -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(); + 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; }