Added rescale of quaternion in Matrix::set(Quat), a copy operation in osg::Quat and
extra tracking options in NodeTrackerManipulator.
This commit is contained in:
@@ -62,8 +62,16 @@ void Matrix_implementation::set( value_type a00, value_type a01, value_type a02,
|
||||
#define QZ q._v[2]
|
||||
#define QW q._v[3]
|
||||
|
||||
void Matrix_implementation::set(const Quat& q)
|
||||
void Matrix_implementation::set(const Quat& q_in)
|
||||
{
|
||||
Quat q(q_in);
|
||||
double length2 = q.length2();
|
||||
if (length2!=1.0)
|
||||
{
|
||||
// normalize quat if required.
|
||||
q /= sqrt(length2);
|
||||
}
|
||||
|
||||
// Source: Gamasutra, Rotating Objects Using Quaternions
|
||||
//
|
||||
//http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
NodeTrackerManipulator::NodeTrackerManipulator()
|
||||
{
|
||||
_trackerMode = NODE_CENTER_AND_ROTATION;
|
||||
_trackerMode = NODE_CENTER_AND_AZMIM_ROTATION;
|
||||
_trackerMode = NODE_CENTER_AND_AZMIM_ELEVATION_ROTATION;
|
||||
|
||||
_rotationMode = ELEVATION_AZIM;
|
||||
_distance = 1.0;
|
||||
|
||||
@@ -361,7 +364,67 @@ void NodeTrackerManipulator::computeNodeCenterAndRotation(osg::Vec3d& nodeCenter
|
||||
double sz = 1.0/sqrt(localToWorld(0,2)*localToWorld(0,2) + localToWorld(1,2)*localToWorld(1,2) + localToWorld(2,2)*localToWorld(2,2));
|
||||
localToWorld = localToWorld*osg::Matrixd::scale(sx,sy,sz);
|
||||
|
||||
localToWorld.get(nodeRotation);
|
||||
|
||||
/*
|
||||
Euler Code not in correct coordinate frame, just an experiment here.
|
||||
|
||||
// Assuming the angles are in radians.
|
||||
double heading, attitude, bank = 0;
|
||||
if (localToWorld(0,1) > 0.998)
|
||||
{ // singularity at north pole
|
||||
heading = atan2(localToWorld(2,0),localToWorld(2,2));
|
||||
attitude = osg::PI_2;
|
||||
bank = 0;
|
||||
}
|
||||
else if (localToWorld(0,1) < -0.998)
|
||||
{ // singularity at south pole
|
||||
heading = atan2(localToWorld(2,0),localToWorld(2,2));
|
||||
attitude = -osg::PI_2;
|
||||
bank = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
heading = atan2(-localToWorld(0,2),localToWorld(0,0));
|
||||
bank = atan2(-localToWorld(2,1),localToWorld(1,1));
|
||||
attitude = asin(localToWorld(0,1));
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<"heading = "<<heading<<" attitude="<<attitude<<" bank="<<bank<<std::endl;
|
||||
*/
|
||||
switch(_trackerMode)
|
||||
{
|
||||
case(NODE_CENTER_AND_AZMIM_ROTATION):
|
||||
{
|
||||
double azim = atan2(-localToWorld(0,1),localToWorld(0,0));
|
||||
nodeRotation.makeRotate(-azim,0.0,0.0,1.0);
|
||||
break;
|
||||
}
|
||||
case(NODE_CENTER_AND_AZMIM_ELEVATION_ROTATION):
|
||||
{
|
||||
double azim = atan2(-localToWorld(0,1),localToWorld(0,0));
|
||||
double elevation = acos(localToWorld(2,2));
|
||||
osg::Quat azimRotation;
|
||||
osg::Quat elevationRotation;
|
||||
azimRotation.makeRotate(-azim,0.0,0.0,1.0);
|
||||
elevationRotation.makeRotate(-elevation,0.0,1.0,0.0);
|
||||
nodeRotation = elevationRotation*azimRotation;
|
||||
osg::notify(osg::NOTICE)<<"azimRotation = "<<azim<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"elevationRotation = "<<elevation<<std::endl;
|
||||
break;
|
||||
}
|
||||
case(NODE_CENTER_AND_ROTATION):
|
||||
{
|
||||
localToWorld.get(nodeRotation);
|
||||
break;
|
||||
}
|
||||
case(NODE_CENTER):
|
||||
default:
|
||||
{
|
||||
nodeRotation = osg::Quat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -370,10 +433,7 @@ osg::Matrixd NodeTrackerManipulator::getMatrix() const
|
||||
osg::Vec3d nodeCenter;
|
||||
osg::Quat nodeRotation;
|
||||
computeNodeCenterAndRotation(nodeCenter,nodeRotation);
|
||||
if (_trackerMode==NODE_CENTER)
|
||||
return osg::Matrixd::translate(0.0,0.0,_distance)*osg::Matrixd::rotate(_rotation)*osg::Matrix::translate(nodeCenter);
|
||||
else
|
||||
return osg::Matrixd::translate(0.0,0.0,_distance)*osg::Matrixd::rotate(_rotation)*osg::Matrixd::rotate(nodeRotation)*osg::Matrix::translate(nodeCenter);
|
||||
return osg::Matrixd::translate(0.0,0.0,_distance)*osg::Matrixd::rotate(_rotation)*osg::Matrixd::rotate(nodeRotation)*osg::Matrix::translate(nodeCenter);
|
||||
}
|
||||
|
||||
osg::Matrixd NodeTrackerManipulator::getInverseMatrix() const
|
||||
@@ -381,10 +441,7 @@ osg::Matrixd NodeTrackerManipulator::getInverseMatrix() const
|
||||
osg::Vec3d nodeCenter;
|
||||
osg::Quat nodeRotation;
|
||||
computeNodeCenterAndRotation(nodeCenter,nodeRotation);
|
||||
if (_trackerMode==NODE_CENTER)
|
||||
return osg::Matrixd::translate(-nodeCenter)*osg::Matrixd::rotate(_rotation.inverse())*osg::Matrixd::translate(0.0,0.0,-_distance);
|
||||
else
|
||||
return osg::Matrixd::translate(-nodeCenter)*osg::Matrixd::rotate(nodeRotation.inverse())*osg::Matrixd::rotate(_rotation.inverse())*osg::Matrixd::translate(0.0,0.0,-_distance);
|
||||
return osg::Matrixd::translate(-nodeCenter)*osg::Matrixd::rotate(nodeRotation.inverse())*osg::Matrixd::rotate(_rotation.inverse())*osg::Matrixd::translate(0.0,0.0,-_distance);
|
||||
}
|
||||
|
||||
void NodeTrackerManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up)
|
||||
|
||||
Reference in New Issue
Block a user