bool CullVisitor::updateCalculatedNearFar(const osg::Matrix& matrix,const osg::BoundingBox& bb)
{
    // efficient computation of near and far, only taking into account the nearest and furthest
    // corners of the bounding box.
    value_type d_near = distance(bb.corner(_bbCornerNear),matrix);
    value_type d_far = distance(bb.corner(_bbCornerFar),matrix);

    if (d_near>d_far)
    {
        std::swap(d_near,d_far);
        if ( !EQUAL_F(d_near, d_far) ) 
        {
            OSG_WARN<<"Warning: CullVisitor::updateCalculatedNearFar(.) near>far in range calculation,"<< std::endl;
            OSG_WARN<<"         correcting by swapping values d_near="<<d_near<<" dfar="<<d_far<< std::endl;
        }
    }

    if (d_far<0.0)
    {
        // whole object behind the eye point so disguard
        return false;
    }

    if (d_near<_computed_znear) _computed_znear = d_near;
    if (d_far>_computed_zfar) _computed_zfar = d_far;

    return true;
}
Beispiel #2
0
void  TXPArchive::getExtents(osg::BoundingBox& extents)
{
    TileInfo sw, ne;
    trpg2iPoint tileExtents;

    this->GetHeader()->GetLodSize(0, tileExtents);
    this->getTileInfo(0, 0, 0, sw);
    this->getTileInfo(tileExtents.x-1, tileExtents.y-1, 0, ne);
    extents.set(sw.bbox._min, sw.bbox._max);
    extents.expandBy(ne.bbox);
}
Beispiel #3
0
osg::BoundingSphere
TileNode::computeBound() const
{
    osg::BoundingSphere bs;
    if (_surface.valid())
    {
        bs = _surface->getBound();
        const osg::BoundingBox bbox = _surface->getAlignedBoundingBox();
        _tileKeyValue.a() = std::max( (bbox.xMax()-bbox.xMin()), (bbox.yMax()-bbox.yMin()) );
    }    
    return bs;
}
Beispiel #4
0
double LispSM::calcNoptGeneral(const osg::Matrix lightSpace, const osg::BoundingBox &B_ls) const
{
    const osg::Matrix &eyeView      = getViewMatrix();
    const osg::Matrix invLightSpace = osg::Matrix::inverse(lightSpace);

    const osg::Vec3d z0_ls = getZ0_ls(lightSpace, _E, B_ls.zMax(), getEyeDir());
    const osg::Vec3d z1_ls = osg::Vec3d(z0_ls.x(), z0_ls.y(), B_ls.zMin());

    // to world
    const osg::Vec4d z0_ws = osg::Vec4d(z0_ls, 1) * invLightSpace;
    const osg::Vec4d z1_ws = osg::Vec4d(z1_ls, 1) * invLightSpace;

    // to eye
    const osg::Vec4d z0_cs = z0_ws * eyeView;
    const osg::Vec4d z1_cs = z1_ws * eyeView;

    double z0 = -z0_cs.z() / z0_cs.w();
    double z1 = -z1_cs.z() / z1_cs.w();

    if (z1 / z0 <= 1.0)
    {
        // solve camera pos singularity in light space problem brutally:
        // if extreme points of B projected to Light space extend beyond
        // camera frustum simply use B extents in camera frustum

        // Its not optimal selection but ceratainly better than negative N
        osg::BoundingBox bb = _hull.computeBoundingBox(eyeView);
        z0 = -bb.zMax();
        if (z0 <= 0)
            z0 = 0.1;

        z1 = -bb.zMin();
        if (z1 <= z0)
            z1 = z0 + 0.1;
    }

    const double d = osg::absolute(B_ls.zMax() - B_ls.zMin());

    double N = d / (sqrt(z1 / z0) - 1.0);
#if PRINT_COMPUTED_N_OPT
    std::cout
        << " N=" << std::setw(8) << N
        << " n=" << std::setw(8) << z0
        << " f=" << std::setw(8) << z1
        << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
        << std::flush;
#endif
    return N;
}
void ComputeAABBOnBoneVisitor::serializeBoundingBox(const osg::BoundingBox &bb,
                                                    const osg::Matrix &transform,
                                                    osgAnimation::Bone &b,
                                                    float ratio) {
    osg::Vec3 center = bb.center();
    double halfLenghtX = (bb._max.x() - bb._min.x()) * 0.50;
    double halfLenghtY = (bb._max.y() - bb._min.y()) * 0.50;
    double halfLenghtZ = (bb._max.z() - bb._min.z()) * 0.50;

    halfLenghtX *= ratio;
    halfLenghtY *= ratio;
    halfLenghtZ *= ratio;

    osg::BoundingBox serializedBB;

    serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() + halfLenghtY, center.z() + halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() + halfLenghtY, center.z() - halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() - halfLenghtY, center.z() - halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() - halfLenghtY, center.z() + halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() + halfLenghtY, center.z() + halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() + halfLenghtY, center.z() - halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() - halfLenghtY, center.z() - halfLenghtZ) * transform);
    serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() - halfLenghtY, center.z() + halfLenghtZ) * transform);

    b.setUserValue("AABBonBone_min", serializedBB._min);
    b.setUserValue("AABBonBone_max", serializedBB._max);
}
void ComputeBoundsVisitor::applyBoundingBox(const osg::BoundingBox& bbox)
{
    if (_matrixStack.empty()) _bb.expandBy(bbox);
    else if (bbox.valid())
    {
        const osg::Matrix& matrix = _matrixStack.back();
        _bb.expandBy(bbox.corner(0) * matrix);
        _bb.expandBy(bbox.corner(1) * matrix);
        _bb.expandBy(bbox.corner(2) * matrix);
        _bb.expandBy(bbox.corner(3) * matrix);
        _bb.expandBy(bbox.corner(4) * matrix);
        _bb.expandBy(bbox.corner(5) * matrix);
        _bb.expandBy(bbox.corner(6) * matrix);
        _bb.expandBy(bbox.corner(7) * matrix);
    }
}
Beispiel #7
0
osg::Vec3 Curve::mapTo( const osg::Vec3 p, osg::BoundingBox originRect, osg::BoundingBox newRect )
{
    osg::Vec3 newPos = p-originRect.center();

    osg::Vec3 originSpace = originRect._max-originRect._min;
    osg::Vec3 scaleFactor = (newRect._max-newRect._min);
    if ( originSpace.x() ) scaleFactor.x() /= originSpace.x();
    else scaleFactor.x() = 0.0;
    if ( originSpace.y() ) scaleFactor.y() /= originSpace.y();
    else scaleFactor.y() = 0.0;
    if ( originSpace.z() ) scaleFactor.z() /= originSpace.z();
    else scaleFactor.z() = 0.0;

    newPos = osg::Vec3(newPos.x()*scaleFactor.x(), newPos.y()*scaleFactor.y(), newPos.z()*scaleFactor.z());
    return newPos+newRect.center();
}
Beispiel #8
0
void Style::setupClipStateSet(const osg::BoundingBox& extents, osg::StateSet* stateset)
{
    unsigned int clipTextureUnit = 1;

    stateset->setAttributeAndModes( new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.0f), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

    stateset->setTextureAttributeAndModes( clipTextureUnit, _clipTexture.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

    osg::Matrixd matrix = osg::Matrixd::translate(osg::Vec3(-extents.xMin(), -extents.yMin(), -extents.zMin()))*
                          osg::Matrixd::scale(osg::Vec3(1.0f/(extents.xMax()-extents.xMin()), 1.0f/(extents.yMax()-extents.yMin()), 1.0f));

    osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
    texgen->setPlanesFromMatrix(matrix);
    texgen->setMode(osg::TexGen::OBJECT_LINEAR);
    stateset->setTextureAttributeAndModes( clipTextureUnit, texgen.get(), osg::StateAttribute::ON);
}
Beispiel #9
0
BboxDrawable::BboxDrawable( const osg::BoundingBox& box, const BBoxSymbol &bboxSymbol ) :
osg::Geometry()
{
    setUseVertexBufferObjects(true);

    float margin = bboxSymbol.margin().isSet() ? bboxSymbol.margin().value() : 2.f;
    osg::Vec3Array* v = new osg::Vec3Array();
    if ( bboxSymbol.geom().isSet() && bboxSymbol.geom().value() == BBoxSymbol::GEOM_BOX_ORIENTED )
    {
        float h = box.yMax() - box.yMin() + 2.f * margin;
        v->push_back( osg::Vec3(box.xMax()+margin+h/2.f, box.yMax()+margin-h/2.f, 0) );
    }
    v->push_back( osg::Vec3(box.xMax()+margin, box.yMax()+margin, 0) );
    v->push_back( osg::Vec3(box.xMin()-margin, box.yMax()+margin, 0) );
    v->push_back( osg::Vec3(box.xMin()-margin, box.yMin()-margin, 0) );
    v->push_back( osg::Vec3(box.xMax()+margin, box.yMin()-margin, 0) );
    setVertexArray(v);
    if ( v->getVertexBufferObject() )
        v->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);

    osg::Vec4Array* c = new osg::Vec4Array();
    if ( bboxSymbol.fill().isSet() )
    {
        c->push_back( bboxSymbol.fill()->color() );
        addPrimitiveSet( new osg::DrawArrays(GL_POLYGON, 0, v->getNumElements()) );
    }

    if ( bboxSymbol.border().isSet() )
    {
        c->push_back( bboxSymbol.border()->color() );
        if ( bboxSymbol.border()->width().isSet() )
            getOrCreateStateSet()->setAttribute( new osg::LineWidth( bboxSymbol.border()->width().value() ));
        addPrimitiveSet( new osg::DrawArrays(GL_LINE_LOOP, 0, v->getNumElements()) );
    }

    setColorArray( c );
    setColorBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );

    // add the static "isText=true" uniform; this is a hint for the annotation shaders
    // if they get installed.
    static osg::ref_ptr<osg::Uniform> s_isTextUniform = new osg::Uniform(osg::Uniform::BOOL, AnnotationUtils::UNIFORM_IS_TEXT());
    s_isTextUniform->set( false );
    getOrCreateStateSet()->addUniform( s_isTextUniform.get() );

    // Disable culling since this bounding box will eventually be drawn in screen space.
