[osg-users] Rendering double triangles as one quad

OpenSceneGraph Users osg-users at lists.openscenegraph.org
Thu Jun 4 01:31:22 PDT 2020


>
> Hello!
>

I will post my solution to this in case someone is interested.

I solved it by having two different geometries controlled by one switch 
node, and depending on the rendermode i control which one is visible.


void OsgSceneMesh::constructVertexAttribute(GI::SceneMesh* sceneMesh, osg::Geode* geode, osg::Geometry* geometry, bool constructSkeletonMesh)    
{
    osg::ref_ptr<osg::Vec3Array>    vertices = new osg::Vec3Array();

    osg::ref_ptr<osg::Vec3Array>    normals = new osg::Vec3Array();

    osg::ref_ptr<osg::Vec2Array>    texCoords  = new osg::Vec2Array();

    osg::ref_ptr<osg::Vec2Array>    texCoords2  = new osg::Vec2Array();


    osg::ref_ptr<osg::DrawElements> indices;


    if(constructSkeletonMesh) indices = static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_LINE_LOOP));

    else indices =  static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(

                                sceneMesh->getType() == GI::MeshType::LINE ?  GL_LINES : GL_TRIANGLES));


    osg::ref_ptr<osg::Vec4Array>    vertexColor = new osg::Vec4Array;


    std::vector<long unsigned int> sceneMeshIndices = sceneMesh->getIndices();

    std::vector<GI::Vertex> sceneMeshVertices = sceneMesh->getVertices();


    //push in vertices

    for(const auto & vertex : sceneMeshVertices)

    {

        vertices->push_back(osg::Vec3(vertex.x_, vertex.y_, vertex.z_));

        normals->push_back(osg::Vec3(vertex.nx_, vertex.ny_, vertex.nz_));

        texCoords->push_back(osg::Vec2(vertex.u_, vertex.v_));

        texCoords2->push_back(osg::Vec2(vertex.u_, vertex.v_));

        vertexColor->push_back(osg::Vec4(vertex.r_,vertex.g_,vertex.b_, 1.f));

    }


    //push in indices

    for(const auto & index : sceneMeshIndices)

    {

        indices->addElement(index);

    }


    //texture buffer and color values later

    geometry->setVertexArray(vertices.get());

    geometry->setNormalArray(normals.get(), osg::Array::BIND_PER_VERTEX);

    geometry->setTexCoordArray(0, texCoords, osg::Array::BIND_PER_VERTEX);

    geometry->setTexCoordArray(1, texCoords2, osg::Array::BIND_PER_VERTEX);

    geometry->setColorArray(vertexColor.get(), osg::Array::BIND_PER_VERTEX);

    geometry->addPrimitiveSet(indices.get());


    geode->addDrawable(geometry);
}



the render mode is controlled through this function 

void OsgSceneMesh::updateRenderMode(GI::PolygonMode polygonMode)

{

    if(this->getNumChildren() < 2) return; //this means we havent initialized the mesh yet


    //set enable/disable skeleton mesh only at wireframe quad polygonmode

    // 0 == skeleton mesh, 1 == triangle mesh


    osg::PolygonMode * osgPolygonMode = new osg::PolygonMode;


    switch(polygonMode)

    {

        case GI::PolygonMode::SOLID :

        {

            this->setValue(0, true);

            this->setValue(1, false);

            osgPolygonMode->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);

            triangleMeshVisible_ = true;

            break;

        }

        case GI::PolygonMode::WIREFRAME_TRIANGLE :

        {

            this->setValue(0, true);

            this->setValue(1, false);

            osgPolygonMode->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);

            triangleMeshVisible_ = true;

            break;

        }

        case GI::PolygonMode::WIREFRAME_QUAD :

        {

            this->setValue(0, false);

            this->setValue(1, true);

            osgPolygonMode->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);

            triangleMeshVisible_ = false;

            break;

        }

    }


    this->getOrCreateStateSet()->setAttributeAndModes( osgPolygonMode,

    osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON );

}


This works fine except for one thing, my intersection raycaster does not 
handle the LINE LOOP mesh when the triangle node is switched off. 

I solved it by creating a node visitor

OsgGeodeMeshActivatorVisitor::OsgGeodeMeshActivatorVisitor(const bool& isReset) :

    isReset_(isReset)

{

    this->setTraversalMode(osg::NodeVisitor::TraversalMode::TRAVERSE_ALL_CHILDREN);

}

void OsgGeodeMeshActivatorVisitor::apply(osg::Node& node)

{

    switchGeodeVisibility(node);

}


void OsgGeodeMeshActivatorVisitor::switchGeodeVisibility(osg::Node& node)

{

    osg::Group* group = node.asGroup();

    if ( !group ) return;


    if(group->getNumChildren() == 0) return;

    for ( unsigned int i=0; i<group->getNumChildren(); ++i )

    {

        OsgSceneMesh* osgSceneMesh = dynamic_cast<OsgSceneMesh*>(group->getChild(0));

        if(osgSceneMesh)

        {

            if(isReset_)  osgSceneMesh->resetTriangleMeshVisible();

            else osgSceneMesh->forceTriangleMeshVisible();


        }

        switchGeodeVisibility(*group->getChild(i));

    }

}



which can force triangle mesh visibility on and reset to original value.

Now in my intersection algorithm i simply force visibility on by accepting 
the visitor on the root node in my tree.

osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector

            = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::WINDOW, mousePosition.x(),  viewportModel_->getHeight() - mousePosition.y());




    osgUtil::IntersectionVisitor intersectionVisitor ( intersector.get() );

    intersectionVisitor.setTraversalMask( ~0x1 ); // mask, things that we dont want to be selected sets 0x1


    osg::Camera* osgCamera = viewer_->getCamera();


    OsgGeodeMeshActivatorVisitor geodeVisibilitySwitchOn(false);

    OsgGeodeMeshActivatorVisitor geodeVisibiltyReset(true);


    osg::Node* root = viewer_->getSceneData();


    root->accept(geodeVisibilitySwitchOn);


    if(osgCamera) osgCamera->accept( intersectionVisitor );

    else

    {

        root->accept(geodeVisibiltyReset);

        return rayTracedMeshPairVector;

    }


    root->accept(geodeVisibiltyReset);


    if( !intersector->containsIntersections() )

    {

        return rayTracedMeshPairVector;

    }

    else

    {

      //work with result, not included in this demo

       }



 And thats it, now we have the possibility to render triangulated wireframe , quaded wireframe and solid structures while intersection with the meshes are possible. here is an image of the result..


https://imgur.com/a/hFh6aGm




Have a good day


//Dan



 

-- 
You received this message because you are subscribed to the Google Groups "OpenSceneGraph Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osg-users+unsubscribe at googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osg-users/6d6b967e-b5e5-4efa-b9ef-bdd7403f4b06%40googlegroups.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20200604/a5b19d4c/attachment-0001.html>


More information about the osg-users mailing list