//---------------------------------------- void ofCamera::calcClipPlanes(ofRectangle viewport) { // autocalculate near/far clip planes if not set by user if(nearClip == 0 || farClip == 0) { float dist = getImagePlaneDistance(viewport); nearClip = (nearClip == 0) ? dist / 100.0f : nearClip; farClip = (farClip == 0) ? dist * 10.0f : farClip; } }
//---------------------------------------- void ofEasyCam::update(ofEventArgs & args){ if(bMouseInputEnabled){ if(!bDistanceSet){ setDistance(getImagePlaneDistance(viewport), true); } rotationFactor = sensitivityRot * 180 / min(viewport.width, viewport.height); if (bMouseInputEnabled) { updateMouse(); } if (bDoRotate) { updateRotation(); }else if (bDoTranslate) { updateTranslation(); } } }
//---------------------------------------- void ofEasyCam::update(ofEventArgs & args){ viewport = getViewport(this->viewport); if(!bDistanceSet && bAutoDistance){ setDistance(getImagePlaneDistance(viewport), true); } if(bMouseInputEnabled){ if(events->getMousePressed()) prevMouse = glm::vec2(events->getMouseX(),events->getMouseY()); if (bDoRotate) { updateRotation(); }else if (bDoTranslate || bDoScrollZoom || bIsBeingScrolled) { updateTranslation(); bDoScrollZoom = false; } } }
//---------------------------------------- void ofEasyCam::update(ofEventArgs & args){ if(!bDistanceSet && bAutoDistance){ setDistance(getImagePlaneDistance(viewport), true); } if(bMouseInputEnabled){ rotationFactor = sensitivityRot * 180 / min(viewport.width, viewport.height); if(ofGetMousePressed()) prevMouse = ofVec2f(ofGetMouseX(),ofGetMouseY()); if (bDoRotate) { updateRotation(); }else if (bDoTranslate || bDoScrollZoom) { updateTranslation(); bDoScrollZoom = false; } } }
//---------------------------------------- void ofEasyCam::update(ofEventArgs & args){ if(!bDistanceSet && bAutoDistance){ setDistance(getImagePlaneDistance(viewport), true); } if(bMouseInputEnabled){ rotationFactor = sensitivityRot * 180 / min(viewport.width, viewport.height); if (bMouseInputEnabled) { updateMouse(); } if (bDoRotate) { // <>< # Added extra boolean bRotation. Now you can disable the camera rotation/oll with disableRotation() if(bRotation) updateRotation(); // updateRotation(); <-- PREVIOUS LINE }else if (bDoTranslate) { updateTranslation(); } } }
//---------------------------------------- void ofEasyCamExt::update(ofEventArgs & args) { if( isDoingMove ) { float tmpFraction = ofMap( ofGetElapsedTimef(), moveStartEndTimeParameters.getMin(), moveStartEndTimeParameters.getMax(), 0.0f, 1.0f ); if( tmpFraction >= 1.0f ) { isDoingMove = false; } tmpFraction = ofClamp( tmpFraction, 0.0f, 1.0f ); tmpFraction = EasingEquations::ease( tmpFraction, easeType ); ofVec3f newPos = positionEaseParameters.getMin().interpolate( positionEaseParameters.getMax(), tmpFraction ); //ofVec3f newLookAtDir = lookAtEaseParameters.getMin().interpolate( lookAtEaseParameters.getMax(), tmpFraction ); ofQuaternion newOrientation; newOrientation.slerp( tmpFraction, orientationEaseStart, orientationEaseEnd ); //resetTransform(); setPosition(newPos); //target.resetTransform(); //target.setPosition(newLookAtDir); //lookAt(target, getUpDir() ); setOrientation( newOrientation ); moveX = 0; moveY = 0; moveZ = 0; } else { if(!bDistanceSet && bAutoDistance) { setDistance(getImagePlaneDistance(viewport), true); } if(bMouseInputEnabled) { rotationFactor = sensitivityRot * 180 / min(viewport.width, viewport.height); if (bMouseInputEnabled) { updateMouse(); } if (bDoRotate) { updateRotation(); } else if (bDoTranslate) { updateTranslation(); } } if( dollyForwardKey != 0 ) { if( ofGetKeyPressed(dollyForwardKey) ) { dollyImpulse( -dollyImpulseAmount ); } } if( dollyBackwardKey != 0 ) { if( ofGetKeyPressed(dollyBackwardKey) ) { dollyImpulse( dollyImpulseAmount ); } } // if (bApplyInertia) { moveX *= drag; moveY *= drag; moveZ *= drag; if (ABS(moveX) <= minDifference && ABS(moveY) <= minDifference && ABS(moveZ) <= minDifference) { //bApplyInertia = false; bDoTranslate = false; } // } move((getXAxis() * moveX) + (getYAxis() * moveY) + (getZAxis() * moveZ)); } }
//---------------------------------------- void ofEasyFingerCam::begin(ofRectangle viewport) { glEnable(GL_DEPTH_TEST); viewportRect = viewport; ofCamera::begin(viewport); ofPushMatrix(); glGetDoublev(GL_PROJECTION_MATRIX, this->matP); glGetDoublev(GL_MODELVIEW_MATRIX, this->matM); glGetIntegerv(GL_VIEWPORT, this->viewport); bool hasTweens = false; if(rTweens.size()>0) { hasTweens = true; setAnglesFromOrientation(); targetXRot = rTweens[0]->x; targetYRot = rTweens[0]->y; targetZRot = rTweens[0]->z; updateRotation(); if(targetXRot - rotationX <1 && targetXRot - rotationX >-1 && targetYRot - rotationY <1 && targetYRot - rotationY >-1 && targetZRot - rotationZ <1 && targetZRot - rotationZ >-1) { rTweens.erase(rTweens.begin()); } setAnglesFromOrientation(); } if(sTweens.size()>0) { hasTweens = true; if(abs(sTweens.at(0)->scale - getDistance()) < 10) { float newvalue = (getDistance()-sTweens.at(0)->scale)*0.05/100; setDistance(getDistance()+newvalue); } } if(pTweens.size()>0) { hasTweens = true; if(target.getPosition().distance(pTweens.at(0)->pan) > 1) { ofVec3f newTranslation; newTranslation = pTweens.at(0)->pan - target.getPosition(); translation = newTranslation/10; target.move(translation); } else { pTweens.erase(pTweens.begin()); } } if(hasTweens) { currentState = TWEENING; } else { currentState = STABLE; if(bMouseInputEnabled||bFingerInputEnabled) { if(!bDistanceSet) { setDistance(getImagePlaneDistance(viewport), true); } if (fingers.size() > 0 ) { // it's important to check whether we've already accounted for the mouse // just in case you use the camera multiple times in a single frame if (lastFrame != ofGetFrameNum()) { lastFrame = ofGetFrameNum(); currentState = STABLE; if (fingers.size() == 1) { if(selectedPlane->axis == AxisPlane::NOAXIS) { currentState = ROTATING; // if there is some smart way to use dt to scale the values drag, we should do it // you can't simply multiply drag etc because the behavior is unstable at high framerates // float dt = ofGetLastFrameTime(); ofVec2f mousePosScreen = ofVec3f(fingers[0]->getX()*ofGetWidth() - viewport.width/2 - viewport.x, viewport.height/2 - (fingers[0]->getY()*ofGetHeight() - viewport.y), 0); ofVec2f mouseVelScreen = (mousePosScreen - mousePosScreenPrev).lengthSquared(); ofVec3f targetPos = target.getGlobalPosition(); ofVec3f mousePosXYZ = ofVec3f(mousePosScreen.x, mousePosScreen.y, targetPos.z); float sphereRadius = min(viewport.width, viewport.height)/2; float diffSquared = sphereRadius * sphereRadius - (targetPos - mousePosXYZ).lengthSquared(); if(diffSquared <= 0) { mousePosXYZ.z = 0; } else { mousePosXYZ.z = sqrtf(diffSquared); } mousePosXYZ.z += targetPos.z; ofVec3f mousePosView = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ; //calc new rotation velocity ofQuaternion newRotation; if(fingerPressedPrev[0]) { newRotation.makeRotate(mousePosViewPrev, mousePosView); } fingerPressedPrev[0] = true; //apply drag towards new velocities rotation.slerp(drag, rotation, newRotation); // TODO: add dt mousePosViewPrev = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ; // apply transforms if they're big enough // TODO: these should be scaled by dt if(translation.lengthSquared() > epsilonTransform) { // TODO: this isn't quite right, it needs to move wrt the rotation target.move(translation); } if (rotation.asVec3().lengthSquared() > epsilonTransform) { target.rotate(rotation.conj()); } if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform) { setDistance(getDistance() * (1.0f + distanceScaleVelocity), false); } mousePosScreenPrev = mousePosScreen; // targetFut.setPosition(target.getPosition()); } } if (fingers.size() == 2) { currentState = SCALING; if(zooming) { ofVec2f pointa = ofVec2f(fingers[0]->getX()*ofGetWidth(),fingers[0]->getY()*ofGetHeight()); ofVec2f pointb = ofVec2f(fingers[1]->getX()*ofGetWidth(),fingers[1]->getY()*ofGetHeight()); float newDistance = pointa.distance(pointb); float newDistanceScaleVelocity = 0.0f; if(prevDistance == 0) { prevDistance = newDistance; } else { newDistanceScaleVelocity = zoomSpeed * ( prevDistance - newDistance) / ofVec2f(0,0).distance(ofVec2f(ofGetHeight(),ofGetWidth())); distanceScaleVelocity = ofLerp(distanceScaleVelocity, newDistanceScaleVelocity, drag); if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform) { setDistance(getDistance() * (1.0f + distanceScaleVelocity), false); } prevDistance = newDistance; } } } else { prevDistance = 0; } if (fingers.size() == 3) { currentState = POINTING; } if (fingers.size() == 5) { if(selectedPlane->axis == AxisPlane::NOAXIS) { currentState = PANNING; //DECIDE LATER } } if (fingers.size() == 10) { if(selectedPlane->axis == AxisPlane::NOAXIS) { currentState = RESET; addPanningTween(ofVec3f(0,0,0)); addRotationTween(0, 0, 0, 1); } } } } else { //MOUSE fingerPressedPrev[0] = false; // it's important to check whether we've already accounted for the mouse // just in case you use the camera multiple times in a single frame if (lastFrame != ofGetFrameNum()) { lastFrame = ofGetFrameNum(); if(selectedPlane->axis == AxisPlane::NOAXIS) { // if there is some smart way to use dt to scale the values drag, we should do it // you can't simply multiply drag etc because the behavior is unstable at high framerates // float dt = ofGetLastFrameTime(); currentState = STABLE; ofVec2f mousePosScreen = ofVec3f(ofGetMouseX() - viewport.width/2 - viewport.x, viewport.height/2 - (ofGetMouseY() - viewport.y), 0); ofVec2f mouseVelScreen = (mousePosScreen - mousePosScreenPrev).lengthSquared(); ofVec3f targetPos = target.getGlobalPosition(); ofVec3f mousePosXYZ = ofVec3f(mousePosScreen.x, mousePosScreen.y, targetPos.z); float sphereRadius = min(viewport.width, viewport.height)/2; float diffSquared = sphereRadius * sphereRadius - (targetPos - mousePosXYZ).lengthSquared(); if(diffSquared <= 0) { mousePosXYZ.z = 0; } else { mousePosXYZ.z = sqrtf(diffSquared); } mousePosXYZ.z += targetPos.z; ofVec3f mousePosView = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ; bool mousePressedCur[] = {ofGetMousePressed(0), ofGetMousePressed(2)}; //calc new rotation velocity ofQuaternion newRotation; if(mousePressedPrev[0] && mousePressedCur[0]) { newRotation.makeRotate(mousePosViewPrev, mousePosView); } //calc new scale velocity float newDistanceScaleVelocity = 0.0f; if(mousePressedPrev[1] && mousePressedCur[1]) { newDistanceScaleVelocity = zoomSpeed * (mousePosScreenPrev.y - mousePosScreen.y) / viewport.height; } mousePressedPrev[0] = mousePressedCur[0]; mousePressedPrev[1] = mousePressedCur[1]; ofVec3f newTranslation; // TODO: this doesn't work at all. why not? if(ofGetMousePressed() && ofGetKeyPressed(OF_KEY_SHIFT)) { newTranslation = mousePosScreenPrev - mousePosScreen; } //apply drag towards new velocities distanceScaleVelocity = ofLerp(distanceScaleVelocity, newDistanceScaleVelocity, drag); // TODO: add dt rotation.slerp(drag, rotation, newRotation); // TODO: add dt translation.interpolate(newTranslation, drag); mousePosViewPrev = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ; // apply transforms if they're big enough // TODO: these should be scaled by dt if(translation.lengthSquared() > epsilonTransform) { // TODO: this isn't quite right, it needs to move wrt the rotation target.move(translation); } if (rotation.asVec3().lengthSquared() > epsilonTransform) { target.rotate(rotation.conj()); } if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform) { setDistance(getDistance() * (1.0f + distanceScaleVelocity), false); } mousePosScreenPrev = mousePosScreen; //targetFut.setPosition(target.getPosition()); } } } } setAnglesFromOrientation(); } ofCamera::begin(viewport); }