[osg-submissions] small fix in examples/osgdepthpartition for gcc 4.3

Robert Osfield robert.osfield at gmail.com
Tue Apr 15 03:00:57 PDT 2008


Hi Tim,

Your submission came through inline, could you send it as a separate
attachment (gzipping it) or tweaking your mail tool will get round this
issue.

Robert.

On Tue, Apr 15, 2008 at 10:54 AM, Tim Moore <timoore at redhat.com> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hello,
> In order to compile with gcc 4.3 (as used in Fedora 9),
> examples/osgdepthpartition/DistanceAccumulator.cpp needs to have limits.h
> (or
> climits, if you prefer) explicitly included.
>
> Tim
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.7 (GNU/Linux)
> Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
>
> iD8DBQFIBHtteDhWHdXrDRURAuiqAJ4pF12+RUceXgGXOA5RJSKdCPQwtACgwSps
> 9uavaVp3xzOpNejbX+cjHaw=
> =XSLk
> -----END PGP SIGNATURE-----
>
> /* OpenSceneGraph example, osgdepthpartion.
> *
> *  Permission is hereby granted, free of charge, to any person obtaining a
> copy
> *  of this software and associated documentation files (the "Software"),
> to deal
> *  in the Software without restriction, including without limitation the
> rights
> *  to use, copy, modify, merge, publish, distribute, sublicense, and/or
> sell
> *  copies of the Software, and to permit persons to whom the Software is
> *  furnished to do so, subject to the following conditions:
> *
> *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> OR
> *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> THE
> *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> IN
> *  THE SOFTWARE.
> */
>
> #include "DistanceAccumulator.h"
> #include <osg/Geode>
> #include <osg/Transform>
> #include <osg/Projection>
> #include <algorithm>
> #include <math.h>
> #include <limits.h>
>
> /** Function that sees whether one DistancePair should come before another
> in
>    an sorted list. Used to sort the vector of DistancePairs. */
> bool precedes(const DistanceAccumulator::DistancePair &a,
>              const DistanceAccumulator::DistancePair &b)
> {
>    // This results in sorting in order of descending far distances
>    if(a.second > b.second) return true;
>    else return false;
> }
>
> /** Computes distance betwen a point and the viewpoint of a matrix */
> double distance(const osg::Vec3 &coord, const osg::Matrix& matrix)
> {
>    return -( coord[0]*matrix(0,2) + coord[1]*matrix(1,2) +
>              coord[2]*matrix(2,2) + matrix(3,2) );
> }
>
> #define CURRENT_CLASS DistanceAccumulator
> CURRENT_CLASS::CURRENT_CLASS()
>    : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
>      _nearFarRatio(0.0005), _maxDepth(UINT_MAX)
> {
>    setMatrices(osg::Matrix::identity(), osg::Matrix::identity());
>    reset();
> }
>
> CURRENT_CLASS::~CURRENT_CLASS() {}
>
> void CURRENT_CLASS::pushLocalFrustum()
> {
>    osg::Matrix& currMatrix = _viewMatrices.back();
>
>        // Compute the frustum in local space
>        osg::Polytope localFrustum;
>        localFrustum.setToUnitFrustum(false, false);
>
>  localFrustum.transformProvidingInverse(currMatrix*_projectionMatrices.back());
>        _localFrusta.push_back(localFrustum);
>
>        // Compute new bounding box corners
>        bbCornerPair corner;
>        corner.second = (currMatrix(0,2)<=0?1:0) |
>                        (currMatrix(1,2)<=0?2:0) |
>                        (currMatrix(2,2)<=0?4:0);
>        corner.first = (~corner.second)&7;
>        _bbCorners.push_back(corner);
> }
>
> void CURRENT_CLASS::pushDistancePair(double zNear, double zFar)
> {
>    if(zFar > 0.0) // Make sure some of drawable is visible
>    {
>      // Make sure near plane is in front of viewpoint.
>      if(zNear <= 0.0)
>      {
>        zNear = zFar*_nearFarRatio;
>        if(zNear >= 1.0) zNear = 1.0; // 1.0 limit chosen arbitrarily!
>      }
>
>      // Add distance pair for current drawable
>      _distancePairs.push_back(DistancePair(zNear, zFar));
>
>      // Override the current nearest/farthest planes if necessary
>      if(zNear < _limits.first) _limits.first = zNear;
>      if(zFar > _limits.second) _limits.second = zFar;
>    }
> }
>
> /** Return true if the node should be traversed, and false if the bounding
> sphere
>    of the node is small enough to be rendered by one Camera. If the latter
>    is true, then store the node's near & far plane distances. */
> bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node)
> {
>    // Allow traversal to continue if we haven't reached maximum depth.
>    bool keepTraversing = (_currentDepth < _maxDepth);
>
>    const osg::BoundingSphere &bs = node.getBound();
>    double zNear = 0.0, zFar = 0.0;
>
>    // Make sure bounding sphere is valid and within viewing volume
>    if(bs.valid())
>    {
>      if(!_localFrusta.back().contains(bs)) keepTraversing = false;
>      else
>      {
>        // Compute near and far planes for this node
>        zNear = distance(bs._center, _viewMatrices.back());
>        zFar = zNear + bs._radius;
>        zNear -= bs._radius;
>
>        // If near/far ratio is big enough, then we don't need to keep
>        // traversing children of this node.
>        if(zNear >= zFar*_nearFarRatio) keepTraversing = false;
>      }
>    }
>
>    // If traversal should stop, then store this node's (near,far) pair
>    if(!keepTraversing) pushDistancePair(zNear, zFar);
>
>    return keepTraversing;
> }
>
> void CURRENT_CLASS::apply(osg::Node &node)
> {
>    if(shouldContinueTraversal(node))
>    {
>      // Traverse this node
>      _currentDepth++;
>      traverse(node);
>      _currentDepth--;
>    }
> }
>
> void CURRENT_CLASS::apply(osg::Projection &proj)
> {
>    if(shouldContinueTraversal(proj))
>    {
>      // Push the new projection matrix view frustum
>      _projectionMatrices.push_back(proj.getMatrix());
>      pushLocalFrustum();
>
>      // Traverse the group
>      _currentDepth++;
>      traverse(proj);
>      _currentDepth--;
>
>      // Reload original matrix and frustum
>      _localFrusta.pop_back();
>      _bbCorners.pop_back();
>      _projectionMatrices.pop_back();
>    }
> }
>
> void CURRENT_CLASS::apply(osg::Transform &transform)
> {
>    if(shouldContinueTraversal(transform))
>    {
>      // Compute transform for current node
>      osg::Matrix currMatrix = _viewMatrices.back();
>      bool pushMatrix = transform.computeLocalToWorldMatrix(currMatrix,
> this);
>
>      if(pushMatrix)
>      {
>        // Store the new modelview matrix and view frustum
>        _viewMatrices.push_back(currMatrix);
>        pushLocalFrustum();
>      }
>
>      _currentDepth++;
>      traverse(transform);
>      _currentDepth--;
>
>      if(pushMatrix)
>      {
>        // Restore the old modelview matrix and view frustum
>        _localFrusta.pop_back();
>        _bbCorners.pop_back();
>        _viewMatrices.pop_back();
>      }
>    }
> }
>
> void CURRENT_CLASS::apply(osg::Geode &geode)
> {
>    // Contained drawables will only be individually considered if we are
>    // allowed to continue traversing.
>    if(shouldContinueTraversal(geode))
>    {
>      osg::Drawable *drawable;
>      double zNear, zFar;
>
>      // Handle each drawable in this geode
>      for(unsigned int i = 0; i < geode.getNumDrawables(); i++)
>      {
>        drawable = geode.getDrawable(i);
>
>        const osg::BoundingBox &bb = drawable->getBound();
>        if(bb.valid())
>        {
>          // Make sure drawable will be visible in the scene
>          if(!_localFrusta.back().contains(bb)) continue;
>
>          // Compute near/far distances for current drawable
>          zNear = distance(bb.corner(_bbCorners.back().first),
>                               _viewMatrices.back());
>          zFar = distance(bb.corner(_bbCorners.back().second),
>                          _viewMatrices.back());
>          if(zNear > zFar) std::swap(zNear, zFar);
>          pushDistancePair(zNear, zFar);
>        }
>      }
>    }
> }
>
> void CURRENT_CLASS::setMatrices(const osg::Matrix &modelview,
>                                const osg::Matrix &projection)
> {
>    _modelview = modelview;
>    _projection = projection;
> }
>
> void CURRENT_CLASS::reset()
> {
>    // Clear vectors & values
>    _distancePairs.clear();
>    _cameraPairs.clear();
>    _limits.first = DBL_MAX;
>    _limits.second = 0.0;
>    _currentDepth = 0;
>
>    // Initial transform matrix is the modelview matrix
>    _viewMatrices.clear();
>    _viewMatrices.push_back(_modelview);
>
>    // Set the initial projection matrix
>    _projectionMatrices.clear();
>    _projectionMatrices.push_back(_projection);
>
>    // Create a frustum without near/far planes, for cull computations
>    _localFrusta.clear();
>    _bbCorners.clear();
>    pushLocalFrustum();
> }
>
> void CURRENT_CLASS::computeCameraPairs()
> {
>    // Nothing in the scene, so no cameras needed
>    if(_distancePairs.empty()) return;
>
>    // Entire scene can be handled by just one camera
>    if(_limits.first >= _limits.second*_nearFarRatio)
>    {
>      _cameraPairs.push_back(_limits);
>      return;
>    }
>
>    PairList::iterator i,j;
>
>    // Sort the list of distance pairs by descending far distance
>    std::sort(_distancePairs.begin(), _distancePairs.end(), precedes);
>
>    // Combine overlapping distance pairs. The resulting set of distance
>    // pairs (called combined pairs) will not overlap.
>    PairList combinedPairs;
>    DistancePair currPair = _distancePairs.front();
>    for(i = _distancePairs.begin(); i != _distancePairs.end(); i++)
>    {
>      // Current distance pair does not overlap current combined pair, so
>      // save the current combined pair and start a new one.
>      if(i->second < 0.99*currPair.first)
>      {
>        combinedPairs.push_back(currPair);
>        currPair = *i;
>      }
>
>      // Current distance pair overlaps current combined pair, so expand
>      // current combined pair to encompass distance pair.
>      else
>        currPair.first = std::min(i->first, currPair.first);
>    }
>    combinedPairs.push_back(currPair); // Add last pair
>
>    // Compute the (near,far) distance pairs for each camera.
>    // Each of these distance pairs is called a "view segment".
>    double currNearLimit, numSegs, new_ratio;
>    double ratio_invlog = 1.0/log(_nearFarRatio);
>    unsigned int temp;
>    for(i = combinedPairs.begin(); i != combinedPairs.end(); i++)
>    {
>      currPair = *i; // Save current view segment
>
>      // Compute the fractional number of view segments needed to span
>      // the current combined distance pair.
>      currNearLimit = currPair.second*_nearFarRatio;
>      if(currPair.first >= currNearLimit) numSegs = 1.0;
>      else
>      {
>        numSegs = log(currPair.first/currPair.second)*ratio_invlog;
>
>        // Compute the near plane of the last view segment
>        //currNearLimit *= pow(_nearFarRatio, -floor(-numSegs) - 1);
>        for(temp = (unsigned int)(-floor(-numSegs)); temp > 1; temp--)
>        {
>          currNearLimit *= _nearFarRatio;
>        }
>      }
>
>      // See if the closest view segment can absorb other combined pairs
>      for(j = i+1; j != combinedPairs.end(); j++)
>      {
>        // No other distance pairs can be included
>        if(j->first < currNearLimit) break;
>      }
>
>      // If we did absorb another combined distance pair, recompute the
>      // number of required view segments.
>      if(i != j-1)
>      {
>        i = j-1;
>        currPair.first = i->first;
>        if(currPair.first >= currPair.second*_nearFarRatio) numSegs = 1.0;
>        else numSegs = log(currPair.first/currPair.second)*ratio_invlog;
>      }
>
>      /* Compute an integer number of segments by rounding the fractional
>         number of segments according to how many segments there are.
>         In general, the more segments there are, the more likely that the
>         integer number of segments will be rounded down.
>         The purpose of this is to try to minimize the number of view
> segments
>         that are used to render any section of the scene without violating
>         the specified _nearFarRatio by too much. */
>      if(numSegs < 10.0) numSegs = floor(numSegs + 1.0 -
> 0.1*floor(numSegs));
>      else numSegs = floor(numSegs);
>
>
>      // Compute the near/far ratio that will be used for each view segment
>      // in this section of the scene.
>      new_ratio = pow(currPair.first/currPair.second, 1.0/numSegs);
>
>      // Add numSegs new view segments to the camera pairs list
>      for(temp = (unsigned int)numSegs; temp > 0; temp--)
>      {
>        currPair.first = currPair.second*new_ratio;
>        _cameraPairs.push_back(currPair);
>        currPair.second = currPair.first;
>      }
>    }
> }
>
> void CURRENT_CLASS::setNearFarRatio(double ratio)
> {
>    if(ratio <= 0.0 || ratio >= 1.0) return;
>    _nearFarRatio = ratio;
> }
> #undef CURRENT_CLASS
>
>
> _______________________________________________
> osg-submissions mailing list
> osg-submissions at lists.openscenegraph.org
>
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.openscenegraph.org/pipermail/osg-submissions-openscenegraph.org/attachments/20080415/eb4c6d2d/attachment-0001.htm 


More information about the osg-submissions mailing list