Hi All,
I built a test geometry with about 9M triangles and 27M vertices. The intent of 
my spike solution (attached) is to select a triangle with mouse to change its 
color. I realized that the bottleneck of that code is the line where the camera 
accepts the "osgUtil::IntersectionVisitor" (line 51: camera->accept(iv)). That 
call takes most of the computation time.
Debugging the OSG code I fall into:

void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, 
osg::Drawable* drawable, const osg::Vec3d& s, const osg::Vec3d& e)

In that code there are different methods to be used: KdTree, 
USE_DOUBLE_CALCULATIONS or USE_FLOAT_CALCULATIONS.
On the basis of your experience, is one of the previous method ideal to solve 
my performance issue or something else must be done?

Best regards,
Gianni

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=71281#71281



// materials.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>

#include <chrono>

#include <osg/Geometry>
#include <osg/Geode>
#include <osg/MatrixTransform>
#include <osg/PolygonOffset>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/MultiTouchTrackballManipulator>
#include <osg/PolygonMode>
#include <osg/LineWidth>
#include <osg/ShadeModel>
#include <osg/Material>
#include <osg/PolygonOffset>

#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>

#include <iostream>

class SelectModelHandler : public osgGA::GUIEventHandler
{
public:
        SelectModelHandler()
                : selectedColor(0.5f, 0.5f, 0.5f, 1.0f)
        {}

        virtual bool handle(const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa)
        {
                if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE &&
                        ea.getModKeyMask() & 
osgGA::GUIEventAdapter::MODKEY_CTRL)
                {
                        osgViewer::View* viewer = 
dynamic_cast<osgViewer::View*>(&aa);
                        if (viewer)
                        {
            std::chrono::steady_clock::time_point start1 = 
std::chrono::steady_clock::now();
            osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new 
osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), 
ea.getY());
                                osgUtil::IntersectionVisitor 
iv(intersector.get());
                                osg::Camera* camera = viewer->getCamera();
            std::chrono::steady_clock::time_point end1 = 
std::chrono::steady_clock::now();
            std::cout << "Intersector creation took " << 
std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1).count() << 
" us.\n";
            std::chrono::steady_clock::time_point  start2 = 
std::chrono::steady_clock::now();
                                camera->accept(iv);
            std::chrono::steady_clock::time_point  end2 = 
std::chrono::steady_clock::now();
            std::cout << "Camera accept took " << 
std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2).count() << 
" us.\n";
            std::chrono::steady_clock::time_point start3 = 
std::chrono::steady_clock::now();
                                if (intersector->containsIntersections())
                                {
                                        
osgUtil::LineSegmentIntersector::Intersections& intersections = 
intersector->getIntersections();
                                        
osgUtil::LineSegmentIntersector::Intersection result = *(intersections.begin());
                                        doUserOperationsColor(result);
                                }
            std::chrono::steady_clock::time_point  end3 = 
std::chrono::steady_clock::now();
            std::cout << "Apply color to geometry took " << 
std::chrono::duration_cast<std::chrono::microseconds>(end3 - start3).count() << 
" us.\n";
         }
                }
                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_0) {
                        selectedColor.set(0.5f, 0.5f, 0.5f, 1.0f);
                }
                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1) {
                        selectedColor.set(1.0f, 0.0f, 0.0f, 1.0f);
                }
                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) {
                        selectedColor.set(0.0f, 1.0f, 0.0f, 1.0f);
                }
                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) {
                        selectedColor.set(0.0f, 0.0f, 1.0f, 1.0f);
                }
                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) {
                        selectedColor.set(1.0f, 0.0f, 1.0f, 1.0f);
                }
                return false;
        }

        virtual void 
doUserOperationsColor(osgUtil::LineSegmentIntersector::Intersection& result)
        {
                osg::Geometry* geom = 
dynamic_cast<osg::Geometry*>(result.drawable.get());
                osg::Vec4Array& color = 
dynamic_cast<osg::Vec4Array&>(*geom->getColorArray());
                color[result.indexList[0]] = selectedColor;
                color[result.indexList[1]] = selectedColor;
                color[result.indexList[2]] = selectedColor;
                geom->dirtyDisplayList();
                color.dirty();
        }

protected:
        osg::Vec4 selectedColor;
};

