Hi all.

Using OSG 3.0.1 under windows.

A problem that we have experienced now and then without understanding the
source of it, is that we get culling problems for scenes where objects are
rendered far from origo.


By default, OSG use float for representing bounding boxes, spheres etc.
I believe I comment on this quite a few years ago related to some other
project we were working on. So the support for double representation in
BV:s was added.

However, we still seem to have problems.

Assume you want to do some rendering using ECEF coordinates, where 0,0,0 is
at the center of the earth.
Then you might end up with values around 6371014 meters. This is obviously
not possible to represent in high enough precision for float.

What we have been doing to avoid the culling problems is to explicitly use
an inverse matrix which brings the coordinates used for rendering down to
origo and multiply all transforms with this matrix.

This give us problem, where in some specific camera views, some of the
rendered (long cylinders) are suddenly culled away, moving closer/away will
bring them back. I will try to reduce this to an OSG example...


What we would LIKE to do, is to have a MatrixTransform with this inverse
matrix. But this was not working before (with float BV:s), and even now
with the cmake settings below:


//Set to ON to build OpenSceneGraph with float BoundingBox instead
// of double.
OSG_USE_FLOAT_BOUNDINGBOX:BOOL=OFF

//Set to ON to build OpenSceneGraph with float BoundingSphere instead
// of double.
OSG_USE_FLOAT_BOUNDINGSPHERE:BOOL=OFF

//Set to ON to build OpenSceneGraph with float Matrix instead of
// double.
OSG_USE_FLOAT_MATRIX:BOOL=OFF

//Set to ON to build OpenSceneGraph with float Plane instead of
// double.
OSG_USE_FLOAT_PLANE:BOOL=OFF


We still see culling problems.
However, I have not been able to break it down to a simple example
demonstrating THIS problem.

But the example below sure show some problems where for some reason, the
coordinates are converted to float somewhere in the pipeline. Im using
Vec3D for representing the vertices, the inverse transform is in double
precision. Still, I get some weird rendering due to this.


Is there anyone else rendering objects far away from origo that have a
success-story to share?

#define X_VAL 6371014

#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/Vec3>
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include <osg/PolygonStipple>
#include <osg/TriangleFunctor>
#include <osg/io_utils>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <osg/Math>
#include <iostream>



osg::Node* createScene()
{
  // create the Geode (Geometry Node) to contain all our osg::Geometry
objects.
  osg::Geode* geode = new osg::Geode();


  // create LINES
  {
    // create Geometry object to store all the vertices and lines primitive.
    osg::Geometry* linesGeom = new osg::Geometry();

    // this time we'll preallocate the vertex array to the size we
    // need and then simple set them as array elements, 8 points
    // makes 4 line segments.
    osg::Vec3dArray* vertices = new osg::Vec3dArray(8);
    (*vertices)[0].set(X_VAL-1.13704, -2.15188e-09, 0.40373);
    (*vertices)[1].set(X_VAL-0.856897, -2.15188e-09, 0.531441);
    (*vertices)[2].set(X_VAL-0.889855, -2.15188e-09, 0.444927);
    (*vertices)[3].set(X_VAL-0.568518, -2.15188e-09, 0.40373);
    (*vertices)[4].set(X_VAL-1.00933, -2.15188e-09, 0.370773);
    (*vertices)[5].set(X_VAL-0.716827, -2.15188e-09, 0.292498);
    (*vertices)[6].set(X_VAL-1.07936, 9.18133e-09, 0.317217);
    (*vertices)[7].set(X_VAL-0.700348, 9.18133e-09, 0.362533);


    // pass the created vertex array to the points geometry object.
    linesGeom->setVertexArray(vertices);

    // set the colors as before, plus using the above
    osg::Vec4Array* colors = new osg::Vec4Array;
    colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
    linesGeom->setColorArray(colors);
    linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

    // set the normal in the same way color.
    osg::Vec3Array* normals = new osg::Vec3Array;
    normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
    linesGeom->setNormalArray(normals);
    linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    // This time we simply use primitive, and hardwire the number of coords
to use
    // since we know up front,
    linesGeom->addPrimitiveSet(new
osg::DrawArrays(osg::PrimitiveSet::LINES,0,8));


    // add the points geometry to the geode.
    geode->addDrawable(linesGeom);
  }

  return geode;
}

int main(int, char **)
{
  osg::Group *root = new osg::Group;

  osg::MatrixTransform *mt = new osg::MatrixTransform;
  osg::Matrix m;

  root->addChild(mt);

  m.setTrans(-X_VAL, 0,0 );
  mt->setMatrix( m );

  // create the model

  mt->addChild( createScene() );

  osgViewer::Viewer viewer;
  viewer.setUpViewInWindow( 0,0, 1280, 720);

  osgDB::writeNodeFile(*mt, "asd.osgx");

  // add model to viewer.
  viewer.setSceneData( root );

  return viewer.run();
}


Cheers,
Anders


-- 
__________________________________________
Anders Backman, HPC2N
90187 UmeƄ University, Sweden
[email protected] http://www.hpc2n.umu.se
Cell: +46-70-392 64 67
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to