void ofEasyCam::mousePressed(ofMouseEventArgs & mouse){ ofRectangle viewport = getViewport(this->viewport); if(viewport.inside(mouse.x, mouse.y)){ lastMouse = mouse; prevMouse = mouse; prevAxisX = getXAxis(); prevAxisY = getYAxis(); prevAxisZ = getZAxis(); prevPosition = ofCamera::getGlobalPosition(); prevOrientation = ofCamera::getGlobalOrientation(); if ((bEnableMouseMiddleButton && mouse.button == OF_MOUSE_BUTTON_MIDDLE) || events->getKeyPressed(doTranslationKey) || mouse.button == OF_MOUSE_BUTTON_RIGHT){ bDoTranslate = true; bDoRotate = false; }else if (mouse.button == OF_MOUSE_BUTTON_LEFT) { bDoTranslate = false; bDoRotate = true; if(ofVec2f(mouse.x - viewport.x - (viewport.width/2), mouse.y - viewport.y - (viewport.height/2)).length() < min(viewport.width/2, viewport.height/2)){ bInsideArcball = true; }else { bInsideArcball = false; } } bApplyInertia = false; } }
void ofEasyCam::mouseScrolled(ofMouseEventArgs & mouse){ ofRectangle viewport = getViewport(this->viewport); prevPosition = ofCamera::getGlobalPosition(); prevAxisZ = getZAxis(); moveZ = mouse.y * 30 * sensitivityZ * (getDistance() + FLT_EPSILON)/ viewport.height; bDoScrollZoom = true; }
//---------------------------------------- void ofEasyCam::mousePressed(ofMouseEventArgs & mouse){ ofRectangle area = getControlArea(); if(area.inside(mouse.x, mouse.y)){ lastMouse = mouse; prevMouse = mouse; prevAxisX = getXAxis(); prevAxisY = getYAxis(); prevAxisZ = getZAxis(); prevPosition = ofCamera::getGlobalPosition(); prevOrientation = ofCamera::getGlobalOrientation(); if((bEnableMouseMiddleButton && mouse.button == OF_MOUSE_BUTTON_MIDDLE) || events->getKeyPressed(doTranslationKey) || mouse.button == OF_MOUSE_BUTTON_RIGHT){ bDoTranslate = true; bDoRotate = false; }else if(mouse.button == OF_MOUSE_BUTTON_LEFT){ bDoTranslate = false; bDoRotate = true; if(glm::length(glm::vec2(mouse.x - area.x - (area.width/2), mouse.y - area.y - (area.height/2))) < std::min(area.width/2, area.height/2)){ bInsideArcball = true; }else{ bInsideArcball = false; } } bApplyInertia = false; } }
//---------------------------------------- void ofEasyCamExt::setDistance(float distance, bool save){//should this be the distance from the camera to the target? if (distance > 0.0f){ if(save){ this->lastDistance = distance; } setPosition(target.getPosition() + (distance * getZAxis())); bDistanceSet = true; } }
//---------------------------------------- void ofEasyCam::mouseScrolled(ofMouseEventArgs & mouse){ if (doInertia) { bApplyInertia = true; } ofRectangle area = getControlArea(); prevPosition = ofCamera::getGlobalPosition(); prevAxisZ = getZAxis(); moveZ = mouse.scrollY * 30 * sensitivityZ * (getDistance() + FLT_EPSILON)/ area.height; bDoScrollZoom = true; bIsBeingScrolled = true; }
//---------------------------------------- void ofEasyCam::updateTranslation(){ 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 ofEasyCam::updateTranslation(){ 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)); }else{ setPosition(prevPosition + ofVec3f(prevAxisX * moveX) + (prevAxisY * moveY) + (prevAxisZ * moveZ)); } }
//---------------------------------------- void ofEasyCam::updateRotation(){ if (bApplyInertia) { xRot *=drag; yRot *=drag; zRot *=drag; if (ABS(xRot) <= minDifference && ABS(yRot) <= minDifference && ABS(zRot) <= minDifference) { bApplyInertia = false; bDoRotate = false; } curRot = ofQuaternion(xRot, getXAxis(), yRot, getYAxis(), zRot, getZAxis()); setPosition((getGlobalPosition()-target.getGlobalPosition())*curRot +target.getGlobalPosition()); rotate(curRot); }else{ curRot = ofQuaternion(xRot, prevAxisX, yRot, prevAxisY, zRot, prevAxisZ); setPosition((prevPosition-target.getGlobalPosition())*curRot +target.getGlobalPosition()); setOrientation(prevOrientation * curRot); } }
//---------------------------------------- void ofEasyCam::updateRotation(){ if(bApplyInertia){ xRot *=drag; yRot *=drag; zRot *=drag; if(ABS(xRot) <= minDifference && ABS(yRot) <= minDifference && ABS(zRot) <= minDifference){ xRot = 0; yRot = 0; zRot = 0; bApplyInertia = false; bDoRotate = false; } curRot = glm::angleAxis(zRot, getZAxis()) * glm::angleAxis(yRot, up()) * glm::angleAxis(xRot, getXAxis()); setPosition(curRot * (getGlobalPosition()-target.getGlobalPosition()) + target.getGlobalPosition()); rotate(curRot); }else if(bDoRotate){ curRot = glm::angleAxis(zRot, prevAxisZ) * glm::angleAxis(yRot, up()) * glm::angleAxis(xRot, prevAxisX); setPosition(curRot * (prevPosition-target.getGlobalPosition()) + target.getGlobalPosition()); setOrientation(curRot * prevOrientation); } }
//---------------------------------------- void ofEasyCam::updateTranslation(){ if(bApplyInertia){ moveX *= drag; moveY *= drag; moveZ *= drag; if(ABS(moveZ) >= minDifference){ bIsBeingScrolled = true; } else { bIsBeingScrolled = false; } if(ABS(moveX) <= minDifference && ABS(moveY) <= minDifference && ABS(moveZ) <= minDifference){ bApplyInertia = false; bDoTranslate = false; } move((getXAxis() * moveX) + (getYAxis() * moveY) + (getZAxis() * moveZ)); }else if(bDoTranslate || bIsBeingScrolled){ setPosition(prevPosition + glm::vec3(prevAxisX * moveX) + (prevAxisY * moveY) + (prevAxisZ * moveZ)); bIsBeingScrolled = false; } }
int main(void) { wdt_enable(WDTO_1S); //odDebugInit(); //DBG1(0x00, 0, 0); /* debug output: main starts */ mouseInit(); usbInit(); usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ uchar i = 0; while(--i){ /* fake USB disconnect for > 250 ms */ wdt_reset(); _delay_ms(1); } usbDeviceConnect(); sei(); //DBG1(0x01, 0, 0); /* debug output: main loop starts */ for(;;){ /* main event loop */ //DBG1(0x02, 0, 0); /* debug output: main loop iterates */ wdt_reset(); usbPoll(); reportBuffer[0]=getXAxis(); reportBuffer[1]=getYAxis(); reportBuffer[2]=getZAxis(); if(usbInterruptIsReady()){ // called after every poll of the interrupt endpoint //DBG1(0x03, 0, 0); // debug output: interrupt report prepared usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer)); } } }
void ofxGameCamera::updateRotation(){ if(!applyRotation) return; // cout << "update rotation!" << endl; if(dampen){ rotationX += (targetXRot - rotationX) *.2; rotationY += (targetYRot - rotationY) *.2; rotationZ += (targetZRot - rotationZ) *.2; } else{ rotationX = targetXRot; rotationY = targetYRot; rotationZ = targetZRot; } setOrientation(ofQuaternion(0,0,0,1)); //reset setOrientation(getOrientationQuat() * ofQuaternion(-rotationZ, getZAxis())); setOrientation(getOrientationQuat() * ofQuaternion(-rotationX, getYAxis())); setOrientation(getOrientationQuat() * ofQuaternion(-rotationY, getXAxis())); targetNode.setOrientation(getOrientationQuat()); }
//---------------------------------------- glm::vec3 ofNode::getLookAtDir() const { return -getZAxis(); }
//---------------------------------------- void ofNode::rollRad(float radians) { rotateRad(radians, getZAxis()); }
//---------------------------------------- void ofNode::rollDeg(float degrees) { rotateDeg(degrees, getZAxis()); }
//---------------------------------------- void ofNode::dolly(float amount) { move(getZAxis() * amount); }
//---------------------------------------- ofVec3f ofNode::getLookAtDir() const { return -getZAxis(); }
void ParaxialTexCoordSystem::doTransform(const Plane3& oldBoundary, const Mat4x4& transformation, BrushFaceAttributes& attribs, bool lockTexture, const Vec3& oldInvariant) { const Vec3 offset = transformation * Vec3::Null; const Vec3& oldNormal = oldBoundary.normal; Vec3 newNormal = transformation * oldNormal - offset; assert(Math::eq(newNormal.length(), 1.0)); // fix some rounding errors - if the old and new texture axes are almost the same, use the old axis if (newNormal.equals(oldNormal, 0.01)) newNormal = oldNormal; if (!lockTexture || attribs.xScale() == 0.0f || attribs.yScale() == 0.0f) { setRotation(newNormal, attribs.rotation(), attribs.rotation()); return; } // calculate the current texture coordinates of the origin const Vec2f oldInvariantTexCoords = computeTexCoords(oldInvariant, attribs.scale()) + attribs.offset(); // project the texture axes onto the boundary plane along the texture Z axis const Vec3 boundaryOffset = oldBoundary.project(Vec3::Null, getZAxis()); const Vec3 oldXAxisOnBoundary = oldBoundary.project(m_xAxis * attribs.xScale(), getZAxis()) - boundaryOffset; const Vec3 oldYAxisOnBoundary = oldBoundary.project(m_yAxis * attribs.yScale(), getZAxis()) - boundaryOffset; // transform the projected texture axes and compensate the translational component const Vec3 transformedXAxis = transformation * oldXAxisOnBoundary - offset; const Vec3 transformedYAxis = transformation * oldYAxisOnBoundary - offset; const Vec2f textureSize = attribs.textureSize(); const bool preferX = textureSize.x() >= textureSize.y(); /* const FloatType dotX = transformedXAxis.normalized().dot(oldXAxisOnBoundary.normalized()); const FloatType dotY = transformedYAxis.normalized().dot(oldYAxisOnBoundary.normalized()); const bool preferX = Math::abs(dotX) < Math::abs(dotY); */ // obtain the new texture plane norm and the new base texture axes Vec3 newBaseXAxis, newBaseYAxis, newProjectionAxis; const size_t newIndex = planeNormalIndex(newNormal); axes(newIndex, newBaseXAxis, newBaseYAxis, newProjectionAxis); const Plane3 newTexturePlane(0.0, newProjectionAxis); // project the transformed texture axes onto the new texture projection plane const Vec3 projectedTransformedXAxis = newTexturePlane.project(transformedXAxis); const Vec3 projectedTransformedYAxis = newTexturePlane.project(transformedYAxis); assert(!projectedTransformedXAxis.nan() && !projectedTransformedYAxis.nan()); const Vec3 normalizedXAxis = projectedTransformedXAxis.normalized(); const Vec3 normalizedYAxis = projectedTransformedYAxis.normalized(); // determine the rotation angle from the dot product of the new base axes and the transformed, projected and normalized texture axes float cosX = static_cast<float>(newBaseXAxis.dot(normalizedXAxis.normalized())); float cosY = static_cast<float>(newBaseYAxis.dot(normalizedYAxis.normalized())); assert(!Math::isnan(cosX)); assert(!Math::isnan(cosY)); float radX = std::acos(cosX); if (crossed(newBaseXAxis, normalizedXAxis).dot(newProjectionAxis) < 0.0) radX *= -1.0f; float radY = std::acos(cosY); if (crossed(newBaseYAxis, normalizedYAxis).dot(newProjectionAxis) < 0.0) radY *= -1.0f; // TODO: be smarter about choosing between the X and Y axis rotations - sometimes either // one can be better float rad = preferX ? radX : radY; // for some reason, when the texture plane normal is the Y axis, we must rotation clockwise if (newIndex == 4) rad *= -1.0f; const float newRotation = Math::correct(Math::normalizeDegrees(Math::degrees(rad)), 4); doSetRotation(newNormal, newRotation, newRotation); // finally compute the scaling factors Vec2f newScale = Vec2f(projectedTransformedXAxis.length(), projectedTransformedYAxis.length()).corrected(4); // the sign of the scaling factors depends on the angle between the new texture axis and the projected transformed axis if (m_xAxis.dot(normalizedXAxis) < 0.0) newScale[0] *= -1.0f; if (m_yAxis.dot(normalizedYAxis) < 0.0) newScale[1] *= -1.0f; // compute the parameters of the transformed texture coordinate system const Vec3 newInvariant = transformation * oldInvariant; // determine the new texture coordinates of the transformed center of the face, sans offsets const Vec2f newInvariantTexCoords = computeTexCoords(newInvariant, newScale); // since the center should be invariant, the offsets are determined by the difference of the current and // the original texture coordiknates of the center const Vec2f newOffset = attribs.modOffset(oldInvariantTexCoords - newInvariantTexCoords).corrected(4); assert(!newOffset.nan()); assert(!newScale.nan()); assert(!Math::isnan(newRotation)); assert(!Math::zero(newScale.x())); assert(!Math::zero(newScale.y())); attribs.setOffset(newOffset); attribs.setScale(newScale); attribs.setRotation(newRotation); }
//---------------------------------------- void ofEasyCamExt::updateTranslation() { move((getXAxis() * moveX) + (getYAxis() * moveY) + (getZAxis() * moveZ)); }
//---------------------------------------- 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::updateRotation() { rotationX += (targetXRot - rotationX) *.1; rotationY += (targetYRot - rotationY) *.1; rotationZ += (targetZRot - rotationZ) *.1; target.setOrientation(ofQuaternion(0,0,0,1)); //reset ofQuaternion p = ((getOrientationQuat() * ofQuaternion(-rotationY, getXAxis())) * ofQuaternion(-rotationX, getYAxis())) * ofQuaternion(-rotationZ, getZAxis()); target.setOrientation(p); }