osg::Vec3Array* buildVertices() {
        osg::Vec3Array* vertices = new osg::Vec3Array;
        vertices->push_back(osg::Vec3(0, 0, 0));
        vertices->push_back(osg::Vec3(10, 0, 0));
        vertices->push_back(osg::Vec3(10, 10, 0));

        vertices->push_back(osg::Vec3(0, 10, 0));
        vertices->push_back(osg::Vec3(20, 0, 0));
        vertices->push_back(osg::Vec3(20, 10, 0));
        vertices->push_back(osg::Vec3(20, 20, 0));
        vertices->push_back(osg::Vec3(10, 20, 0));
        vertices->push_back(osg::Vec3(0, 20, 0));
        return vertices;
}

osg::Vec3Array* buildVertices(unsigned int num_rows)
{
        float length = 1.0;
        osg::Vec3Array* vertices = new osg::Vec3Array;
        for (unsigned int j = 0; j < num_rows; ++j)
        {
                for (unsigned int i = 0; i < num_rows; ++i)
                {

                        vertices->push_back(osg::Vec3(i * length, j *length, 
0.0));
                        vertices->push_back(osg::Vec3((i + 1) * length, j 
*length, 0.0));
                        vertices->push_back(osg::Vec3((i)* length, (j + 1) 
*length, 0.0));

                        vertices->push_back(osg::Vec3((i + 1) * length, j 
*length, 0.0));
                        vertices->push_back(osg::Vec3((i + 1) * length, (j + 1) 
*length, 0.0));
                        vertices->push_back(osg::Vec3(i* length, (j + 1) * 
length, 0.0));

                }
        }
        return vertices;
}

osg::DrawElementsUInt* buildElements(unsigned int num_rows)
{
        osg::DrawElementsUInt* element = new 
osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
        for (unsigned int i = 0; i < (num_rows) *(num_rows) * 6; ++i)
        {
                element->push_back(i);
        }

        return element;
}

osg::Vec4Array* buildColors(unsigned int num_rows) {
        osg::Vec4Array* colors = new osg::Vec4Array(num_rows *num_rows * 6);
        std::fill(std::begin(*colors), std::end(*colors), osg::Vec4(0.50f, 
0.5f, 0.5f, 1.0f));
        return colors;
}

osg::Geometry* buildGeometry() {
        unsigned int count = 1500;
        osg::Geometry* geometry = new osg::Geometry;
        geometry->setDataVariance(osg::Object::DYNAMIC);
        geometry->setVertexArray(buildVertices(count));
        geometry->setColorArray(buildColors(count), 
osg::Array::BIND_PER_VERTEX);

        geometry->addPrimitiveSet(buildElements(count));

        return geometry;
}

osg::Node* createScene() {
        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(buildGeometry());
        return geode;
}

void addWireframe(osg::Group* root, osg::Node* scene)
{
        osg::ref_ptr<osg::Group> decorator = new osg::Group;
        decorator->setNodeMask(0x1); //disable wireframe by default

        osg::StateSet* stateset = decorator->getOrCreateStateSet();

        osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
        polyoffset->setFactor(-1.0f);
        polyoffset->setUnits(-1.0f);
        stateset->setAttributeAndModes(polyoffset, 
osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

        osg::PolygonMode* polymode = new osg::PolygonMode;
        polymode->setMode(osg::PolygonMode::FRONT_AND_BACK, 
osg::PolygonMode::LINE);
        stateset->setAttributeAndModes(polymode, osg::StateAttribute::OVERRIDE 
| osg::StateAttribute::ON);

        osg::Material* material = new osg::Material;
        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OVERRIDE | 
osg::StateAttribute::OFF);
        stateset->setAttributeAndModes(material, osg::StateAttribute::OVERRIDE 
| osg::StateAttribute::ON);

        decorator->addChild(scene);
        root->addChild(decorator);
}

int main(int argc, char** argv)
{
        osg::ArgumentParser arguments(&argc, argv);

        osgViewer::Viewer viewer(arguments);

        osg::ref_ptr<osg::Group> root = new osg::Group;
        osg::Node* scene = createScene();
        root->addChild(scene);
        addWireframe(root, scene);

        osg::ref_ptr<SelectModelHandler> selector = new SelectModelHandler;
        viewer.setSceneData(root);
        viewer.addEventHandler(selector.get());
        viewer.setCameraManipulator(new osgGA::TrackballManipulator);

        // add the window size toggle handler
        viewer.addEventHandler(new osgViewer::WindowSizeHandler);
        viewer.addEventHandler(new osgViewer::StatsHandler);
        viewer.run();
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to