代码之家  ›  专栏  ›  技术社区  ›  ahmedsoubky

OSG OSG::矩阵变换

  •  1
  • ahmedsoubky  · 技术社区  · 11 年前

    我正在尝试在我的应用程序中的抬头显示(HUD)中绘制指南针。我已经成功地将场景中的指南针渲染为纹理几何体。问题是,当我尝试使用osg::MatrixTransfrom和osg::Matrix类旋转指南针时,它会将指南针转换到场景中的错误位置。代码如下:

    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 回复  |  直到 11 年前
        1
  •  1
  •   Keugyeol    10 年前

    我认为z轴旋转的中心位于屏幕左下角的正交2D原点。

    我想知道你是否尝试过:

    在DrawCompass()中,以原点为中心的push_back顶点。

    
        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));
    

    然后,在使用旋转的矩阵设置矩阵之前,将顶点平移到所需位置,即(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);
    

    我不确定它是否有效,因为我没有尝试运行代码。