Re: [osg-users] Visibility of lines

2012-12-18 Thread Jen Hunter
Hi, 

I think there might be a small bug in osg::OcclusionQueryNode, that I've yet to 
find.

Here is a small example with a line triangle, that shows the problem.
I added no face geometry so the lines should basically always be visible when 
in view.
Each line is under an OcclusionQueryNode, but under some camera poses using the 
trackball manipulator, line 3 isn't visible, although it should be.
When I put all the lines in a osg::Group, they are visible.

Does anybody have an idea where the problem might be?


Code:

#include  
#include  
#include 
#include 
#include 
#include 

 int main( int argc, char** argv ) 
 { 
int width = 640;
int height = 480;

osgViewer::Viewer viewer;
osg::ref_ptr camera = new osg::Camera;
camera->setClearColor(osg::Vec4(1.0, 1.0, 1.0, 0.0)); 
camera->setViewport( new osg::Viewport(0, 0, width, height) );
camera->setProjectionMatrixAsPerspective(30.0f, 
static_cast(width)/static_cast(height), 1.0f, 1.0f );
viewer.setCamera(camera);

osg::Group* rootnode = new osg::Group;
viewer.setSceneData(rootnode);
viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.setUpViewInWindow(200, 200, width, height);
viewer.setCameraManipulator( new osgGA::TrackballManipulator );

std::vector lines;

//Line 1
lines.push_back(osg::Vec3(-1,0,0));
lines.push_back(osg::Vec3(0,1,0));

//Line 2
lines.push_back(osg::Vec3(0,1,0));
lines.push_back(osg::Vec3(1,0,0));

//Line 3
lines.push_back(osg::Vec3(1,0,0));
lines.push_back( osg::Vec3(-1,0,0));

for(int i = 0; i < 3; i++){

//osg::ref_ptr parent = new osg::Group;
osg::ref_ptr parent = new 
osg::OcclusionQueryNode;
parent->setVisibilityThreshold(1);
parent->setQueriesEnabled(true);

osg::Geometry* linesGeom = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(lines.at(i+i));
vertices->push_back(lines.at(i+i+1));
osg::Vec4Array* color = new osg::Vec4Array;
color->push_back(osg::Vec4(1,0,0,1));
linesGeom->setColorArray(color);
linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
linesGeom->setVertexArray(vertices);
linesGeom->addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
osg::Geode* geode = new osg::Geode();
geode->addDrawable(linesGeom);
parent->addChild(geode);
rootnode->addChild(parent);
}
return viewer.run();
 }




Cheers,
Dakota

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





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Visibility of lines

2012-12-12 Thread Robert Osfield
Hi Jen,

I haven't personally used the OcclusionQueryNode for work myself, perhaps
Paul Martz the author of this feature might be able to chip in.

Robert.

On 12 December 2012 12:39, Jen Hunter  wrote:

> Hi Robert,
>
> thank you for your reply. I appreciate your help :)
>
> I'm sorry if I didn't express myself correctly. I also have to admit I'm
> not quite the expert on computer graphics.
>
> Let's try to make it clearer. I want to know which of the lines on my
> model are visible in a rendered image. That would be the case if a line
> results in at least one drawn pixel.
>
> I need to have this information for an AR application which performs edge
> tracking. Such approaches work with 2D-3D correspondences for each frame to
> estimate the camera parameters.
> The recorded webcam image of an object shows of course only the edges of
> the object which are visible from the cameras point of view. To get the
> correspondences I need excactly the same lines on the model (from the last
> frame).
>
> I programmed a working OPENGL example for finding out the visible lines
> using occlusion query glGetOcclusionQueryuivNV.
>
> At the moment I fail to understand how to make that work for OSG. I had a
> look at osgocclusionquery and the used OcclusionQueryNode and understand
> that it uses ARB_occlusion_query to check the pixel count.
>
> I tried the following but the output of the visible lines is still
> incorrect:
>
>
> Code:
>
> osg::Node* scene = osgDB::readNodeFile("file.dae");
> if (!scene) return 1;
>
> osg::Group* rootnode = new osg::Group;
> rootnode->addChild(scene);
> viewer.setSceneData(rootnode);
>
> GetLinesVisitor lineFinder;
> scene->accept(lineFinder);
> lines = lineFinder.getLineVector();
>
> for(int i = 0; i < lines.size(); i++){
>
> osg::ref_ptr parent = new
> osg::OcclusionQueryNode;
> parent->setVisibilityThreshold( 0 );
>
> osg::Geometry* linesGeom = new osg::Geometry();
> osg::Vec3Array* vertices = new osg::Vec3Array;
> vertices->push_back(lines.at(i).start);
> vertices->push_back(lines.at(i).end);
> linesGeom->setVertexArray(vertices);
> linesGeom->addPrimitiveSet(new
> osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
>
> osg::Geode* geode = new osg::Geode();
> geode->addDrawable(linesGeom);
> parent->addChild(geode);
>
>
> //A std::vector for all OcclusionQueryNodes. I later ask in a loop
> for each element oqNodes.at(i).get()->getPassed() and count the trues
> oqNodes.push_back(parent);
> rootnode->addChild(parent);
> }
>
>
>
>
>
>
> So here are my questions:
>
> (1) How do I set up an OcclusionQueryNode for each line?
>
> (2) Why does the approach from my previous post not work? Is the
> calculation of screen coordinates (using MVPW matrix) for a given vertex
> really so imprecise that I cannot count on this being the correct
> coordinates to look up in the depth buffer?
>
>
> Cheers,
> Dakota
>
> --
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=51538#51538
>
>
>
>
>
> ___
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Visibility of lines

2012-12-12 Thread Jen Hunter
Hi Robert,

thank you for your reply. I appreciate your help :)

