OfEasyCam zoom into mouse position

#1

Can anyone advise how to get ofEasyCam to zoom into the mouse position when using the scroll-zoom function?

Thanks
S

#2

Hi, the ofEasyCam has this feature when in ortho mode, but I can not remember why it does not have it when in non ortho mode. as such you can “enable” it for non ortho mode making a few modifications to the ofEasyCam source code.
So go into ofEasyCam.cpp and comment line 296 and lines 310-312

so that block will end up looking like this

if(currentTransformType == TRANSFORM_TRANSLATE_XY ||
	   currentTransformType == TRANSFORM_TRANSLATE_Z  ||
	   currentTransformType == TRANSFORM_SCALE) {
//		if(getOrtho()){
			//In ortho mode moving along the z axis has no effect besides clipping.
			// Instead, scale is applied to achieve the effect of getting near or far from the target.
			glm::vec3 mousePre ;
			bool bDoScale = (currentTransformType == TRANSFORM_SCALE || currentTransformType == TRANSFORM_TRANSLATE_Z);
			if (bDoScale) {
				mousePre = screenToWorld(glm::vec3((bIsScrolling?mouseAtScroll:lastPressMouse),0));
			}
			move(glm::vec3(lastPressAxisX * translate.x) + (lastPressAxisY * translate.y));
			if (bDoScale) {
				setScale(getScale() + translate.z);
				// this move call is to keep the scaling centered below the mouse.
				move(mousePre - screenToWorld(glm::vec3((bIsScrolling?mouseAtScroll:lastPressMouse),0)));
			}
//		}else{
//			move(glm::vec3(lastPressAxisX * translate.x) + (lastPressAxisY * translate.y) + (lastPressAxisZ * translate.z));
//		}
	}

then move line 428 so it sits outside the ifstatemente where it is. It will look like the following .

void ofEasyCam::mouseScrolled(ofMouseEventArgs & mouse){
	ofRectangle area = getControlArea();
	if(area.inside(mouse)){
		mouseVel = mouse  - prevMouse;
		prevMouse = mouse;
		if (doInertia) {
			bApplyInertia = true;
		}
		lastPressPosition = ofCamera::getGlobalPosition();
		lastPressAxisZ = getZAxis();
		if (getOrtho()) {
			translate.z = sensitivityScroll * mouse.scrollY / viewport.height;
		}else{
			translate.z = mouse.scrollY * 30 * sensitivityTranslate.z * (getDistance() + std::numeric_limits<float>::epsilon())/ area.height;
		}
		mouseAtScroll = mouse;///this is the line you need to move
		currentTransformType = TRANSFORM_SCALE;
		bIsScrolling = true;
	}
}

You might want to adjust the sensitivity of the scrolling too.
let me know if this is what you were looking for
Otherwise, ofxGrabCam does something similar plus being able to rotate around the object it has below

1 Like
#3

Ah yes this is super, thanks!

I’d found the enableOrtho setting but the above will help too, would be good to have the same ability for perspective.

On sensitivity, there didn’t seem to be a ‘set scroll sensitivity’ void, so I’ve added one to change ’sensitivityScroll’ values. Perhaps this was missed off?

Also; I’m translating the final drawn outcome (an ofFbo), so to have the mouse interactions accurate to position, would it make sense to have a ‘mouse offset’ vec2 setting in the easyCam object? To subtract from any mouse input coords.

S

#4

Hi

YEah, I don’t really remember why it is not. I wrote most of the ofEasyCam code and I think that there was some reason for it to be as it is. But having it as an option would be great.

you’re right. It would be probably a good idea to add it.

There are two things you need for doing this, when you call begin() on the ofEasyCam you need to include an ofRectangle as argument which will become the camera viewport (the area where it will be drawn). so it would look like (assuming that cam is an ofEasyCam object)

cam.begin(ofRectangle(200, 100, 300,400));

Also you’ll need to set the ofEasyCam control area which is a rectangle where the mouse is used. so you can call

 cam.setControlArea(ofRectangle(200, 100, 300,400));

which will make the control area the same as the view port, thus you will be able to draw the camera in a section of the screen and control it aswell. in the case of using it with an fbo you will probably just need to set the control area to the position and size where you are drawing the fbo so the interaction is correct.