Struct Arcball

Page Contents

Struct Documentation

struct nanogui::Arcball

Arcball helper class to interactively rotate objects on-screen.

The Arcball class enables fluid interaction by representing rotations using a quaternion, and is setup to be used in conjunction with the existing mouse callbacks defined in nanogui::Widget. The Arcball operates by maintaining an “active” state which is typically controlled using a mouse button click / release. A click pressed would call Arcball::button with down = true, and a click released with down = false. The high level mechanics are:

  1. The Arcball is made active by calling Arcball::button with a specified click location, and down = true.
  2. As the user holds the mouse button down and drags, calls to Arcball::motion are issued. Internally, the Arcball keeps track of how far the rotation is from the start click. During the active state, mQuat is not updated, call Arcball::matrix to get the current rotation for use in drawing updates. Receiving the rotation as a matrix will usually be more convenient for traditional pipelines, however you can also acquire the active rotation using Arcball::activeState.
  3. The user releases the mouse button, and a call to Arcball::button with down = false. The Arcball is no longer active, and its internal mQuat is updated.

A very simple nanogui::Screen derived class to illustrate usage:

class ArcballScreen : public nanogui::Screen {
public:
    // Creating a 400x400 window
    ArcballScreen() : nanogui::Screen({400, 400}, "ArcballDemo") {
        mArcball.setSize(mSize);// Note 1
    }

    virtual bool mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers) override {
        // In this example, we are using the left mouse button
        // to control the arcball motion
        if (button == GLFW_MOUSE_BUTTON_1) {
            mArcball.button(p, down);// Note 2
            return true;
        }
        return false;
    }

    virtual bool mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) override {
        if (button == GLFW_MOUSE_BUTTON_1) {
            mArcball.motion(p);// Note 2
            return true;
        }
        return false;
    }

    virtual void drawContents() override {
        // Option 1: acquire a 4x4 homogeneous rotation matrix
        Matrix4f rotation = mArcball.matrix();
        // Option 2: acquire an equivalent quaternion
        Quaternionf rotation = mArcball.activeState();
        // ... do some drawing with the current rotation ...
    }

protected:
    nanogui::Arcball mArcball;
};
Note 1
The user is responsible for setting the size with Arcball::setSize, this does not need to be the same as the Screen dimensions (e.g., you are using the Arcball to control a specific glViewport).
Note 2
Be aware that the input vector p to Widget::mouseButtonEvent and Widget::mouseMotionEvent are in the coordinates of the Screen dimensions (top left is (0, 0), bottom right is (width, height)). If you are using the Arcball to control a subregion of the Screen, you will want to transform the input p before calling Arcball::button or Arcball::motion. For example, if controlling the right half of the screen, you might create Vector2i adjusted_click(p.x() - (mSize.x() / 2), p.y()), and then call mArcball.motion(adjusted_click).

Public Functions

Arcball(float speedFactor = 2.0f)

The default constructor.

Note

Make sure to call Arcball::setSize after construction.

Parameters

Arcball(const Quaternionf &quat)

Constructs an Arcball based off of the specified rotation.

Note

Make sure to call Arcball::setSize after construction.

Quaternionf &state()

The internal rotation of the Arcball.

Call Arcball::matrix for drawing loops, this method will not return any updates while mActive is true.

const Quaternionf &state() const

const version of Arcball::state.

void setState(const Quaternionf &state)

Sets the rotation of this Arcball. The Arcball will be marked as not active.

void setSize(Vector2i size)

Sets the size of this Arcball.

The size of the Arcball and the positions being provided in Arcball::button and Arcball::motion are directly related.

const Vector2i &size() const

Returns the current size of this Arcball.

void setSpeedFactor(float speedFactor)

Sets the speed at which this Arcball rotates. See also mSpeedFactor.

float speedFactor() const

Returns the current speed at which this Arcball rotates.

bool active() const

Returns whether or not this Arcball is currently active.

void button(Vector2i pos, bool pressed)

Signals a state change from active to non-active, or vice-versa.

Parameters
  • pos: The click location, should be in the same coordinate system as specified by mSize.
  • pressed: When true, this Arcball becomes active. When false, this Arcball becomes non-active, and its internal mQuat is updated with the final rotation.

bool motion(Vector2i pos)

When active, updates mIncr corresponding to the specified position.

Parameters
  • pos: Where the mouse has been dragged to.

Matrix4f matrix() const

Returns the current rotation including the active motion, suitable for use with typical homogeneous matrix transformations. The upper left 3x3 block is the rotation matrix, with 0-0-0-1 as the right-most column / bottom row.

Quaternionf activeState() const

Returns the current rotation including the active motion.

void interrupt()

Interrupts the current Arcball motion by calling Arcball::button with (0, 0) and false.

Use this method to “close” the state of the Arcball when a mouse release event is not available. You would use this method if you need to stop the Arcball from updating its internal rotation, but the event stopping the rotation does not come from a mouse release. For example, you have a callback that created a nanogui::MessageDialog which will now be in focus.

Protected Attributes

bool mActive

Whether or not this Arcball is currently active.

Vector2i mLastPos

The last click position (which triggered the Arcball to be active / non-active).

Vector2i mSize

The size of this Arcball.

Quaternionf mQuat

The current stable state. When this Arcball is active, represents the state of this Arcball when Arcball::button was called with down = true.

Quaternionf mIncr

When active, tracks the overall update to the state. Identity when non-active.

float mSpeedFactor

The speed at which this Arcball rotates. Smaller values mean it rotates more slowly, higher values mean it rotates more quickly.