#if OSG_MIN_VERSION_REQUIRED(3,4,0)
    setCullingActive(false);
#endif
}
Beispiel #10
0
// this is the algorithm discussed in the article
osg::Matrix LispSM::getLispSmMtx(const osg::Matrix &lightSpace) const
{
    const osg::BoundingBox B_ls = _hull.computeBoundingBox(lightSpace);

    const double n = getN(lightSpace, B_ls);

    // get the coordinates of the near camera point in light space
    const osg::Vec3d e_ls = _E * lightSpace;
    // c start has the x and y coordinate of e, the z coord of B.min()
    const osg::Vec3d Cstart_lp(e_ls.x(), e_ls.y(), B_ls.zMax());

    if (n >= OSG_INFINITY)
    {
        // if n is inf. than we should do uniform shadow mapping
        return osg::Matrix::identity();
    }

    // calc C the projection center
    // new projection center C, n behind the near plane of P
    // we work along a negative axis so we transform +n*<the positive axis> == -n*<neg axis>
    const osg::Vec3d C(Cstart_lp + osg::Vec3d(0, 0, 1) * n);
    // construct a translation that moves to the projection center
    const osg::Matrix projectionCenter = osg::Matrix::translate(-C);

    // calc d the perspective transform depth or light space y extents
    const double d = osg::absolute(B_ls.zMax() - B_ls.zMin());

    // the lispsm perspective transformation

    // here done with a standard frustum call that maps P onto the unit cube with
    // corner points [-1,-1,-1] and [1,1,1].
    // in directX you can use the same mapping and do a mapping to the directX post-perspective cube
    // with corner points [-1,-1,0] and [1,1,1] as the final step after all the shadow mapping.
    osg::Matrix P = osg::Matrix::frustum(-1.0, 1.0, -1.0, 1.0, n, n + d);

    // invert the transform from right handed into left handed coordinate system for the ndc
    // done by the openGL style frustumGL call
    // so we stay in a right handed system
    P = P * osg::Matrix::scale(1.0, 1.0, -1.0);
    // return the lispsm frustum with the projection center
    return projectionCenter * P;
}
Beispiel #11
0
void
HorizonTileCuller::set(const osg::BoundingBox& bbox)
{
    // Adjust the horizon ellipsoid based on the minimum Z value of the tile;
    // necessary because a tile that's below the ellipsoid (ocean floor, e.g.)
    // may be visible even if it doesn't pass the horizon-cone test. In such
    // cases we need a more conservative ellipsoid.
    double zMin = bbox.corner(0).z();
    if ( zMin < 0.0 )
    {
        _horizonProto.setEllipsoid( osg::EllipsoidModel(_radiusEquator + zMin, _radiusPolar + zMin) );
    }

    // consider the uppermost 4 points of the tile-aligned bounding box.
    // (the last four corners of the bbox are the "zmax" corners.)
    for(unsigned i=0; i<4; ++i)
    {
        _points[i] = bbox.corner(4+i) * _local2world;
    }
}
void ComputeBoundingBoxByRotation(osg::BoundingBox & InOut,osg::Vec3 BBCenter,float BBSize,osg::Matrixd Rotation)
{
	osg::BoundingBox bb;
	bb.set(BBCenter.x()-BBSize,BBCenter.y()-BBSize,BBCenter.z()-BBSize,BBCenter.x()+BBSize,BBCenter.y()+BBSize,BBCenter.z()+BBSize);
    osg::BoundingBox Tbb;
	for(unsigned int i=0;i<8;i++)
    {
        Tbb.expandBy(Rotation.preMult(bb.corner(i)));
    }
	InOut.set(Tbb.xMin(),Tbb.yMin(),Tbb.zMin(),Tbb.xMax(),Tbb.yMax(),Tbb.zMax());
}
Beispiel #13
0
BboxDrawable::BboxDrawable( const osg::BoundingBox& box, const BBoxSymbol &bboxSymbol ) :
osg::Geometry()
{
    setUseVertexBufferObjects(true);

    float margin = bboxSymbol.margin().isSet() ? bboxSymbol.margin().value() : 2.f;
    osg::Vec3Array* v = new osg::Vec3Array();
    if ( bboxSymbol.geom().isSet() && bboxSymbol.geom().value() == BBoxSymbol::GEOM_BOX_ORIENTED )
    {
        float h = box.yMax() - box.yMin() + 2.f * margin;
        v->push_back( osg::Vec3(box.xMax()+margin+h/2.f, box.yMax()+margin-h/2.f, 0) );
    }
    v->push_back( osg::Vec3(box.xMax()+margin, box.yMax()+margin, 0) );
    v->push_back( osg::Vec3(box.xMin()-margin, box.yMax()+margin, 0) );
    v->push_back( osg::Vec3(box.xMin()-margin, box.yMin()-margin, 0) );
    v->push_back( osg::Vec3(box.xMax()+margin, box.yMin()-margin, 0) );
    setVertexArray(v);
    if ( v->getVertexBufferObject() )
        v->getVertexBufferObject()->setUsage(GL_STATIC_DRAW_ARB);

    osg::Vec4Array* c = new osg::Vec4Array(osg::Array::BIND_PER_PRIMITIVE_SET);
    if ( bboxSymbol.fill().isSet() )
    {
        c->push_back( bboxSymbol.fill()->color() );
        osg::DrawElements* de = new osg::DrawElementsUByte(GL_TRIANGLE_STRIP);
        de->addElement(0);
        de->addElement(1);
        de->addElement(3);
        de->addElement(2);
        addPrimitiveSet(de);
        //addPrimitiveSet( new osg::DrawArrays(GL_POLYGON, 0, v->getNumElements()) );
    }

    if ( bboxSymbol.border().isSet() )
    {
        c->push_back( bboxSymbol.border()->color() );
        if ( bboxSymbol.border()->width().isSet() )
            getOrCreateStateSet()->setAttribute( new osg::LineWidth( bboxSymbol.border()->width().value() ));
        addPrimitiveSet( new osg::DrawArrays(GL_LINE_LOOP, 0, v->getNumElements()) );
    }

    setColorArray( c );

    // Disable culling since this bounding box will eventually be drawn in screen space.
    setCullingActive(false);
}
Beispiel #14
0
void BuildKdTree::computeDivisions(KdTree::BuildOptions& options)
{
    osg::Vec3 dimensions(_bb.xMax()-_bb.xMin(),
                         _bb.yMax()-_bb.yMin(),
                         _bb.zMax()-_bb.zMin());

#ifdef VERBOSE_OUTPUT
    OSG_NOTICE<<"computeDivisions("<<options._maxNumLevels<<") "<<dimensions<< " { "<<std::endl;
#endif

    _axisStack.reserve(options._maxNumLevels);

    for(unsigned int level=0; level<options._maxNumLevels; ++level)
    {
        int axis = 0;
        if (dimensions[0]>=dimensions[1])
        {
            if (dimensions[0]>=dimensions[2]) axis = 0;
            else axis = 2;
        }
        else if (dimensions[1]>=dimensions[2]) axis = 1;
        else axis = 2;

        _axisStack.push_back(axis);
        dimensions[axis] /= 2.0f;

#ifdef VERBOSE_OUTPUT
        OSG_NOTICE<<"  "<<level<<", "<<dimensions<<", "<<axis<<std::endl;
#endif
    }

#ifdef VERBOSE_OUTPUT
    OSG_NOTICE<<"}"<<std::endl;
#endif
}
Beispiel #15
0
    void apply(osg::Node &node)
    {
        osg::Transform *mt;
        osg::Geode *geo;

        osg::ref_ptr<osg::RefMatrix> M = matStack.back();
        if ((geo = dynamic_cast<osg::Geode *>(&node)))
        {
            unsigned int i;
            osg::BoundingBox bb;
            for (i = 0; i < geo->getNumDrawables(); i++)
            {
                bb.expandBy(geo->getDrawable(i)->getBound());
            }
            if (M.get())
            {
                bbox.expandBy(osg::Vec3(bb.xMin(), bb.yMin(), bb.zMin()) * *M);
                bbox.expandBy(osg::Vec3(bb.xMax(), bb.yMax(), bb.zMax()) * *M);
            }
            else
            {
                bbox.expandBy(osg::Vec3(bb.xMin(), bb.yMin(), bb.zMin()));
                bbox.expandBy(osg::Vec3(bb.xMax(), bb.yMax(), bb.zMax()));
            }
        }
        if ((mt = dynamic_cast<osg::Transform *>(&node)))
        {
            osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix;
            mt->computeLocalToWorldMatrix(*matrix, this);
            matStack.push_back(matrix);
        }
        traverse(node);
        if ((mt = dynamic_cast<osg::Transform *>(&node)))
        {
            matStack.pop_back();
        }
    }
