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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org