Added osg::Matrix::getOtho,getFrustum and getLookAt() methods.
Added test for new matrix methods into unit tests example, but these really should go in their own lib...
This commit is contained in:
parent
8e0e9d35d8
commit
a4b29996fd
@ -2,6 +2,86 @@
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/ApplicationUsage>
|
||||
|
||||
#include <osg/Matrix>
|
||||
|
||||
|
||||
void testFrustum(double left,double right,double bottom,double top,double zNear,double zFar)
|
||||
{
|
||||
osg::Matrix f;
|
||||
f.makeFrustum(left,right,bottom,top,zNear,zFar);
|
||||
|
||||
|
||||
double c_zNear = f(3,2) / (f(2,2)-1.0f);
|
||||
double c_zFar = f(3,2) / (1.0f+f(2,2));
|
||||
|
||||
double c_left = c_zNear * (f(2,0)-1.0f) / f(0,0);
|
||||
double c_right = c_zNear * (1.0f+f(2,0)) / f(0,0);
|
||||
|
||||
double c_top = c_zNear * (1+f(2,1)) / f(1,1);
|
||||
double c_bottom = c_zNear * (f(2,1)-1.0f) / f(1,1);
|
||||
|
||||
f.getFrustum(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar);
|
||||
|
||||
std::cout << "testFrustum"<<std::endl;
|
||||
std::cout << " left = "<<left<<" compute "<<c_left<<std::endl;
|
||||
std::cout << " right = "<<right<<" compute "<<c_right<<std::endl;
|
||||
|
||||
std::cout << " bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
|
||||
std::cout << " top = "<<top<<" compute "<<c_top<<std::endl;
|
||||
|
||||
std::cout << " zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
|
||||
std::cout << " zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void testOrtho(double left,double right,double bottom,double top,double zNear,double zFar)
|
||||
{
|
||||
osg::Matrix f;
|
||||
f.makeOrtho(left,right,bottom,top,zNear,zFar);
|
||||
|
||||
double c_zNear = (f(3,2)+1.0f) / f(2,2);
|
||||
double c_zFar = (f(3,2)-1.0f) / f(2,2);
|
||||
|
||||
double c_left = -(1.0f+f(3,0)) / f(0,0);
|
||||
double c_right = (1.0f-f(3,0)) / f(0,0);
|
||||
|
||||
double c_bottom = -(1.0f+f(3,1)) / f(1,1);
|
||||
double c_top = (1.0f-f(3,1)) / f(1,1);
|
||||
|
||||
f.getOrtho(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar);
|
||||
|
||||
|
||||
std::cout << "testOrtho"<<std::endl;
|
||||
std::cout << " left = "<<left<<" compute "<<c_left<<std::endl;
|
||||
std::cout << " right = "<<right<<" compute "<<c_right<<std::endl;
|
||||
|
||||
std::cout << " bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
|
||||
std::cout << " top = "<<top<<" compute "<<c_top<<std::endl;
|
||||
|
||||
std::cout << " zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
|
||||
std::cout << " zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void testLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
|
||||
{
|
||||
osg::Matrix mv;
|
||||
mv.makeLookAt(eye,center,up);
|
||||
|
||||
osg::Vec3 c_eye,c_center,c_up;
|
||||
mv.getLookAt(c_eye,c_center,c_up);
|
||||
|
||||
std::cout << "testLookAt"<<std::endl;
|
||||
std::cout << " eye "<<eye<< " compute "<<c_eye<<std::endl;
|
||||
std::cout << " eye "<<center<< " compute "<<c_center<<std::endl;
|
||||
std::cout << " eye "<<up<< " compute "<<c_up<<std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
osg::ArgumentParser arguments(&argc,argv);
|
||||
@ -11,11 +91,21 @@ int main( int argc, char** argv )
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");
|
||||
|
||||
|
||||
if (arguments.argc()<=1)
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool printQualifiedTest = false;
|
||||
while (arguments.read("qt")) printQualifiedTest = true;
|
||||
|
||||
bool displayMatrixTest = false;
|
||||
while (arguments.read("matrix")) displayMatrixTest = true;
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
@ -34,10 +124,20 @@ int main( int argc, char** argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (arguments.argc()<=1)
|
||||
|
||||
if (displayMatrixTest)
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
|
||||
return 1;
|
||||
std::cout<<"****** Running matrix tests ******"<<std::endl;
|
||||
|
||||
testFrustum(-1,1,-1,1,1,1000);
|
||||
testFrustum(0,1,1,2,2.5,100000);
|
||||
|
||||
testOrtho(0,1,1,2,2.1,1000);
|
||||
testOrtho(-1,10,1,20,2.5,100000);
|
||||
|
||||
testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(0.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
|
||||
testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(1.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,6 +107,12 @@ class SG_EXPORT Matrix
|
||||
double bottom, double top,
|
||||
double zNear, double zFar);
|
||||
|
||||
/** Get the othorgraphic settings of the orthographic projection matrix.
|
||||
* Note, if matrix is not an orthographic matrix then invalid values will be returned.*/
|
||||
void getOrtho(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar);
|
||||
|
||||
/** Set to a 2D orthographic projection. See glOrtho2D for further details.*/
|
||||
inline void makeOrtho2D(double left, double right,
|
||||
double bottom, double top)
|
||||
@ -114,19 +120,28 @@ class SG_EXPORT Matrix
|
||||
makeOrtho(left,right,bottom,top,-1.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
/** Set to a perspective projection. See glFrustum for further details.*/
|
||||
void makeFrustum(double left, double right,
|
||||
double bottom, double top,
|
||||
double zNear, double zFar);
|
||||
|
||||
/** Get the frustum setting of a perspective projection matrix.
|
||||
* Note, if matrix is not an orthographic matrix then invalid values will be returned.*/
|
||||
void getFrustum(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar);
|
||||
|
||||
/** Set to a symmetrical perspective projection, See gluPerspective for further details.
|
||||
* Aspect ratio is defined as width/height.*/
|
||||
void makePerspective(double fovy,double aspectRatio,
|
||||
double zNear, double zFar);
|
||||
|
||||
/** Set to the position and orientation as per a camera, using the same convention as gluLookAt. */
|
||||
/** Set to the position and orientation modelview matrix, using the same convention as gluLookAt. */
|
||||
void makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
|
||||
|
||||
/** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */
|
||||
void getLookAt(Vec3& eye,Vec3& center,Vec3& up,float lookDistance=1.0f);
|
||||
|
||||
bool invert( const Matrix& );
|
||||
|
||||
@ -209,31 +224,6 @@ class SG_EXPORT Matrix
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
// temporarily commented out while waiting for a more generic implementation
|
||||
// of MatrixProduct proxy class.
|
||||
// // Helper class to optimize product expressions somewhat
|
||||
// class MatrixProduct {
|
||||
// public:
|
||||
// const Matrix& A;
|
||||
// const Matrix& B;
|
||||
//
|
||||
// MatrixProduct( const Matrix& lhs, const Matrix& rhs ) : A(lhs), B(rhs) {}
|
||||
// };
|
||||
//
|
||||
// inline MatrixProduct operator * ( const Matrix& other ) const
|
||||
// { return MatrixProduct(*this, other); }
|
||||
//
|
||||
// inline void operator = ( const MatrixProduct& p )
|
||||
// {
|
||||
// if( this == &(p.A)) postMult(p.B);
|
||||
// else if( this == &(p.B)) preMult(p.A);
|
||||
// else mult( p.A, p.B );
|
||||
// }
|
||||
//
|
||||
// Matrix( const MatrixProduct& p ) //allows implicit evaluation of the product
|
||||
// { mult( p.A, p.B ); }
|
||||
|
||||
protected:
|
||||
float _mat[4][4];
|
||||
|
||||
|
@ -326,6 +326,21 @@ void Matrix::makeOrtho(double left, double right,
|
||||
SET_ROW(3, tx, ty, tz, 1.0f )
|
||||
}
|
||||
|
||||
void Matrix::getOrtho(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar)
|
||||
{
|
||||
zNear = (_mat[3][2]+1.0f) / _mat[2][2];
|
||||
zFar = (_mat[3][2]-1.0f) / _mat[2][2];
|
||||
|
||||
left = -(1.0f+_mat[3][0]) / _mat[0][0];
|
||||
right = (1.0f-_mat[3][0]) / _mat[0][0];
|
||||
|
||||
bottom = -(1.0f+_mat[3][1]) / _mat[1][1];
|
||||
top = (1.0f-_mat[3][1]) / _mat[1][1];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeFrustum(double left, double right,
|
||||
double bottom, double top,
|
||||
double zNear, double zFar)
|
||||
@ -341,6 +356,20 @@ void Matrix::makeFrustum(double left, double right,
|
||||
SET_ROW(3, 0.0f, 0.0f, D, 0.0f )
|
||||
}
|
||||
|
||||
void Matrix::getFrustum(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar)
|
||||
{
|
||||
zNear = _mat[3][2] / (_mat[2][2]-1.0f);
|
||||
zFar = _mat[3][2] / (1.0f+_mat[2][2]);
|
||||
|
||||
left = zNear * (_mat[2][0]-1.0f) / _mat[0][0];
|
||||
right = zNear * (1.0f+_mat[2][0]) / _mat[0][0];
|
||||
|
||||
top = zNear * (1.0f+_mat[2][1]) / _mat[1][1];
|
||||
bottom = zNear * (_mat[2][1]-1.0f) / _mat[1][1];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makePerspective(double fovy,double aspectRatio,
|
||||
double zNear, double zFar)
|
||||
@ -373,4 +402,15 @@ void Matrix::makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
|
||||
preMult(Matrix::translate(-eye));
|
||||
}
|
||||
|
||||
void Matrix::getLookAt(Vec3& eye,Vec3& center,Vec3& up,float lookDistance)
|
||||
{
|
||||
Matrix inv;
|
||||
inv.invert(*this);
|
||||
eye = osg::Vec3(0.0f,0.0f,0.0f)*inv;
|
||||
up = transform3x3(*this,osg::Vec3(0.0f,1.0f,0.0f));
|
||||
center = transform3x3(*this,osg::Vec3(0.0f,0.0f,-1));
|
||||
center.normalize();
|
||||
center = eye + center*lookDistance;
|
||||
}
|
||||
|
||||
#undef SET_ROW
|
||||
|
Loading…
Reference in New Issue
Block a user