Beispiel #16
0
void
HorizonTileCuller::set(const SpatialReference* srs, 
                       const osg::Matrix&      local2world,
                       const osg::BoundingBox& bbox)
{
    if (!_horizon.valid() && srs->isGeographic())
    {
        _horizon = new Horizon();
    }

    if (_horizon.valid())
    {
        _horizon->setEllipsoid(*srs->getEllipsoid());
        //_radiusPolar = srs->getEllipsoid()->getRadiusPolar();
        //_radiusEquator = srs->getEllipsoid()->getRadiusEquator();
        //_local2world = local2world;

        // Adjust the horizon ellipsoid based on the minimum Z value of the tile;
        // necessary because a tile that's below the ellipsoid (ocean floor, e.g.)
        // may be visible even if it doesn't pass the horizon-cone test. In such
        // cases we need a more conservative ellipsoid.
        double zMin = (double)std::min( bbox.corner(0).z(), 0.0f );
        zMin = std::max(zMin, -25000.0); // approx the lowest point on earth * 2
        _horizon->setEllipsoid( osg::EllipsoidModel(
            srs->getEllipsoid()->getRadiusEquator() + zMin, 
            srs->getEllipsoid()->getRadiusPolar() + zMin) );

        // consider the uppermost 4 points of the tile-aligned bounding box.
        // (the last four corners of the bbox are the "zmax" corners.)
        for(unsigned i=0; i<4; ++i)
        {
            _points[i] = bbox.corner(4+i) * local2world;
        }

        //_bs.set(bbox.center() * _local2world, bbox.radius());
    }
}
Beispiel #17
0
bool DebugShadowMap::ViewData::DebugBoundingBox
    ( const osg::BoundingBox & bb, const char * name )
{
    bool result = false;
#if defined( _DEBUG    ) || defined( DEBUG )
    if( !name ) name = "";

    osg::BoundingBox & bb_prev = _boundingBoxMap[ std::string( name ) ];

    result = bb.center() != bb_prev.center() || bb.radius() != bb_prev.radius();
    if( result )
        std::cout << "Box<" << name << "> ("
                  << ( bb._max._v[0] + bb._min._v[0] ) * 0.5 << " "
                  << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " "
                  << ( bb._max._v[2] + bb._min._v[2] ) * 0.5 << ") ["
                  << ( bb._max._v[0] - bb._min._v[0] ) << " "
                  << ( bb._max._v[1] - bb._min._v[1] ) << " "
                  << ( bb._max._v[2] - bb._min._v[2] ) << "] "
                  << std::endl;

    bb_prev = bb;
#endif
    return result;
}
Beispiel #18
0
bool GetBoundingBox(osg::BoundingBox & BB, dtCore::DeltaDrawable & drawable)
{
    osg::Node* node = drawable.GetOSGNode();
    if (node != 0)
    {
        dtUtil::BoundingBoxVisitor bbv;
		node->accept(bbv);

		// no copy constructor for osg::BB...
		BB.set(bbv.mBoundingBox._min, bbv.mBoundingBox._max);
		return true;
    }

    LOG_WARNING("No valid osg node of drawable when asking for bounding box.");
    return false;
}
Beispiel #19
0
inline bool CheckAndMultiplyBoxIfWithinPolytope
    ( osg::BoundingBox & bb, osg::Matrix & m, osg::Polytope &p )
{
    if( !bb.valid() ) return false;

    osg::Vec3 o = bb._min * m, s[3];

    for( int i = 0; i < 3; i ++ )
        s[i] = osg::Vec3( m(i,0), m(i,1), m(i,2) ) * ( bb._max[i] - bb._min[i] );

    for( osg::Polytope::PlaneList::iterator it = p.getPlaneList().begin();
         it != p.getPlaneList().end();
         ++it )
    {
        float dist = it->distance( o ), dist_min = dist, dist_max = dist;

        for( int i = 0; i < 3; i ++ ) {
            dist = it->dotProductNormal( s[i] );
            if( dist < 0 ) dist_min += dist; else dist_max += dist;
        }

        if( dist_max < 0 )
            return false;
    }

    bb._max = bb._min = o;
#if 1
    for( int i = 0; i < 3; i ++ )
        for( int j = 0; j < 3; j ++ )
            if( s[i][j] < 0 ) bb._min[j] += s[i][j]; else bb._max[j] += s[i][j];
#else
    b.expandBy( o + s[0] );
    b.expandBy( o + s[1] );
    b.expandBy( o + s[2] );
    b.expandBy( o + s[0] + s[1] );
    b.expandBy( o + s[0] + s[2] );
    b.expandBy( o + s[1] + s[2] );
    b.expandBy( o + s[0] + s[1] + s[2] );
#endif

#if ( IGNORE_OBJECTS_LARGER_THAN_HEIGHT > 0 )
   if( bb._max[2] - bb._min[2] > IGNORE_OBJECTS_LARGER_THAN_HEIGHT ) // ignore huge objects
       return false;
#endif

    return true;
}
void MinimalShadowMap::ViewData::cutScenePolytope
    ( const osg::Matrix & transform, 
      const osg::Matrix & inverse, 
      const osg::BoundingBox & bb )
{   
    _sceneReceivingShadowPolytopePoints.clear();

    if( bb.valid() ) {
        osg::Polytope polytope;
        polytope.setToBoundingBox( bb );
        polytope.transformProvidingInverse( inverse );
        _sceneReceivingShadowPolytope.cut( polytope );        
        _sceneReceivingShadowPolytope.getPoints
                                ( _sceneReceivingShadowPolytopePoints );
    } else
        _sceneReceivingShadowPolytope.clear();
}
Beispiel #21
0
CSulGeomBox::CSulGeomBox( const osg::BoundingBox& bb ) :
CSulGeode()
{
	m_minX = bb.xMin();
	m_maxX = bb.xMax();
	m_minY = bb.yMin();
	m_maxY = bb.yMax();
	m_minZ = bb.zMin();
	m_maxZ = bb.zMax();

	createDrawable();
}
bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
{
    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::MOVE):
        case(osgGA::GUIEventAdapter::PUSH):
        case(osgGA::GUIEventAdapter::DRAG):
        case(osgGA::GUIEventAdapter::RELEASE):
        {
            if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
            {
                _drawablesOnPush.clear();
            }
            osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
            osgUtil::LineSegmentIntersector::Intersections intersections;
            if (viewer->computeIntersections(ea, nv->getNodePath(), intersections))
            {
                for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();
                    hitr!=intersections.end();
                    ++hitr)
                {
                    if (_operation == FORWARD_MOUSE_EVENT)
                    {
                        osg::ref_ptr<osgGA::GUIEventAdapter> cloned_ea = osg::clone(&ea);

                        // clear touch-data as this prevents sending the event as mouse-event
                        cloned_ea->setTouchData(NULL);

                        // reproject mouse-coord
                        const osg::BoundingBox bb(hitr->drawable->getBound());
                        const osg::Vec3& p(hitr->localIntersectionPoint);

                        float transformed_x = (p.x() - bb.xMin()) / (bb.xMax() - bb.xMin());
                        float transformed_y = (p.z() - bb.zMin()) / (bb.zMax() - bb.zMin());

                        cloned_ea->setX(ea.getXmin() + transformed_x * (ea.getXmax() - ea.getXmin()));
                        cloned_ea->setY(ea.getYmin() + transformed_y * (ea.getYmax() - ea.getYmin()));
                        cloned_ea->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);



                        // std::cout << transformed_x << "/" << transformed_x << " -> " << cloned_ea->getX() << "/" <<cloned_ea->getY() << std::endl;

                        SlideEventHandler::instance()->forwardEventToDevices(cloned_ea.get());
                    }
                    else if ((_operation == FORWARD_TOUCH_EVENT) && ea.isMultiTouchEvent())
                    {
                        osg::ref_ptr<osgGA::GUIEventAdapter> cloned_ea = osg::clone(&ea);
                        cloned_ea->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS);

                        osgGA::GUIEventAdapter::TouchData* touch_data = cloned_ea->getTouchData();



                        // reproject touch-points
                        const osg::BoundingBox bb(hitr->drawable->getBound());

                        osg::Camera* camera = viewer->getCamera();
                        osg::Matrix matrix = osg::computeLocalToWorld(hitr->nodePath, false) * camera->getViewMatrix() * camera->getProjectionMatrix();
                        matrix.postMult(camera->getViewport()->computeWindowMatrix());

                        osg::Matrixd inverse;
                        inverse.invert(matrix);

                        // transform touch-points into local coord-system
                        unsigned int j(0);
                        for(osgGA::GUIEventAdapter::TouchData::iterator i = touch_data->begin(); i != touch_data->end(); ++i, ++j)
                        {
                            osg::Vec3 local = osg::Vec3(i->x, i->y, 0) * inverse;

                            // std::cout << local << " hit: " << hitr->localIntersectionPoint << std::endl;

                            local.x() = (local.x() - bb.xMin()) / (bb.xMax() - bb.xMin());
                            local.z() = (local.z() - bb.zMin()) / (bb.zMax() - bb.zMin());

                            local.x() = (ea.getXmin() + local.x() * (ea.getXmax() - ea.getXmin()));
                            local.z() = (ea.getYmin() + local.z() * (ea.getYmax() - ea.getYmin()));

                            // std::cout << ea.getX() << "/" << ea.getY() << " -- " << i->x << " " << i->y << " -> " << local.x() <<"/" << local.z() << std::endl;

                            i->x = local.x();
                            i->y = 1 + local.z(); // no idea why I have to add 1 to get y in the range [0..1]
                        }


                        // std::cout << transformed_x << "/" << transformed_x << " -> " << cloned_ea->getX() << "/" <<cloned_ea->getY() << std::endl;


                        SlideEventHandler::instance()->forwardEventToDevices(cloned_ea.get());
                    }
                    else
                    {
                        if (ea.getEventType()==osgGA::GUIEventAdapter::PUSH)
                        {
                            _drawablesOnPush.insert( hitr->drawable.get() );
                        }
                        else if (ea.getEventType()==osgGA::GUIEventAdapter::MOVE)
                        {
                            OSG_INFO<<"Tooltip..."<<std::endl;
                        }
                        else if (ea.getEventType()==osgGA::GUIEventAdapter::RELEASE)
                        {
                            if (_drawablesOnPush.find(hitr->drawable.get()) != _drawablesOnPush.end())
                                doOperation();
                            return true;
                        }
                    }
                }
            }
            break;
        }
        case(osgGA::GUIEventAdapter::KEYDOWN):
        {
            //OSG_NOTICE<<"PickEventHandler KEYDOWN "<<(char)ea.getKey()<<std::endl;
            //if (object) OSG_NOTICE<<"    "<<object->className()<<std::endl;
            break;
        }
        default:
            break;
    }
    return false;
}
        inline void init_towbar()
        {
            body_s_ = findFirstNode((tow_visual_object_)->root(),"body_s");
            body_b_ = findFirstNode((tow_visual_object_)->root(),"body_b");
            body_a_ = findFirstNode((tow_visual_object_)->root(),"body_a");

            osg::ComputeBoundsVisitor cbvs;
            body_s_->accept( cbvs );
            const osg::BoundingBox bb_s = cbvs.getBoundingBox();

            osg::ComputeBoundsVisitor cbvb;
            body_b_->accept( cbvb );
            const osg::BoundingBox bb_b = cbvb.getBoundingBox();

            osg::ComputeBoundsVisitor cbva;
            body_a_->accept( cbva );
            const osg::BoundingBox bb_a = cbva.getBoundingBox();

            osg::ComputeBoundsVisitor cbv;
            (tow_visual_object_)->root()->accept( cbv );
            const osg::BoundingBox bb_ = cbv.getBoundingBox();

            radius_   = abs(bb_.yMax() - bb_.yMin())/2.0;//(*tow_visual_object_)->root()->getBound().radius();

            radius_s_ = abs(bb_s.yMax() - bb_s.yMin())/2.0;//body_s_->getBound().radius();
            radius_a_ = abs(bb_a.yMax() - bb_a.yMin())/2.0;//body_a_->getBound().radius(); 
            radius_b_ = abs(bb_b.yMax() - bb_b.yMin())/2.0;//body_b_->getBound().radius();
        }
