Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save roymacdonald/cd92c6d5adfa2c8aeffb22fc6c293bcc to your computer and use it in GitHub Desktop.
Save roymacdonald/cd92c6d5adfa2c8aeffb22fc6c293bcc to your computer and use it in GitHub Desktop.

ofEasyCam custom mouse interaction

written by Roy Macdonald

A new feature in openFrameworks 0.10 is that you can customize ofEasyCam's mouse interactions. This allows you to mimic your favorite CAD software or use a configuration that feels better for certain purposes.

2D ortho camera

I like to modify these for 2D interactions in ortho mode. This allows you to easilly navigate your "canvas".

It is really simple.

Let's asume that you are using this on your ofApp. so, in the ofApp.h file you will have

ofEasyCam cam;

Then in ofApp.cpp, inside setup() add the following lines of code:

First you need to get rid of the default interactions. As of now, the scrolling interactions are not customizable, hence are not removed with the following line.

cam.removeAllInteractions();

Now you can add your custom interactions using addInteraction(), further down you can find the possible parameters you can give to this function.

cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT);
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_RIGHT);

Notice that I did not add rotation to the interactions, since I want to have a 2D ortho camera. The next line is needed to set the ofEasyCam in ortho mode:

cam.enableOrtho();

In ortho mode you might want to set the near and far clip very far away so this don't bother. If you want to use these somehow you still can modify them at any point in your app. Setting the near clip to a negative value doesn't make much sense when the camera is in perspective mode (ortho disabled) but in ortho mode it is needed to be able to zoom in.

cam.setNearClip(-1000000);
cam.setFarClip(1000000);

Flip the camera so it looks correct.

cam.setVFlip(true);

So, all these together, just to make your copypasting easier :)

cam.removeAllInteractions();
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT);
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_RIGHT);

cam.enableOrtho();
cam.setNearClip(-1000000);
cam.setFarClip(1000000);
cam.setVFlip(true);

Mouse interactions

When we called cam.addInteraction(...) in the lines above, i did not explained the parameters passed, although I think these are quite self-explanatory. So, this function links together a certain kind of camera movement with a mouse button. The first argument is the camera movement, which can be any one of the following:

ofEasyCam::TRANSFORM_ROTATE
ofEasyCam::TRANSFORM_TRANSLATE_XY
ofEasyCam::TRANSFORM_TRANSLATE_Z
ofEasyCam::TRANSFORM_SCALE

The second argument is the mouse button, which are:

OF_MOUSE_BUTTON_LEFT
OF_MOUSE_BUTTON_MIDDLE
OF_MOUSE_BUTTON_RIGHT

if you have a mouse with lots of buttons you can use these using the following instead

OF_MOUSE_BUTTON_1
OF_MOUSE_BUTTON_2
OF_MOUSE_BUTTON_3
OF_MOUSE_BUTTON_4
OF_MOUSE_BUTTON_5
OF_MOUSE_BUTTON_6
OF_MOUSE_BUTTON_7
OF_MOUSE_BUTTON_8
OF_MOUSE_BUTTON_LAST

You can mix the mouse buttons and camera movements in any way you want, although using two different camera movements with the same mouse button can give some weird results.

Mouse and key interactions

In lots of cases you might want to restrict the mouse interaction to happen only when a certain key is being pressed, which is really useful and used a lot in the CAD world. This is actually quite simple to achieve, and the only thing you need is to add a third argument to cam.addInteraction(...) which is the key. So, only when both the key and the specified mouse button are being pressed the camera movement will happen.

So if in the code we previously used we add ' ' (a blank space character) as a third argument we will restrict the camera's mouse interaction to happen only when the space bar is being pressed. And it looks like this:

cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT, ' ');
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_RIGHT, ' ');

You can even set a different camera movement to the same button with and without a key being pressed, so instead of the previous code we use:

cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT);
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_LEFT, ' ');

In the above case the XY translation will only happen when the left mouse button is being pressed and the space bar is NOT pressed. When the space key is pressed the translate Z movement will happen.

The key that you pass can be either a literal key, like in the code above or for example 'a' to use lowercase a key and so on.

You can also specify the keyboard special keys: For example in the code above, if we want to use the shift key instead of the space bar we would specify it like the following.

cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_LEFT, OF_KEY_SHIFT);

The available special keys are the following

OF_KEY_RETURN
OF_KEY_ESC
OF_KEY_TAB
OF_KEY_BACKSPACE
OF_KEY_DEL
OF_KEY_SHIFT
OF_KEY_CONTROL
OF_KEY_ALT
OF_KEY_SUPER
OF_KEY_COMMAND
OF_KEY_LEFT_SHIFT
OF_KEY_RIGHT_SHIFT
OF_KEY_LEFT_CONTROL
OF_KEY_RIGHT_CONTROL
OF_KEY_LEFT_ALT
OF_KEY_RIGHT_ALT
OF_KEY_LEFT_SUPER
OF_KEY_RIGHT_SUPER
OF_KEY_LEFT_COMMAND
OF_KEY_RIGHT_COMMAND
OF_KEY_F1
OF_KEY_F2
OF_KEY_F3
OF_KEY_F4
OF_KEY_F5
OF_KEY_F6
OF_KEY_F7
OF_KEY_F8
OF_KEY_F9
OF_KEY_F10
OF_KEY_F11
OF_KEY_F12
OF_KEY_LEFT
OF_KEY_UP
OF_KEY_RIGHT
OF_KEY_DOWN
OF_KEY_PAGE_UP
OF_KEY_PAGE_DOWN
OF_KEY_HOME
OF_KEY_END
OF_KEY_INSERT

Other functions

In the example code above, we used cam.removeAllInteractions(); to remove all the current (default) interactions. You can also remove specific interactions using cam.removeInteraction(...) and pass to it the same arguments you passed when adding the interaction. Hence, if we want to remove:

cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_LEFT, ' ' '); 

We must call:

cam.removeInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_LEFT, ' ');

You can also check if a certain interaction has been added using the following method which will return true or false.

cam.hasInteraction(ofEasyCam::TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_LEFT, ' '); 

also you can check if a mouse button and key combination is being used, without passing the camera movement type. It will also return true or false.

cam.hasInteraction(OF_MOUSE_BUTTON_LEFT, ' '); 

Default interactions

Just in case you are curious, ofEasyCam's default mouse interactions are:

addInteraction(TRANSFORM_ROTATE, OF_MOUSE_BUTTON_LEFT);
addInteraction(TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_LEFT,'m'); // m for move
addInteraction(TRANSFORM_TRANSLATE_Z, OF_MOUSE_BUTTON_RIGHT);
addInteraction(TRANSFORM_TRANSLATE_XY, OF_MOUSE_BUTTON_MIDDLE);

I hope you find this useful. cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment