diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index c70f87565..49e14bfa0 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -275,6 +275,7 @@ namespace CSVRender , mRollLeft(false) , mRollRight(false) , mCenter(0,0,0) + , mDistance(0) , mCenterNode(new osg::PositionAttitudeTransform()) { group->addChild(mCenterNode); @@ -343,7 +344,7 @@ namespace CSVRender if (mode == "p-navi") { rotateHorizontal(x * getMouseScalar()); - rotateVertical(y * getMouseScalar()); + rotateVertical(-y * getMouseScalar()); setModified(); } else if (mode == "s-navi") @@ -353,7 +354,7 @@ namespace CSVRender } else if (mode == "t-navi") { - zoom(x * (mFast ? SpeedMultiplier : 1)); + zoom(-x * (mFast ? SpeedMultiplier : 1)); } else { @@ -392,8 +393,6 @@ namespace CSVRender mCenterNode->setPosition(mCenter); - lookAtCenter(); - // Normalize the matrix to counter drift getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); @@ -412,6 +411,8 @@ namespace CSVRender osg::Vec3d eye, up; getCamera()->getViewMatrixAsLookAt(eye, mCenter, up, DefaultStartDistance); + mDistance = DefaultStartDistance; + mInitialized = true; } @@ -430,26 +431,27 @@ namespace CSVRender void OrbitCameraController::rotateHorizontal(double value) { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = position - mCenter; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Quat offsetRotation = osg::Quat(value, LocalUp); - osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + osg::Quat rotation = osg::Quat(value, up); + osg::Vec3d oldOffset = eye - mCenter; + osg::Vec3d newOffset = rotation * oldOffset; - getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } void OrbitCameraController::rotateVertical(double value) { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = position - mCenter; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Quat offsetRotation = osg::Quat(value, LocalLeft); - osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + osg::Vec3d forward = center - eye; + osg::Quat rotation = osg::Quat(value, up ^ forward); + osg::Vec3d oldOffset = eye - mCenter; + osg::Vec3d newOffset = rotation * oldOffset; - getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } void OrbitCameraController::roll(double value) @@ -465,24 +467,13 @@ namespace CSVRender void OrbitCameraController::zoom(double value) { - osg::Vec3d dir = mCenter - getCamera()->getViewMatrix().getTrans(); - double distance = dir.normalize(); + mDistance = std::max(10., mDistance + value); - if (distance > 1 || value < 0) - { - getCamera()->getViewMatrix() *= osg::Matrixd::translate(dir * value); - } - } - - void OrbitCameraController::lookAtCenter() - { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = mCenter - position; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up, 1.f); - osg::Quat newRotation; - newRotation.makeRotate(LocalForward, offset); + osg::Vec3d offset = (eye - center) * mDistance; - getCamera()->getViewMatrix().setRotate(newRotation); + getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up); } } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 6c89d20f7..78afe2320 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -119,11 +119,10 @@ namespace CSVRender void translate(const osg::Vec3d& offset); void zoom(double value); - void lookAtCenter(); - bool mInitialized; bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; osg::Vec3d mCenter; + double mDistance; osg::ref_ptr mCenterNode; };