Gui: Added classic trackball orbit style (#20535)
* Gui: add classic trackball orbit * Gui: add rounded arcball orbit
This commit is contained in:
@@ -64,7 +64,9 @@ public:
|
|||||||
enum OrbitStyle {
|
enum OrbitStyle {
|
||||||
Turntable,
|
Turntable,
|
||||||
Trackball,
|
Trackball,
|
||||||
FreeTurntable
|
FreeTurntable,
|
||||||
|
TrackballClassic,
|
||||||
|
RoundedArcball
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr float defaultSphereRadius = 0.8F;
|
static constexpr float defaultSphereRadius = 0.8F;
|
||||||
@@ -87,7 +89,112 @@ public:
|
|||||||
|
|
||||||
SbVec3f project(const SbVec2f &point) override
|
SbVec3f project(const SbVec2f &point) override
|
||||||
{
|
{
|
||||||
return inherited::project(point);
|
if (orbit != RoundedArcball) {
|
||||||
|
return inherited::project(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rounded Arcball implementation
|
||||||
|
// based on SbSphereSheetProjector in Open Inventor
|
||||||
|
SbVec3f result;
|
||||||
|
SbLine workingLine = getWorkingLine(point);
|
||||||
|
|
||||||
|
if (needSetup) {
|
||||||
|
setupPlane();
|
||||||
|
}
|
||||||
|
|
||||||
|
SbVec3f planeIntersection;
|
||||||
|
|
||||||
|
SbVec3f sphereIntersection, dontCare;
|
||||||
|
SbBool hitSphere;
|
||||||
|
if (intersectFront == TRUE) {
|
||||||
|
hitSphere = sphere.intersect(workingLine, sphereIntersection, dontCare);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hitSphere = sphere.intersect(workingLine, dontCare, sphereIntersection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hitSphere) {
|
||||||
|
// drop the sphere intersection onto the tolerance plane
|
||||||
|
|
||||||
|
SbLine projectLine(sphereIntersection, sphereIntersection + planeDir);
|
||||||
|
if (!tolPlane.intersect(projectLine, planeIntersection))
|
||||||
|
#ifdef DEBUG
|
||||||
|
SoDebugError::post("SbSphereSheetProjector::project",
|
||||||
|
"Couldn't intersect working line with plane");
|
||||||
|
#else
|
||||||
|
/* Do nothing */;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (!tolPlane.intersect(workingLine, planeIntersection))
|
||||||
|
#ifdef DEBUG
|
||||||
|
SoDebugError::post("SbSphereSheetProjector::project", "Couldn't intersect with plane");
|
||||||
|
#else
|
||||||
|
/* Do nothing */;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Three possibilities:
|
||||||
|
// (1) Intersection is on the sphere inside where the fillet
|
||||||
|
// hits it
|
||||||
|
// (2) Intersection is on the fillet
|
||||||
|
// (3) Intersection is on the plane
|
||||||
|
float distance = (planeIntersection - planePoint).length();
|
||||||
|
|
||||||
|
// Amount of filleting
|
||||||
|
// 0 = no fillet (just sphere and plane)
|
||||||
|
// infinity = only fillet
|
||||||
|
float border = 0.5;
|
||||||
|
|
||||||
|
// Radius where the fillet meets the plane in "squished space"
|
||||||
|
float r_a = 1.0F + border;
|
||||||
|
// Radius where the sphere meets the fillet in "squished space"
|
||||||
|
float r_i = 2.0 / (r_a + 1.0 / r_a);
|
||||||
|
|
||||||
|
// Distance squared in "squished space"
|
||||||
|
float d_2 = (distance * distance) * r_a * r_a;
|
||||||
|
// Distance in "squished space"
|
||||||
|
float d = std::sqrt(d_2);
|
||||||
|
|
||||||
|
// Compute how far off the plane we are
|
||||||
|
float offsetDist = 0.0;
|
||||||
|
|
||||||
|
if (d > r_a) {
|
||||||
|
// On the plane
|
||||||
|
offsetDist = 0.0;
|
||||||
|
}
|
||||||
|
else if (d < r_i) {
|
||||||
|
// On the sphere inside the fillet
|
||||||
|
offsetDist = std::sqrt(1.0 - d_2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// On the fillet
|
||||||
|
float d_r = r_a - d;
|
||||||
|
float a = border * (1.0 + border / 2.0);
|
||||||
|
offsetDist = a - std::sqrt((a + d_r) * (a - d_r));
|
||||||
|
}
|
||||||
|
|
||||||
|
SbVec3f offset;
|
||||||
|
if (orientToEye) {
|
||||||
|
if (viewVol.getProjectionType() == SbViewVolume::PERSPECTIVE) {
|
||||||
|
offset = workingProjPoint - planeIntersection;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
worldToWorking.multDirMatrix(viewVol.zVector(), offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset.normalize();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset.setValue(0, 0, 1);
|
||||||
|
}
|
||||||
|
if (intersectFront == FALSE) {
|
||||||
|
offset *= -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset *= offsetDist;
|
||||||
|
result = planeIntersection + offset;
|
||||||
|
|
||||||
|
lastPoint = result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SbRotation getRotation(const SbVec3f &point1, const SbVec3f &point2) override
|
SbRotation getRotation(const SbVec3f &point1, const SbVec3f &point2) override
|
||||||
@@ -99,6 +206,9 @@ public:
|
|||||||
if (orbit == FreeTurntable) {
|
if (orbit == FreeTurntable) {
|
||||||
return getFreeTurntable(point1, point2);
|
return getFreeTurntable(point1, point2);
|
||||||
}
|
}
|
||||||
|
if (orbit == TrackballClassic) {
|
||||||
|
return getTrackballClassic(point1, point2);
|
||||||
|
}
|
||||||
|
|
||||||
return rot;
|
return rot;
|
||||||
}
|
}
|
||||||
@@ -164,6 +274,22 @@ private:
|
|||||||
return zrot * xrot;
|
return zrot * xrot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SbRotation getTrackballClassic(const SbVec3f &point1, const SbVec3f &point2) const
|
||||||
|
{
|
||||||
|
// Classic trackball
|
||||||
|
SbRotation zrot;
|
||||||
|
SbRotation yrot;
|
||||||
|
SbVec3f dif = point1 - point2;
|
||||||
|
|
||||||
|
SbVec3f zaxis(1,0,0);
|
||||||
|
zrot.setValue(zaxis, dif[1]);
|
||||||
|
|
||||||
|
SbVec3f yaxis(0,1,0);
|
||||||
|
yrot.setValue(yaxis, -dif[0]);
|
||||||
|
|
||||||
|
return zrot * yrot;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SbMatrix worldToScreen;
|
SbMatrix worldToScreen;
|
||||||
OrbitStyle orbit{Trackball};
|
OrbitStyle orbit{Trackball};
|
||||||
@@ -415,7 +541,7 @@ std::shared_ptr<NavigationAnimation> NavigationStyle::setCameraOrientation(const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// or set the pose directly
|
// or set the pose directly
|
||||||
|
|
||||||
// Distance from rotation center to camera position in camera coordinate system
|
// Distance from rotation center to camera position in camera coordinate system
|
||||||
const SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
|
const SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
|
||||||
|
|
||||||
@@ -447,7 +573,7 @@ std::shared_ptr<NavigationAnimation> NavigationStyle::translateCamera(const SbVe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// or set the pose directly
|
// or set the pose directly
|
||||||
|
|
||||||
camera->position = camera->position.getValue() + translation;
|
camera->position = camera->position.getValue() + translation;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@@ -580,21 +706,21 @@ void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotatio
|
|||||||
// Fix issue with near clipping in orthogonal view
|
// Fix issue with near clipping in orthogonal view
|
||||||
if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
|
if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
|
||||||
|
|
||||||
// The center of the bounding sphere in camera coordinate system
|
// The center of the bounding sphere in camera coordinate system
|
||||||
SbVec3f center;
|
SbVec3f center;
|
||||||
camera->orientation.getValue().inverse().multVec(boundingSphere.getCenter() - camera->position.getValue(), center);
|
camera->orientation.getValue().inverse().multVec(boundingSphere.getCenter() - camera->position.getValue(), center);
|
||||||
|
|
||||||
SbVec3f dir;
|
SbVec3f dir;
|
||||||
camera->orientation.getValue().multVec(SbVec3f(0, 0, -1), dir);
|
camera->orientation.getValue().multVec(SbVec3f(0, 0, -1), dir);
|
||||||
|
|
||||||
// Reposition the camera but keep the focal point the same
|
// Reposition the camera but keep the focal point the same
|
||||||
// nearDistance is 0 and farDistance is the diameter of the bounding sphere
|
// nearDistance is 0 and farDistance is the diameter of the bounding sphere
|
||||||
float repositionDistance = -center.getValue()[2] - boundingSphere.getRadius();
|
float repositionDistance = -center.getValue()[2] - boundingSphere.getRadius();
|
||||||
camera->position = camera->position.getValue() + repositionDistance * dir;
|
camera->position = camera->position.getValue() + repositionDistance * dir;
|
||||||
camera->nearDistance = 0;
|
camera->nearDistance = 0;
|
||||||
camera->farDistance = 2 * boundingSphere.getRadius() + 1;
|
camera->farDistance = 2 * boundingSphere.getRadius() + 1;
|
||||||
camera->focalDistance = camera->focalDistance.getValue() - repositionDistance;
|
camera->focalDistance = camera->focalDistance.getValue() - repositionDistance;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,13 +813,13 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue)
|
|||||||
// frustum (similar to glFrustum())
|
// frustum (similar to glFrustum())
|
||||||
if (!t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId()) &&
|
if (!t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId()) &&
|
||||||
tname != "FrustumCamera") {
|
tname != "FrustumCamera") {
|
||||||
/* static SbBool first = true;
|
/* static SbBool first = true;
|
||||||
if (first) {
|
if (first) {
|
||||||
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
|
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
|
||||||
"Unknown camera type, "
|
"Unknown camera type, "
|
||||||
"will zoom by moving position, but this might not be correct.");
|
"will zoom by moving position, but this might not be correct.");
|
||||||
first = false;
|
first = false;
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
const float oldfocaldist = cam->focalDistance.getValue();
|
const float oldfocaldist = cam->focalDistance.getValue();
|
||||||
@@ -888,7 +1014,9 @@ void NavigationStyle::spin(const SbVec2f & pointerpos)
|
|||||||
float sensitivity = getSensitivity();
|
float sensitivity = getSensitivity();
|
||||||
|
|
||||||
// Adjust the spin projector sphere to the screen position of the rotation center when the mouse intersects an object
|
// Adjust the spin projector sphere to the screen position of the rotation center when the mouse intersects an object
|
||||||
if (getOrbitStyle() == Trackball && rotationCenterMode & RotationCenterMode::ScenePointAtCursor && rotationCenterFound && rotationCenterIsScenePointAtCursor) {
|
if ((getOrbitStyle() == Trackball || getOrbitStyle() == TrackballClassic || getOrbitStyle() == RoundedArcball)
|
||||||
|
&& rotationCenterMode & RotationCenterMode::ScenePointAtCursor && rotationCenterFound
|
||||||
|
&& rotationCenterIsScenePointAtCursor) {
|
||||||
const auto pointOnScreen = viewer->getPointOnViewport(rotationCenter);
|
const auto pointOnScreen = viewer->getPointOnViewport(rotationCenter);
|
||||||
const auto sphereCenter = 2 * normalizePixelPos(pointOnScreen) - SbVec2f {1, 1};
|
const auto sphereCenter = 2 * normalizePixelPos(pointOnScreen) - SbVec2f {1, 1};
|
||||||
|
|
||||||
@@ -1293,23 +1421,23 @@ void NavigationStyle::startSelection(NavigationStyle::SelectionMode mode)
|
|||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case Lasso:
|
case Lasso:
|
||||||
mouseSelection = new PolyPickerSelection();
|
mouseSelection = new PolyPickerSelection();
|
||||||
break;
|
break;
|
||||||
case Rectangle:
|
case Rectangle:
|
||||||
mouseSelection = new RectangleSelection();
|
mouseSelection = new RectangleSelection();
|
||||||
break;
|
break;
|
||||||
case Rubberband:
|
case Rubberband:
|
||||||
mouseSelection = new RubberbandSelection();
|
mouseSelection = new RubberbandSelection();
|
||||||
break;
|
break;
|
||||||
case BoxZoom:
|
case BoxZoom:
|
||||||
mouseSelection = new BoxZoomSelection();
|
mouseSelection = new BoxZoomSelection();
|
||||||
break;
|
break;
|
||||||
case Clip:
|
case Clip:
|
||||||
mouseSelection = new PolyClipSelection();
|
mouseSelection = new PolyClipSelection();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouseSelection)
|
if (mouseSelection)
|
||||||
@@ -1344,7 +1472,7 @@ SbBool NavigationStyle::isSelecting() const
|
|||||||
const std::vector<SbVec2s>& NavigationStyle::getPolygon(SelectionRole* role) const
|
const std::vector<SbVec2s>& NavigationStyle::getPolygon(SelectionRole* role) const
|
||||||
{
|
{
|
||||||
if (role)
|
if (role)
|
||||||
*role = this->selectedRole;
|
*role = this->selectedRole;
|
||||||
return pcPolygon;
|
return pcPolygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1420,59 +1548,59 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (newmode) {
|
switch (newmode) {
|
||||||
case DRAGGING:
|
case DRAGGING:
|
||||||
// Set up initial projection point for the projector object when
|
// Set up initial projection point for the projector object when
|
||||||
// first starting a drag operation.
|
// first starting a drag operation.
|
||||||
animator->stop();
|
animator->stop();
|
||||||
viewer->showRotationCenter(true);
|
viewer->showRotationCenter(true);
|
||||||
|
|
||||||
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
|
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
|
||||||
findBoundingSphere();
|
findBoundingSphere();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->spinprojector->project(this->lastmouseposition);
|
this->spinprojector->project(this->lastmouseposition);
|
||||||
this->interactiveCountInc();
|
this->interactiveCountInc();
|
||||||
this->clearLog();
|
this->clearLog();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPINNING:
|
case SPINNING:
|
||||||
this->interactiveCountInc();
|
this->interactiveCountInc();
|
||||||
viewer->getSoRenderManager()->scheduleRedraw();
|
viewer->getSoRenderManager()->scheduleRedraw();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PANNING:
|
case PANNING:
|
||||||
animator->stop();
|
animator->stop();
|
||||||
setupPanningPlane(viewer->getSoRenderManager()->getCamera());
|
setupPanningPlane(viewer->getSoRenderManager()->getCamera());
|
||||||
this->interactiveCountInc();
|
this->interactiveCountInc();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZOOMING:
|
case ZOOMING:
|
||||||
animator->stop();
|
animator->stop();
|
||||||
this->interactiveCountInc();
|
this->interactiveCountInc();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOXZOOM:
|
case BOXZOOM:
|
||||||
animator->stop();
|
animator->stop();
|
||||||
this->interactiveCountInc();
|
this->interactiveCountInc();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // include default to avoid compiler warnings.
|
default: // include default to avoid compiler warnings.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (oldmode) {
|
switch (oldmode) {
|
||||||
case SPINNING:
|
case SPINNING:
|
||||||
case DRAGGING:
|
case DRAGGING:
|
||||||
viewer->showRotationCenter(false);
|
viewer->showRotationCenter(false);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case PANNING:
|
case PANNING:
|
||||||
case ZOOMING:
|
case ZOOMING:
|
||||||
case BOXZOOM:
|
case BOXZOOM:
|
||||||
this->interactiveCountDec();
|
this->interactiveCountDec();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer->setCursorRepresentation(newmode);
|
viewer->setCursorRepresentation(newmode);
|
||||||
@@ -1569,20 +1697,20 @@ void NavigationStyle::syncWithEvent(const SoEvent * const ev)
|
|||||||
auto const event = static_cast<const SoKeyboardEvent *>(ev);
|
auto const event = static_cast<const SoKeyboardEvent *>(ev);
|
||||||
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
||||||
switch (event->getKey()) {
|
switch (event->getKey()) {
|
||||||
case SoKeyboardEvent::LEFT_CONTROL:
|
case SoKeyboardEvent::LEFT_CONTROL:
|
||||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||||
this->ctrldown = press;
|
this->ctrldown = press;
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::LEFT_SHIFT:
|
case SoKeyboardEvent::LEFT_SHIFT:
|
||||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||||
this->shiftdown = press;
|
this->shiftdown = press;
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::LEFT_ALT:
|
case SoKeyboardEvent::LEFT_ALT:
|
||||||
case SoKeyboardEvent::RIGHT_ALT:
|
case SoKeyboardEvent::RIGHT_ALT:
|
||||||
this->altdown = press;
|
this->altdown = press;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1594,17 +1722,17 @@ void NavigationStyle::syncWithEvent(const SoEvent * const ev)
|
|||||||
|
|
||||||
// SoDebugError::postInfo("processSoEvent", "button = %d", button);
|
// SoDebugError::postInfo("processSoEvent", "button = %d", button);
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case SoMouseButtonEvent::BUTTON1:
|
case SoMouseButtonEvent::BUTTON1:
|
||||||
this->button1down = press;
|
this->button1down = press;
|
||||||
break;
|
break;
|
||||||
case SoMouseButtonEvent::BUTTON2:
|
case SoMouseButtonEvent::BUTTON2:
|
||||||
this->button2down = press;
|
this->button2down = press;
|
||||||
break;
|
break;
|
||||||
case SoMouseButtonEvent::BUTTON3:
|
case SoMouseButtonEvent::BUTTON3:
|
||||||
this->button3down = press;
|
this->button3down = press;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1645,43 +1773,43 @@ SbBool NavigationStyle::processKeyboardEvent(const SoKeyboardEvent * const event
|
|||||||
SbBool processed = false;
|
SbBool processed = false;
|
||||||
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
|
||||||
switch (event->getKey()) {
|
switch (event->getKey()) {
|
||||||
case SoKeyboardEvent::LEFT_CONTROL:
|
case SoKeyboardEvent::LEFT_CONTROL:
|
||||||
case SoKeyboardEvent::RIGHT_CONTROL:
|
case SoKeyboardEvent::RIGHT_CONTROL:
|
||||||
this->ctrldown = press;
|
this->ctrldown = press;
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::LEFT_SHIFT:
|
case SoKeyboardEvent::LEFT_SHIFT:
|
||||||
case SoKeyboardEvent::RIGHT_SHIFT:
|
case SoKeyboardEvent::RIGHT_SHIFT:
|
||||||
this->shiftdown = press;
|
this->shiftdown = press;
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::LEFT_ALT:
|
case SoKeyboardEvent::LEFT_ALT:
|
||||||
case SoKeyboardEvent::RIGHT_ALT:
|
case SoKeyboardEvent::RIGHT_ALT:
|
||||||
this->altdown = press;
|
this->altdown = press;
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::S:
|
case SoKeyboardEvent::S:
|
||||||
case SoKeyboardEvent::HOME:
|
case SoKeyboardEvent::HOME:
|
||||||
case SoKeyboardEvent::LEFT_ARROW:
|
case SoKeyboardEvent::LEFT_ARROW:
|
||||||
case SoKeyboardEvent::UP_ARROW:
|
case SoKeyboardEvent::UP_ARROW:
|
||||||
case SoKeyboardEvent::RIGHT_ARROW:
|
case SoKeyboardEvent::RIGHT_ARROW:
|
||||||
case SoKeyboardEvent::DOWN_ARROW:
|
case SoKeyboardEvent::DOWN_ARROW:
|
||||||
if (!this->isViewing())
|
if (!this->isViewing())
|
||||||
this->setViewing(true);
|
this->setViewing(true);
|
||||||
break;
|
break;
|
||||||
case SoKeyboardEvent::PAGE_UP:
|
case SoKeyboardEvent::PAGE_UP:
|
||||||
{
|
{
|
||||||
processed = true;
|
processed = true;
|
||||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||||
doZoom(viewer->getSoRenderManager()->getCamera(), getDelta(), posn);
|
doZoom(viewer->getSoRenderManager()->getCamera(), getDelta(), posn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SoKeyboardEvent::PAGE_DOWN:
|
case SoKeyboardEvent::PAGE_DOWN:
|
||||||
{
|
{
|
||||||
processed = true;
|
processed = true;
|
||||||
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
const SbVec2f posn = normalizePixelPos(event->getPosition());
|
||||||
doZoom(viewer->getSoRenderManager()->getCamera(), -getDelta(), posn);
|
doZoom(viewer->getSoRenderManager()->getCamera(), -getDelta(), posn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return processed;
|
return processed;
|
||||||
|
|||||||
@@ -103,7 +103,9 @@ public:
|
|||||||
enum OrbitStyle {
|
enum OrbitStyle {
|
||||||
Turntable,
|
Turntable,
|
||||||
Trackball,
|
Trackball,
|
||||||
FreeTurntable
|
FreeTurntable,
|
||||||
|
TrackballClassic,
|
||||||
|
RoundedArcball,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class RotationCenterMode {
|
enum class RotationCenterMode {
|
||||||
|
|||||||
@@ -475,7 +475,9 @@ Select a set and then press the button to view said configurations.</string>
|
|||||||
<string>Rotation orbit style.
|
<string>Rotation orbit style.
|
||||||
Trackball: moving the mouse horizontally will rotate the part around the y-axis
|
Trackball: moving the mouse horizontally will rotate the part around the y-axis
|
||||||
Turntable: the part will be rotated around the z-axis (with constrained axes).
|
Turntable: the part will be rotated around the z-axis (with constrained axes).
|
||||||
Free Turntable: the part will be rotated around the z-axis.</string>
|
Free Turntable: the part will be rotated around the z-axis.
|
||||||
|
Trackball Classic: moving the mouse will rotate the part allowing precession
|
||||||
|
Rounded Arcball: moving the mouse in the corners of the screen will only roll the part.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
@@ -495,6 +497,16 @@ Free Turntable: the part will be rotated around the z-axis.</string>
|
|||||||
<string>Free Turntable</string>
|
<string>Free Turntable</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Trackball Classic</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rounded Arcball</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
|||||||
@@ -612,6 +612,8 @@ def retranslateUi():
|
|||||||
aTurntable.setText(translate("NavigationIndicator", "Turntable"))
|
aTurntable.setText(translate("NavigationIndicator", "Turntable"))
|
||||||
aFreeTurntable.setText(translate("NavigationIndicator", "Free Turntable"))
|
aFreeTurntable.setText(translate("NavigationIndicator", "Free Turntable"))
|
||||||
aTrackball.setText(translate("NavigationIndicator", "Trackball"))
|
aTrackball.setText(translate("NavigationIndicator", "Trackball"))
|
||||||
|
aTrackballClassic.setText(translate("NavigationIndicator", "Trackball Classic"))
|
||||||
|
aRoundedArcball.setText(translate("NavigationIndicator", "Rounded Arcball"))
|
||||||
a0.setText(translate("NavigationIndicator", "Undefined"))
|
a0.setText(translate("NavigationIndicator", "Undefined"))
|
||||||
|
|
||||||
|
|
||||||
@@ -648,10 +650,18 @@ aTrackball.setCheckable(True)
|
|||||||
aFreeTurntable = QtGui.QAction(gOrbit)
|
aFreeTurntable = QtGui.QAction(gOrbit)
|
||||||
aFreeTurntable.setObjectName("NavigationIndicator_FreeTurntable")
|
aFreeTurntable.setObjectName("NavigationIndicator_FreeTurntable")
|
||||||
aFreeTurntable.setCheckable(True)
|
aFreeTurntable.setCheckable(True)
|
||||||
|
aTrackballClassic = QtGui.QAction(gOrbit)
|
||||||
|
aTrackballClassic.setObjectName("NavigationIndicator_TrackballClassic")
|
||||||
|
aTrackballClassic.setCheckable(True)
|
||||||
|
aRoundedArcball = QtGui.QAction(gOrbit)
|
||||||
|
aRoundedArcball.setObjectName("NavigationIndicator_RoundedArcball")
|
||||||
|
aRoundedArcball.setCheckable(True)
|
||||||
|
|
||||||
menuOrbit.addAction(aTurntable)
|
menuOrbit.addAction(aTurntable)
|
||||||
menuOrbit.addAction(aTrackball)
|
menuOrbit.addAction(aTrackball)
|
||||||
menuOrbit.addAction(aFreeTurntable)
|
menuOrbit.addAction(aFreeTurntable)
|
||||||
|
menuOrbit.addAction(aTrackballClassic)
|
||||||
|
menuOrbit.addAction(aRoundedArcball)
|
||||||
|
|
||||||
menuSettings.addMenu(menuOrbit)
|
menuSettings.addMenu(menuOrbit)
|
||||||
menuSettings.addSeparator()
|
menuSettings.addSeparator()
|
||||||
@@ -795,6 +805,10 @@ def onOrbit():
|
|||||||
pView.SetInt("OrbitStyle", 1)
|
pView.SetInt("OrbitStyle", 1)
|
||||||
elif aFreeTurntable.isChecked():
|
elif aFreeTurntable.isChecked():
|
||||||
pView.SetInt("OrbitStyle", 2)
|
pView.SetInt("OrbitStyle", 2)
|
||||||
|
elif aTrackballClassic.isChecked():
|
||||||
|
pView.SetInt("OrbitStyle", 3)
|
||||||
|
elif aRoundedArcball.isChecked():
|
||||||
|
pView.SetInt("OrbitStyle", 4)
|
||||||
|
|
||||||
|
|
||||||
def onOrbitShow():
|
def onOrbitShow():
|
||||||
@@ -808,6 +822,10 @@ def onOrbitShow():
|
|||||||
aTrackball.setChecked(True)
|
aTrackball.setChecked(True)
|
||||||
elif OrbitStyle == 2:
|
elif OrbitStyle == 2:
|
||||||
aFreeTurntable.setChecked(True)
|
aFreeTurntable.setChecked(True)
|
||||||
|
elif OrbitStyle == 3:
|
||||||
|
aTrackballClassic.setChecked(True)
|
||||||
|
elif OrbitStyle == 4:
|
||||||
|
aRoundedArcball.setChecked(True)
|
||||||
gOrbit.blockSignals(False)
|
gOrbit.blockSignals(False)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user