I'm sorry if I didn't express myself correctly. I also have to admit I'm not 
quite the expert on computer graphics.

Let's try to make it clearer. I want to know which of the lines on my model are 
visible in a rendered image. That would be the case if a line results in at 
least one drawn pixel.

I need to have this information for an AR application which performs edge 
tracking. Such approaches work with 2D-3D correspondences for each frame to 
estimate the camera parameters.
The recorded webcam image of an object shows of course only the edges of the 
object which are visible from the cameras point of view. To get the 
correspondences I need excactly the same lines on the model (from the last 
frame).

I programmed a working OPENGL example for finding out the visible lines using 
occlusion query glGetOcclusionQueryuivNV. 

At the moment I fail to understand how to make that work for OSG. I had a look 
at osgocclusionquery and the used OcclusionQueryNode and understand that it 
uses ARB_occlusion_query to check the pixel count.

I tried the following but the output of the visible lines is still incorrect:


Code:

osg::Node* scene = osgDB::readNodeFile("file.dae");
if (!scene) return 1;

osg::Group* rootnode = new osg::Group;
rootnode->addChild(scene);
viewer.setSceneData(rootnode);

GetLinesVisitor lineFinder; 
scene->accept(lineFinder);
lines = lineFinder.getLineVector();

for(int i = 0; i < lines.size(); i++){

osg::ref_ptr parent = new 
osg::OcclusionQueryNode;
parent->setVisibilityThreshold( 0 );

osg::Geometry* linesGeom = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(lines.at(i).start);
vertices->push_back(lines.at(i).end);
linesGeom->setVertexArray(vertices);
linesGeom->addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));

osg::Geode* geode = new osg::Geode();
geode->addDrawable(linesGeom);
parent->addChild(geode);


//A std::vector for all OcclusionQueryNodes. I later ask in a loop for 
each element oqNodes.at(i).get()->getPassed() and count the trues
oqNodes.push_back(parent);
rootnode->addChild(parent);
}






So here are my questions:

(1) How do I set up an OcclusionQueryNode for each line?

(2) Why does the approach from my previous post not work? Is the calculation of 
screen coordinates (using MVPW matrix) for a given vertex really so imprecise 
that I cannot count on this being the correct coordinates to look up in the 
depth buffer?


Cheers,
Dakota

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





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Visibility of lines

2012-12-05 Thread Robert Osfield
On 5 December 2012 16:31, Robert Osfield  wrote:

> Are you away of the OpenGL occlusion querry feature?
>

Opps typo, "away" should be "aware".  Have a look at the osgocclusionquery
example for more details.

Robert.
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] Visibility of lines

2012-12-05 Thread Robert Osfield
Hi Jen,

I'll not dive into the details of how you are going about things as I
suspect it might be best to tackle things in a different way.

So.. could you explain from a higher level what you need to do and for what
purpose.  Please explain what exactly you mean by visible - just in the
view frustum or do you mean just contributes pixels to the final on
screen?  Are you away of the OpenGL occlusion querry feature?

