[osg-users] [vpb] geographic to geocentric coordinate transformation
Christian Schulte
christian.schulte at onera.fr
Fri Jun 19 08:05:53 PDT 2015
Hello Elias,
underneath you will find your corrected and commented example (sorry, I
had to change the lat,lon and models :-) ).
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osg/PositionAttitudeTransform>
int main( int argc, char** argv ) {
osg::ref_ptr<osg::GraphicsContext::Traits> traits;
if(!(traits = new osg::GraphicsContext::Traits()).valid()) {
// print
osg::notify(osg::WARN)
<< " - traits = new osg::GraphicsContext::Traits() ->
invalid : abandon" << std::endl;
// error
return NULL;
}
// set traits properties
traits->screenNum = 0;
traits->x = 40;
traits->y = 40;
traits->width = 1024;
traits->height = 768;
traits->doubleBuffer = true;
traits->windowDecoration = true;
traits->vsync = true;
osg::ref_ptr<osg::GraphicsContext> gc =
osg::GraphicsContext::createGraphicsContext(traits);
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("EC225.ive");
osg::ref_ptr<osg::Node> map =
osgDB::readNodeFile("y:/Bdt/Marseille/marseillemipmaphard09dds.ive");
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
osg::Vec3d center, eye, up;
//Getting XYZ position for cessna
osg::Matrix cessnaLocation;
osg::EllipsoidModel ellipsoid;
double x,y,z;
ellipsoid.convertLatLongHeightToXYZ(osg::DegreesToRadians(43.449310),
osg::DegreesToRadians(5.197525), 200.0, x, y, z);
osg::Vec3 positionForCessna = osg::Vec3d(x,y,z);
//Placing cessna
osg::ref_ptr<osg::PositionAttitudeTransform> moveCessna = new
osg::PositionAttitudeTransform;
moveCessna->setPosition(positionForCessna);
// Calculating attitude (heading north)
double phi = 0.0;
double psi = 0.0;
double theta = 0.0;
osg::Matrixd localToWorld;
osg::Matrixd attitude;
ellipsoid.computeLocalToWorldTransformFromXYZ(osg::DegreesToRadians(43.449310),
osg::DegreesToRadians(5.197525), 200.0, localToWorld);
attitude.makeRotate(
osg::DegreesToRadians(phi), osg::Y_AXIS,
osg::DegreesToRadians(theta), osg::X_AXIS,
osg::DegreesToRadians(-psi), osg::Z_AXIS);
attitude *= localToWorld;
osg::Quat quat = attitude.getRotate();
moveCessna->setAttitude(quat);
moveCessna->addChild(cessna.get());
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
// Create camera as shallow copy of theo ne of the view
camera =
dynamic_cast<osg::Camera*>(viewer->getCamera()->clone(osg::CopyOp::SHALLOW_COPY));
camera->setGraphicsContext(gc);
camera->setProjectionMatrixAsPerspective(40.0,1.33,0.1,10000.0);
camera->setViewport(new osg::Viewport(0, 0, gc->getTraits()->width,
gc->getTraits()->height));
camera->setClearColor(osg::Vec4f(0.5f,0.5f,0.0f,0.0f));
camera->setCullingActive(false);
//Getting XYZ position for camera
//Lat Lon are the same, height is 500.0
// The eye : position of the camera
ellipsoid.convertLatLongHeightToXYZ(osg::DegreesToRadians(43.449310),
osg::DegreesToRadians(5.197525), 500.0, x, y, z);
eye = osg::Vec3d(x,y,z);
// The center : position where you look at (same position a little
bit underneath...
ellipsoid.convertLatLongHeightToXYZ(osg::DegreesToRadians(43.449310),
osg::DegreesToRadians(5.197525), 499.9, x, y, z);
center = osg::Vec3d(x,y,z);
// The up : a little more tricky...
// It is the up vector of your screen (ie what is the bottom top
axis of your screen)
// If you want it to be north up
up = osg::Vec3d ( -std::cos(osg::DegreesToRadians(43.449310)) *
std::sin( osg::DegreesToRadians(5.197525)),
-std::sin(osg::DegreesToRadians(43.449310)) * std::sin(
osg::DegreesToRadians(5.197525)),
std::cos(osg::DegreesToRadians(5.197525)));
// If you want it to be east up
up = osg::Vec3d ( -std::cos(osg::DegreesToRadians(43.449310)),
std::cos(osg::DegreesToRadians(43.449310)),
0.0);
// Now you can set your view matrix
camera->setViewMatrixAsLookAt(eye,center,up);
// Some light for the scene...
osg::ref_ptr<osg::Light> light = new osg::Light();
light->setLightNum(0);
light->setDataVariance(osg::Object::DYNAMIC);
osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource;
lightSource->setLight(light);
lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
// Adding the elements
root->addChild( map.get() );
root->addChild( moveCessna.get() );
root->addChild( lightSource.get());
// Setting up the view
viewer->setCamera( camera.get() );
viewer->setSceneData( root.get() );
osg::ref_ptr<osgViewer::StatsHandler> stats = new
osgViewer::StatsHandler();
viewer->addEventHandler(stats.get());
while (!viewer->done())
{
viewer->frame();
}
return 1;
}
Hope it helps out !
Cheers,
Christian
Le 18/06/2015 20:23, Elias Tarasov a écrit :
> Hello, Christian!
>
> Again, your comments helped me:)
> And again, i can't understand it from the first time.
>
> The root of the problem here is how to move and rotate camera.
> And the root of it is how to calculate needed matrices.
>
> So, i looked for it:
>
> 1. Looked into general OSG forum.
> 2. Looked into vpb forum.
> 3. Stackoverflow.
>
> There are a lot of info but to indicate what kind of problem i have, here is the pattern of what i found:
>
> Vec3d eye( 1000.0, 1000.0, 0.0 );
> Vec3d center( 0.0, 0.0, 0.0 );
> Vec3d up( 0.0, 0.0, 1.0 );
> viewer.getCamera()->setViewMatrixAsLookAt( eye, center, up );
>
> Assumption:
> Vectors must be defined with respect to some choosen coordinate frame.
> So, with respect to what frame eye, center, up are defined?
> How can i calculate them?
> I presume, that without knowing in what frame vectors are expressed, and how to move to that frame from already defined frame (for instance from ECEF),
> variables like Vec3d eye( 1000.0, 1000.0, 0.0 ) are useless.
>
> Here is the code i changed according to your recomendations.
> In the comments, there are at least three issues:
> 1. How to correctly define rotation?
> 2. How to define Up vector.
> 3. How to correctly add moved camera.
>
> int main( int argc, char** argv ) {
>
> osg::ref_ptr<osg::Group> root = new osg::Group;
> osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("c:/OpenSceneGraph/data/cessnafire.osg");
> osg::ref_ptr<osg::Node> map = osgDB::readNodeFile("c:/Terrain/FromUSGS/output/out.osgb");
> osg::ref_ptr<osg::Camera> camera = new osg::Camera;
>
> //Getting XYZ position for cessna
> //-85.4877762 is terrain's center lat
> //30.5292506 is terrain's center lon
> //100 m - height above terrain we want to place the cessna.
> osg::Matrix cessnaLocation;
> osg::EllipsoidModel ellipsoid;
> ellipsoid.computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(-85.4877762), osg::DegreesToRadians(30.5292506), 100, cessnaLocation);
> osg::Vec3 positionForCessna = cessnaLocation.getTrans();
>
> //Placing cessna
> osg::ref_ptr<osg::PositionAttitudeTransform> moveCessna = new osg::PositionAttitudeTransform;
> moveCessna->setPosition(positionForCessna);
> moveCessna->addChild(cessna.get());
>
> //Getting XYZ position for camera
> //Lat Lon are the same, height is 150
> osg::Matrix cameraLocation;
> ellipsoid.computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(-85.4877762), osg::DegreesToRadians(30.5292506), 150, cameraLocation);
> osg::Vec3 positionForCamera = cameraLocation.getTrans();
>
> //Placing camera
> osg::ref_ptr<osg::PositionAttitudeTransform> moveCamera = new osg::PositionAttitudeTransform;
> moveCamera->setPosition(positionForCamera);
> moveCamera->addChild(camera.get());
>
> //rotation and Y up
> //How to setup rotation matrix? with respect to what coordinate frame? I presume View frame with respect to ECEF?
> osg::Matrix rotation;
> rotation.makeRotate(osg::PI_2, osg::Vec3f(1.0, 0.0, 0.0)); //Here we rotate around X on the angle pi/2. But rotate around what?
>
> //How to define that matrix and why does it need?
> osg::Matrix ToYUP; //Maybe here we can define a direction around of which we make our rotation?
>
> //View = translation * YUP * rotation;
> osg::Matrix viewMatrix;
> viewMatrix = cameraLocation * ToYUP * rotation;
> camera->setViewMatrix(viewMatrix);
>
> //How to add moved camera?
> root->addChild(camera.get() );
> //Or maybe even camera->addChild( root.get() ); ?
> root->addChild( moveCessna.get() );
> root->addChild( map.get() );
>
> osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
> viewer->setCamera( camera.get() );
> viewer->setSceneData( root.get() );
>
> return viewer->run();
> }
>
>
> Thank you!
>
> Cheers,
> Elias
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=64123#64123
>
>
>
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
--
SCHULTE Christian
Ingénieur Recherche
Responsable du Laboratoire de Simulation
ONERA - DCSD/PSEV
Département Commande des Systèmes et Dynamique du Vol
ONERA - Centre de Salon de Provence
BA 701
13661 SALON AIR Cedex - France
Tel :04.90.17.01.45
More information about the osg-users
mailing list