|
Martin, Martin Beckett wrote: Cory Riddell wrote: Sure (although it is extremely rough right now). In my event handler, I handle a KEYUP event and test for 'x', 'y', and 'z' keys. They are all very similar. My 'x' code looks like: if (ea.getKey() == 'x') { // reposition the camera so that the vector from the camera to the center of the vessel is parallel to // the x-axis osg::Vec3d eye, center, up; osgGA::MatrixManipulator* mm = viewer->getCameraManipulator(); mm->getHomePosition(eye, center, up); double centerZ = center.z(); osg::Matrix m = mm->getInverseMatrix(); m.getLookAt(eye, center, up); double radius = eye.length(); populateCameraRepositionArrays(eye, osg::Vec3(radius, 0, centerZ), m_eyePts, center, osg::Vec3(radius-1, 0, centerZ), m_centerPts, up, osg::Vec3(0, 0, 1), m_upPts); } m_eyePts, m_centerPts, and m_upPts are osg::Vec3Arrays. The 0th elements contain the final positions and the nth elements the starting positions. The populateCameraRepositionArrays() is a non-member help function that calculates all the intermediate steps. It looks like: /** Compute a sequence of points from an initial position to a final position. These are used to smoothly * reposition a camera to a predefined position. */ void populateCameraRepositionArrays(const osg::Vec3& initEye, const osg::Vec3& finalEye, osg::Vec3Array* eyePts, const osg::Vec3& initCenter, const osg::Vec3& finalCenter, osg::Vec3Array* centerPts, const osg::Vec3& initUp, const osg::Vec3& finalUp, osg::Vec3Array* upPts) { centerPts->clear(); eyePts->clear(); upPts->clear(); double eyeX1(finalEye.x()), eyeY1(finalEye.y()), eyeZ1(finalEye.z()); double centerX1(finalCenter.x()), centerY1(finalCenter.y()), centerZ1(finalCenter.z()); double upX1(finalUp.x()), upY1(finalUp.y()), upZ1(finalUp.z()); double eyeDeltaX(initEye.x()-eyeX1), eyeDeltaY(initEye.y()-eyeY1), eyeDeltaZ(initEye.z()-eyeZ1); double centerDeltaX(initCenter.x()-centerX1), centerDeltaY(initCenter.y()-centerY1), centerDeltaZ(initCenter.z()-centerZ1); double upDeltaX(initUp.x()-upX1), upDeltaY(initUp.y()-upY1), upDeltaZ(initUp.z()-upZ1); double inc = 1.0 / AUTO_MOVE_STEPS; for (int i=0; i<AUTO_MOVE_STEPS; ++i) { double t = i * inc; eyePts->push_back(osg::Vec3(eyeX1+eyeDeltaX*t, eyeY1+eyeDeltaY*t, eyeZ1+eyeDeltaZ*t)); centerPts->push_back(osg::Vec3(centerX1+centerDeltaX*t, centerY1+centerDeltaY*t, centerZ1+centerDeltaZ*t)); upPts->push_back(osg::Vec3(upX1+upDeltaX*t, upY1+upDeltaY*t, upZ1+upDeltaZ*t)); } } This is just moving the camera along a chord from the initial positions to the final positions. I'm going to make it an arc later. It's using the parametric line equation: | x1 + (x2 - x1) * t | | y1 + (y2 - y1) * t | <-- this is supposed to look like a vector | z1 + (z2 - z1) * t | where 0 <= t < 1 My FRAME event handler looks like: case osgGA::GUIEventAdapter::FRAME: { if (!m_centerPts->empty()) { osg::Vec3 eye, center, up; osgGA::MatrixManipulator* mm = viewer->getCameraManipulator(); osg::Matrix m = mm->getInverseMatrix(); center = m_centerPts->back(); m_centerPts->pop_back(); eye = m_eyePts->back(); m_eyePts->pop_back(); up = m_upPts->back(); m_upPts->pop_back(); if (!m_centerPts->empty()) { // avoid the final setting because it generates exceptions m.makeLookAt(eye, center, up); viewer->getCameraManipulator()->setByInverseMatrix(m); } } } break; Like I said, it's pretty rough, but it works. I'm going to add a time component to prevent the animation from completing too quickly on fast machines (remember computers that used to have a turbo button to run the cpu at 4.77 MHz?). Cory |
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