Beispiel #24
0
bool PickEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
{
    if (ea.getHandled()) return false;

    switch(ea.getEventType())
    {
        case(osgGA::GUIEventAdapter::MOVE):
        case(osgGA::GUIEventAdapter::PUSH):
        case(osgGA::GUIEventAdapter::DRAG):
        case(osgGA::GUIEventAdapter::RELEASE):
        {
            if(ea.getEventType() == osgGA::GUIEventAdapter::PUSH)
            {
                _drawablesOnPush.clear();
            }
            osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
            osgUtil::LineSegmentIntersector::Intersections intersections;
            if (viewer->computeIntersections(ea, nv->getNodePath(), intersections))
            {
                for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();
                    hitr!=intersections.end();
                    ++hitr)
                {
                    if (_operation == FORWARD_EVENT)
                    {
                        osg::ref_ptr<osgGA::GUIEventAdapter> cloned_ea = osg::clone(&ea);
                        const osg::BoundingBox bb(hitr->drawable->getBound());
                        const osg::Vec3& p(hitr->localIntersectionPoint);
                        
                        float transformed_x = (p.x() - bb.xMin()) / (bb.xMax() - bb.xMin());
                        float transformed_y = (p.z() - bb.zMin()) / (bb.zMax() - bb.zMin());
                        
                        cloned_ea->setX(ea.getXmin() + transformed_x * (ea.getXmax() - ea.getXmin()));
                        cloned_ea->setY(ea.getYmin() + transformed_y * (ea.getYmax() - ea.getYmin()));
                        cloned_ea->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
                        
                        // std::cout << transformed_x << "/" << transformed_x << " -> " << cloned_ea->getX() << "/" <<cloned_ea->getY() << std::endl;
                        
                        
                        // dispatch cloned event to devices
                        osgViewer::View::Devices& devices = viewer->getDevices();
                        for(osgViewer::View::Devices::iterator i = devices.begin(); i != devices.end(); ++i)
                        {
                            if((*i)->getCapabilities() & osgGA::Device::SEND_EVENTS)
                            {
                                (*i)->sendEvent(*cloned_ea);
                            }
                        }
                    }
                    else 
                    {
                        if (ea.getEventType()==osgGA::GUIEventAdapter::PUSH)
                        {
                            _drawablesOnPush.insert( hitr->drawable.get() );
                        }
                        else if (ea.getEventType()==osgGA::GUIEventAdapter::MOVE)
                        {
                            OSG_INFO<<"Tooltip..."<<std::endl;
                        }
                        else if (ea.getEventType()==osgGA::GUIEventAdapter::RELEASE)
                        {
                            if (_drawablesOnPush.find(hitr->drawable.get()) != _drawablesOnPush.end())
                                doOperation();
                            return true;
                        }
                    }
                }
            }
            break;
        }
        case(osgGA::GUIEventAdapter::KEYDOWN):
        {
            //OSG_NOTICE<<"PickEventHandler KEYDOWN "<<(char)ea.getKey()<<std::endl;
            //if (object) OSG_NOTICE<<"    "<<object->className()<<std::endl;
            break;
        }
        default:
            break;
    }
    return false;
}
Beispiel #25
0
void MxCore::lookAtAndFit( const osg::BoundingBox& bb )
{
    // We'll get the view matrix to project the bounding box, so pre-configure it
    // to point at the box center. Eye position doesn't matter at this point (we
    // compute the eye position at the end of the function).
    osg::Vec3d newDir = bb.center() - _position;
    newDir.normalize();
    setDir( newDir );


    // Ttransform the bounding box vertices into eye space,
    // then determine their x and y extents. We'll compare the eye
    // space bb aspect ratio against the projection _aspect to
    // determine the critical axis to fit.

    osg::ref_ptr< osg::Vec3Array > corners = new osg::Vec3Array;
    corners->resize( 8 );
    ( *corners )[ 0 ].set( bb._min );
    ( *corners )[ 1 ].set( bb._max.x(), bb._min.y(), bb._min.z() );
    ( *corners )[ 2 ].set( bb._max.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 3 ].set( bb._min.x(), bb._min.y(), bb._max.z() );
    ( *corners )[ 4 ].set( bb._max );
    ( *corners )[ 5 ].set( bb._min.x(), bb._max.y(), bb._max.z() );
    ( *corners )[ 6 ].set( bb._min.x(), bb._max.y(), bb._min.z() );
    ( *corners )[ 7 ].set( bb._max.x(), bb._max.y(), bb._min.z() );

    osgwTools::transform( getInverseMatrix(), corners.get() );
    // The 'corners' array of bb verts are now in eye space.

    // Determine max and min values for eye space x and y
    osg::Vec2 minEC( FLT_MAX, FLT_MAX ), maxEC( FLT_MIN, FLT_MIN );
    unsigned int idx;
    for( idx=0; idx<8; idx++ )
    {
        const osg::Vec3& v( ( *corners )[ idx ] );
        minEC[ 0 ] = osg::minimum< float >( v.x(), minEC[ 0 ] );
        minEC[ 1 ] = osg::minimum< float >( v.y(), minEC[ 1 ] );
        maxEC[ 0 ] = osg::maximum< float >( v.x(), maxEC[ 0 ] );
        maxEC[ 1 ] = osg::maximum< float >( v.y(), maxEC[ 1 ] );
    }
    // aspect is width (x) over height (y).
    const double ecWidth( maxEC[ 0 ] - minEC[ 0 ] );
    const double ecHeight( maxEC[ 1 ] - minEC[ 1 ] );
    const double ecAspect = ecWidth / ecHeight;


    // We'll store half the extent of interest into a dummy bounding sphere's radius.
    // We'll store the analogous fov in bestFov.
    osg::BoundingSphere bs;
    double bestFov;
    if( ecAspect > _aspect )
    {
        // Fit eye space x to the view
        bs.radius() = ecWidth * .5;
        bestFov = _aspect * _fovy;
    }
    else
    {
        // Fit eye space y to the view
        bs.radius() = ecHeight * .5;
        bestFov = _fovy;
    }

    // The wrap-up code sets the eye position at the best distance from
    // the bb center. Extra distance is added in to account for the fact
    // that the input bound probably has a larger radius than the eye coord
    // bound that we're passing to computeInitialDistanceFromFOVY().
    const double extraDistance = bb.radius() - bs.radius();
    const double distance = extraDistance +
        osgwMx::computeInitialDistanceFromFOVY( bs, bestFov );
    setPosition( bs.center() - ( newDir * distance ) );
}
Beispiel #26
0
void
WriterCompareTriangle::cutscene(int                     nbVertices,
                                const osg::BoundingBox& sceneBox)
{
    osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min;

    static const unsigned int k = 4;

    unsigned int nbVerticesX = (nbVertices * k) / (length.z() * length.y());
    unsigned int nbVerticesY = (nbVertices * k) / (length.z() * length.x());
    unsigned int nbVerticesZ = (nbVertices * k) / (length.x() * length.y());

    setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ);

    OSG_DEBUG << "Cutting x by " << nbVerticesX << std::endl
        << "Cutting y by " << nbVerticesY << std::endl
        << "Cutting z by " << nbVerticesZ << std::endl;

    osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; //These 3 lines set the size of a box in x, y and z
    osg::BoundingBox::value_type blocY = length.y() / nbVerticesY;
    osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ;

    boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ);
    short yinc = 1;
    short xinc = 1;
    unsigned int y = 0;
    unsigned int x = 0;
    for (unsigned int z = 0; z < nbVerticesZ; ++z)
    {
        while (x < nbVerticesX && x >= 0)
        {
            while (y < nbVerticesY && y >= 0)
            {
                osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX;
                if (x == 0) //to prevent from mesh with no case
                    xMin -= 10;

                osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY;
                if (y == 0) //to prevent from mesh with no case
                    yMin -= 10;

                osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ;
                if (z == 0) //to prevent from mesh with no case
                    zMin -= 10;

                osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX;
                if (x == nbVerticesX - 1) //to prevent from mesh with no case
                    xMax += 10;

                osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY;
                if (y == nbVerticesY - 1) //to prevent from mesh with no case
                    yMax += 10;

                osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ;
                if (z == nbVerticesZ - 1) //to prevent from mesh with no case
                    zMax += 10;

                boxList.push_back(osg::BoundingBox(xMin, // Add a box to the list
                    yMin,
                    zMin,
                    xMax, 
                    yMax,
                    zMax));
                y += yinc;
            }
            yinc = -yinc;
            y += yinc;
            x += xinc;
        }
        xinc = -xinc;
        x += xinc;
    }
}
Beispiel #27
0
bool IntersectKdTree::intersectAndClip(osg::Vec3& s, osg::Vec3& e, const osg::BoundingBox& bb) const
{
    //return true;

    //if (!bb.valid()) return true;

    // compate s and e against the xMin to xMax range of bb.
    if (s.x()<=e.x())
    {

        // trivial reject of segment wholely outside.
        if (e.x()<bb.xMin()) return false;
        if (s.x()>bb.xMax()) return false;

        if (s.x()<bb.xMin())
        {
            // clip s to xMin.
            s = s+_d_invX*(bb.xMin()-s.x());
        }

        if (e.x()>bb.xMax())
        {
            // clip e to xMax.
            e = s+_d_invX*(bb.xMax()-s.x());
        }
    }
    else
    {
        if (s.x()<bb.xMin()) return false;
        if (e.x()>bb.xMax()) return false;

        if (e.x()<bb.xMin())
        {
            // clip s to xMin.
            e = s+_d_invX*(bb.xMin()-s.x());
        }

        if (s.x()>bb.xMax())
        {
            // clip e to xMax.
            s = s+_d_invX*(bb.xMax()-s.x());
        }
    }

    // compate s and e against the yMin to yMax range of bb.
    if (s.y()<=e.y())
    {

        // trivial reject of segment wholely outside.
        if (e.y()<bb.yMin()) return false;
        if (s.y()>bb.yMax()) return false;

        if (s.y()<bb.yMin())
        {
            // clip s to yMin.
            s = s+_d_invY*(bb.yMin()-s.y());
        }

        if (e.y()>bb.yMax())
        {
            // clip e to yMax.
            e = s+_d_invY*(bb.yMax()-s.y());
        }
    }
    else
    {
        if (s.y()<bb.yMin()) return false;
        if (e.y()>bb.yMax()) return false;

        if (e.y()<bb.yMin())
        {
            // clip s to yMin.
            e = s+_d_invY*(bb.yMin()-s.y());
        }

        if (s.y()>bb.yMax())
        {
            // clip e to yMax.
            s = s+_d_invY*(bb.yMax()-s.y());
        }
    }

    // compate s and e against the zMin to zMax range of bb.
    if (s.z()<=e.z())
    {

        // trivial reject of segment wholely outside.
        if (e.z()<bb.zMin()) return false;
        if (s.z()>bb.zMax()) return false;

        if (s.z()<bb.zMin())
        {
            // clip s to zMin.
            s = s+_d_invZ*(bb.zMin()-s.z());
        }

        if (e.z()>bb.zMax())
        {
            // clip e to zMax.
            e = s+_d_invZ*(bb.zMax()-s.z());
        }
    }
    else
    {
        if (s.z()<bb.zMin()) return false;
        if (e.z()>bb.zMax()) return false;

        if (e.z()<bb.zMin())
        {
            // clip s to zMin.
            e = s+_d_invZ*(bb.zMin()-s.z());
        }

        if (s.z()>bb.zMax())
        {
            // clip e to zMax.
            s = s+_d_invZ*(bb.zMax()-s.z());
        }
    }

    // OSG_NOTICE<<"clampped segment "<<s<<" "<<e<<std::endl;

    // if (s==e) return false;

    return true;
}
Beispiel #28
0
void WriterCompareTriangle::cutscene(int nbVertices, const osg::BoundingBox & sceneBox)
{
    osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min;

    static const float k = 1.3f;        // Arbitrary constant multiplier for density computation ("simulates" non-uniform point distributions)
    // Computes "density" of points, and thus the number of blocks to divide the mesh into
    int nbVerticesX = static_cast<int>( (nbVertices * k) / (length.z() * length.y()) );
    int nbVerticesY = static_cast<int>( (nbVertices * k) / (length.z() * length.x()) );
    int nbVerticesZ = static_cast<int>( (nbVertices * k) / (length.x() * length.y()) );

    setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cutting the scene in too many blocs

    OSG_INFO
        << "Cutting x by " << nbVerticesX << std::endl
        << "Cutting y by " << nbVerticesY << std::endl
        << "Cutting z by " << nbVerticesZ << std::endl;

    osg::BoundingBox::value_type blocX = length.x() / nbVerticesX;    // These 3 lines set the size of a bloc in x, y and z
    osg::BoundingBox::value_type blocY = length.y() / nbVerticesY;
    osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ;

    boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ);
    short yinc = 1;
    short xinc = 1;
    int y = 0;
    int x = 0;
    for (int z = 0; z < nbVerticesZ; ++z)
    {
        while (x < nbVerticesX && x >= 0)
        {
            while (y < nbVerticesY && y >= 0)
            {
                osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX;
                if (x == 0) //to prevent from mesh with no case
                    xMin -= 10;

                osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY;
                if (y == 0) //to prevent from mesh with no case
                    yMin -= 10;

                osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ;
                if (z == 0) //to prevent from mesh with no case
                    zMin -= 10;

                osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX;
                if (x == nbVerticesX - 1) //to prevent from mesh with no case
                    xMax += 10;

                osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY;
                if (y == nbVerticesY - 1) //to prevent from mesh with no case
                    yMax += 10;

                osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ;
                if (z == nbVerticesZ - 1) //to prevent from mesh with no case
                    zMax += 10;

                boxList.push_back(osg::BoundingBox(xMin, // Add a bloc to the list
                    yMin,
                    zMin,
                    xMax,
                    yMax,
                    zMax));
                y += yinc;
            }
            yinc = -yinc;
            y += yinc;
            x += xinc;
        }
        xinc = -xinc;
        x += xinc;
    }
}
void MinimalShadowMap::ViewData::trimProjection
    ( osg::Matrixd & projectionMatrix, osg::BoundingBox bb, unsigned int trimMask )
{
#if 1
    if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return;
    double l = -1, r = 1, b = -1, t = 1, n = 1, f = -1;

#if 0
    // make sure bounding box does not extend beyond unit frustum clip range
    for( int i = 0; i < 3; i ++ ) {
        if( bb._min[i] < -1 ) bb._min[i] = -1;
        if( bb._max[i] >  1 ) bb._max[i] =  1;
    }
#endif

    if( trimMask & 1 ) l = bb._min[0];
    if( trimMask & 2 ) r = bb._max[0];
    if( trimMask & 4 ) b = bb._min[1];
    if( trimMask & 8 ) t = bb._max[1];
    if( trimMask & 16 ) n = -bb._min[2];
    if( trimMask & 32 ) f = -bb._max[2];

    projectionMatrix.postMult( osg::Matrix::ortho( l,r,b,t,n,f ) );
#else
    if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return;
    double l, r, t, b, n, f;
    bool ortho = projectionMatrix.getOrtho( l, r, b, t, n, f ); 
    if( !ortho && !projectionMatrix.getFrustum( l, r, b, t, n, f ) )
        return; // rotated or skewed or other crooked projection - give up

    // make sure bounding box does not extend beyond unit frustum clip range
    for( int i = 0; i < 3; i ++ ) {
        if( bb._min[i] < -1 ) bb._min[i] = -1;
        if( bb._max[i] >  1 ) bb._max[i] =  1;
    }

    osg::Matrix projectionToView = osg::Matrix::inverse( projectionMatrix );
    
    osg::Vec3 min =
        osg::Vec3( bb._min[0], bb._min[1], bb._min[2] ) * projectionToView;

    osg::Vec3 max =
        osg::Vec3( bb._max[0], bb._max[1], bb._max[2] ) * projectionToView;

    if( trimMask & 16 ) { // trim near
        if( !ortho ) { // recalc frustum corners on new near plane
            l *= -min[2] / n;
            r *= -min[2] / n;
            b *= -min[2] / n;
            t *= -min[2] / n;
        }
        n = -min[2];
    }

    if( trimMask & 32 ) // trim far
        f = -max[2];

    if( !ortho ) {
        min[0] *=  -n / min[2];
        min[1] *=  -n / min[2];
        max[0] *=  -n / max[2];
        max[1] *=  -n / max[2];
    }

    if( l < r ) { // check for inverted X range
        if( l < min[0] && ( trimMask & 1 ) ) l = min[0];
        if( r > max[0] && ( trimMask & 2 ) ) r = max[0];
    } else {
        if( l > min[0] && ( trimMask & 1 ) ) l = min[0];
        if( r < max[0] && ( trimMask & 2 ) ) r = max[0];
    }

    if( b < t ) { // check for inverted Y range
        if( b < min[1] && ( trimMask & 4 ) ) b = min[1];
        if( t > max[1] && ( trimMask & 8 ) ) t = max[1];
    } else {
        if( b > min[1] && ( trimMask & 4 ) ) b = min[1];
        if( t < max[1] && ( trimMask & 8 ) ) t = max[1];
    }

    if( ortho ) 
        projectionMatrix.makeOrtho( l, r, b, t, n, f );
    else 
        projectionMatrix.makeFrustum( l, r, b, t, n, f );
#endif
}
Beispiel #30
0
osg::ref_ptr<osg::Geometry> HUDView::createRandNumBackground(osg::BoundingBox bb)
{
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;

	osg::Vec3 sizeUpY(0, bb.yMax() + bb.yMax() / 2, 0.0);
	osg::Vec3 sizeUpYN(0, -bb.yMax() / 2, 0.0);
	bb.expandBy(sizeUpY);
	bb.expandBy(sizeUpYN);


	osg::Vec3 halfExtent((bb.xMax() - bb.xMin()) / 2.0, (bb.yMax() - bb.yMin()) / 2.0f, 0);
	float x_length = bb.xMax() - bb.xMin();
	float y_length = bb.yMax() - bb.yMin();

	vertices->push_back(osg::Vec3(0, y_length, 0) - halfExtent);
	vertices->push_back(osg::Vec3(0, 0, 0) - halfExtent);
	vertices->push_back(osg::Vec3(x_length, 0, 0) - halfExtent);
	vertices->push_back(osg::Vec3(x_length, y_length, 0) - halfExtent);
	geom->setVertexArray(vertices);
	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
	geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
	colors->push_back(osg::Vec4(0.0f, 0.2f, 1.0f, 0.7f));
	geom->setColorArray(colors, osg::Array::BIND_OVERALL);
	geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
	osg::ref_ptr<osg::StateSet> stateset = geom->getOrCreateStateSet();
	stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
	stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	//stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
	stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	return geom;

}