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