This is meant to act similarly to Processing’s “PeasyCam”:
http://mrfeinberg.com/peasycam/
In Processing, all you have to do is say:
import peasy.*;
void setup() {
PeasyCam cam = new PeasyCam(this, 500);
}
And it automatically registers methods to Processing’s mouse event and draw method so that you can control the camera with the mouse.
ofxEasyCam can be used similarly.
1 Download ofx3dUtils http://code.google.com/p/ofx3dutils/
2 Add #include “ofxEasyCam.h” to your testApp.h
3 Add ofxEasyCam camera; as a member of your testApp
4 In testApp:setup(), specify the z-distance of the camera:
camera.setup(this, 500);
5 In testApp::draw(), add:
camera.draw();
To the beginning of the method. (I can’t register for ofEvents.draw, because that’s called at the end of draw() rather than the beginning).
ofxEasyCam extends ofx3dUtils’ ofxCamera, so all of its methods are available.
#pragma once
#include "ofx3DUtils.h"
class ofxEasyCam : public ofxCamera {
private:
bool mouseHasMoved, mouseClicked;
float dmouseX, dmouseY, pmouseX, pmouseY;
int mouseButton;
public:
float zoomSpeed, orbitSpeed, panSpeed;
ofxEasyCam() {
zoomSpeed = 1;
orbitSpeed = .2;
panSpeed = 1;
ofAddListener(ofEvents.mousePressed, this, &ofxEasyCam::mousePressed);
ofAddListener(ofEvents.mouseReleased, this, &ofxEasyCam::mouseReleased);
ofAddListener(ofEvents.mouseDragged, this, &ofxEasyCam::mouseDragged);
}
void setup(ofBaseApp* app, float dist) {
position(ofGetWidth() / 2, ofGetHeight() / 2, dist);
dmouseX = dmouseY = pmouseX = pmouseY = 0;
mouseHasMoved = false;
mouseClicked = false;
}
void draw() {
ofxVec3f relx = getDir().getCrossed(getUp()).normalize();
ofxVec3f rely = getDir().getCrossed(relx).normalize();
if(mouseButton == 0) {
orbitAround(
getEye(),
relx,
orbitSpeed * dmouseY);
orbitAround(
getEye(),
rely,
orbitSpeed * -dmouseX);
} else if(mouseButton == 2) {
ofxVec3f offset = getDir().normalize() * (zoomSpeed * dmouseY);
eye(getEye() - offset);
moveGlobal(offset);
} else if(mouseButton == 3) {
ofxVec3f offset =
(relx * dmouseX * panSpeed) +
(rely * dmouseY * panSpeed);
moveGlobal(offset);
}
dmouseX *= .9;
dmouseY *= .9;
place();
}
void mousePressed(ofMouseEventArgs& event) {
if(mouseClicked == true)
mouseButton = 3; // left + right
else
mouseButton = event.button;
mouseClicked = true;
}
void mouseDragged(ofMouseEventArgs& event) {
int x = event.x;
int y = event.y;
if(mouseHasMoved) {
dmouseX = pmouseX - x;
dmouseY = pmouseY - y;
} else
mouseHasMoved = true;
pmouseX = x;
pmouseY = y;
}
void mouseReleased(ofMouseEventArgs& event) {
mouseHasMoved = false;
mouseClicked = false;
}
};
There is one known bug: gimbal lock. If you look from the north or south pole positions, you can get some weirdly fast rotation.
update: ofxEasyCam is now in the ofx3DUtils svn, I’ll maintain it there.