1
votes

I am trying to draw a compass within Head Up Display(HUD) in my application. I have successfully rendered the compass within the scene as a textured geometry. The question is when I try to rotate the compass using osg::MatrixTransfrom and osg::Matrix classes, it translates the compass to a wrong position in the scene. Here is the code :

osg::ref_ptr<osg::Node> CustomHUD::DrawCompass(void)
{
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->push_back( osg::Vec3(CENTERX-150.0f,0.0f,0.0f));
vertices->push_back( osg::Vec3(CENTERX-150.0f,300.0f,0.0f));
vertices->push_back( osg::Vec3(CENTERX+150.0f,300.0f,0.0f));
vertices->push_back( osg::Vec3(CENTERX+150.0f,0.0f,0.0f));

osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
normals->push_back( osg::Vec3(0.0f,0.0f,-1.0f));

osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array;
texcoords->push_back(osg::Vec2(0.0f,0.0f));
texcoords->push_back(osg::Vec2(0.0f,1.0f));
texcoords->push_back(osg::Vec2(1.0f,1.0f));
texcoords->push_back(osg::Vec2(1.0f,0.0f));

osg::ref_ptr<osg::Geometry> quad = new osg::Geometry;
quad->setVertexArray(vertices.get());
quad->setNormalArray(normals.get());
quad->setNormalBinding(osg::Geometry::BIND_OVERALL);
quad->setTexCoordArray(0,texcoords.get());
quad->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));




osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("/home/ttc/Pictures   compassfinal2.png");
texture->setImage(image.get());
//texture->setTextureSize(500,500);




osg::ref_ptr<osg::Group> mainroot = new osg::Group;
osg::ref_ptr<osg::Geode> drawing2 = new osg::Geode;

drawing2->addDrawable(quad.get());
drawing2->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture.get());
drawing2->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
drawing2->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
drawing2->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);




vtTransform *transnode = new vtTransform;
osg::ref_ptr<osg::MatrixTransform> transnodeosg = new osg::MatrixTransform;

transnodeosg->setMatrix(osg::Matrix::rotate(-0.9,osg::Vec3f(0.0,0.0,1.0)));
transnode->SetOsgTransform(transnodeosg);


transnode->addChild(drawing2);
mainroot->addChild(transnode);
return mainroot.get();

}

osg::Camera* CustomHUD::CreateHUD()
{
// create a camera to set up the projection and model view matrices, and thesubgraph        to draw in the HUD
osg::Camera* camera = new osg::Camera;

// set the projection matrix
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));

// set the view matrix
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());

// only clear the depth buffer
camera->setClearMask(GL_DEPTH_BUFFER_BIT);

// draw subgraph after main camera view.
camera->setRenderOrder(osg::Camera::POST_RENDER);

// we don't want the camera to grab event focus from the viewers main camera(s).
camera->setAllowEventFocus(false);



// add to this camera a subgraph to render
{

    geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    // turn lighting off for the text and disable depth test to ensure it's always ontop.
    osg::StateSet* stateset = geode->getOrCreateStateSet();

    osg::Vec3 position(0.0f,0.0f,0.0f);
    osg::Vec3 delta(0.0f,-120.0f,0.0f);

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );
        text->setFont(timesFont);
        text->setPosition(position);
        text->setText("Egypt Airforces SVS");
        position += delta;
    }

   DrawCenterSymbol();

   camera->addChild(geode);
   camera->addChild(DrawCompass());
   }
1

1 Answers

1
votes

I think the center of the z-axis rotation is at the origin of ortho2D which is at the lower left corner of the screen.

I wonder if you have tried this:

In the DrawCompass(), push_back vertices centered at the origin.


    vertices->push_back( osg::Vec3(-150.0f,-150.0f,0.0f));
    vertices->push_back( osg::Vec3(-150.0f,+150.0f,0.0f));
    vertices->push_back( osg::Vec3(+150.0f,+150.0f,0.0f));
    vertices->push_back( osg::Vec3(+150.0f,-150.0f,0.0f));

And then, before you setMatrix with the rotated one, translate the vertices to the desired position i.e. (CENTERX, 150).


    osg::Matrix mat = osg::Matrix::rotate(-0.9,osg::Vec3f(0.0,0.0,1.0));
    mat = mat * mat.translate(CENTERX, 150.0f, 0);
    transnodeosg->setMatrix(mat);

I am not sure if it would work since I didn't try running the code.