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:
committed by
GitHub
parent
7c3164ff61
commit
ad419828b0
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user