Robert.

On 5 December 2012 11:28, Jen Hunter  wrote:

> Dear osg community,
>
> currently I need to find out which lines were visible in last drawn frame.
>
> My current approach is the following:
>
> (1) I use a NodeVisitor to check the loaded model for lines. I store the
> vertices of each line in a class LineData. Every LineData object is stored
> in a vector.
>
> (2) Knowing the lines I want to determine which of them were visible in
> the last view. I calculate the screen coordinates for each vertex of a line
> (vec = V * modelViewMatrix * projectionMatrix * windowMatrix).
>
> (3) Then I convert the z values of the screen coordinates to depth values
> using Znear*Zfar / (Zfar - vec.z()*(Zfar-Znear)).
>
> (4) After that I check the depth buffer of the last frame at the position
> of the screen coordinates and also extract the depth value using the
> formula from (3).
>
> (5) Then I substract both depth values and for the start and the end point
> of the line and if both results are under a specified threshold i count the
> line as visible.
>
> However, I think in theory it should be working this way, but the
> calculated number of visible lines is almost always wrong. I found out that
> for some calculated screen coordinates one dimension is one pixel off, so
> that I do not access the correct pixel in the depth buffer which is why the
> returned value of these is the zfar value and not the wanted depth.
>
>
> I attached some code and a model to show my problem. When you click at a
> point on the model the visible lines are calculated. While the camera is in
> home position the output of the visible lines on the command line is 4
> which is correct. When you move the camera and try different poses the
> number of calculated visible lines changes but almost never to the desired
> number which can be counted on the rendered image.
>
>
> Code:
>
> #include 
>
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
>
> #include 
> #include 
> #include 
> #include 
>
> osg::Matrix lastViewMatrix;
>
> struct CaptureCB : public osg::Camera::DrawCallback{
>
> CaptureCB(osg::ref_ptrimg1){
> image3D = img1;
> }
> virtual void operator()( osg::RenderInfo& ri ) const{
>
> image3D->readPixels( 0, 0,
> ri.getCurrentCamera()->getViewport()->width(),
> ri.getCurrentCamera()->getViewport()->height(), GL_DEPTH_COMPONENT,
> GL_FLOAT );
> osg::ref_ptr  osgCam = ri.getCurrentCamera();
> osgCam->attach(osg::Camera::DEPTH_BUFFER,image3D.get());
> lastViewMatrix = ri.getCurrentCamera()->getViewMatrix();
> }
> protected:
> osg::ref_ptrimage3D;
>
> };
>
> class LineData{
>
> public:
> LineData(){};
> ~LineData(){};
>
> osg::Vec3 start;
> osg::Vec3 end;
>
> void setLine(osg::Vec3 s, osg::Vec3 e){
> start = s;
> end = e;
>
> for(int i = 1; i < samplePointNr; i++){
> double t = (double)i/samplePointNr;
> osg::Vec3 p(start.x() * (1-t) + end.x() * t, start.y() *
> (1-t) + end.y() * t, start.z() * (1-t) + end.z() * t);
> samplePoints.push_back(p);
> }
> }
>
> bool operator == (const LineData& line2) const{
>
> if
> ((!start.valid())||(!end.valid())||(!line2.start.valid())||(!line2.end.valid()))
> return false;
>
> return ((start.x() == line2.start.x()) &&
> (start.y() == line2.start.y()) &&
> (start.z() == line2.start.z()) &&
> (end.x() == line2.end.x()) &&
> (end.y() == line2.end.y()) &&
> (end.z() == line2.end.z()));
> }
>
> void printValues(){
> std::cout<<"start: "< "<
> }
>
> double getEuclideanDistance(osg::Vec3 s,osg::Vec3 e){
> double dist = sqrt( pow(s.x() - e.x(), 2) + pow(s.y() - e.y(), 2)
> + pow(s.z() - e.z(), 2) );
> return dist;
> }
>
> private:
> int samplePointNr;
> std::vectorsamplePoints;
>
>
> };
>
> std::vectorlines;
> osg::ref_ptr image = new osg::Image;
>
> //Determine lines in the model
> class GetLinesVisitor : public osg::NodeVisitor{
>
> public:
>
> GetLinesVisitor():
> osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN){
> numberOfLines = 0;
> numberOfLinesDeleted = 0;
> }
>
> std::vector getLi