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
[email protected]
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
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org