예제 #1
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;
}
예제 #2
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
}
예제 #3
0
osg::Vec2 Curve::mapTo2D( const osg::Vec3 p, osg::BoundingBox originRect, osg::BoundingBox newRect )
{
    if ( originRect.xMin()==originRect.xMax() )
    {
        newRect.zMin() = newRect.yMin(); newRect.zMax() = newRect.yMax();
        newRect.yMin() = newRect.xMin(); newRect.yMax() = newRect.xMax();
        newRect.xMin() = 0.0;            newRect.xMax() = 0.0;
    }
    else if ( originRect.yMin()==originRect.yMax() )
    {
        newRect.zMin() = newRect.yMin(); newRect.zMax() = newRect.yMax();
        newRect.yMin() = 0.0;            newRect.yMax() = 0.0;
    }

    osg::Vec3 newPoint = mapTo( p, originRect, newRect );
    osg::Vec2 point2D( newPoint.x(), newPoint.y() );
    if ( originRect.xMin()==originRect.xMax() ) point2D.set( newPoint.y(), newPoint.z() );
    else if ( originRect.yMin()==originRect.yMax() ) point2D.set( newPoint.x(), newPoint.z() );

    return point2D;
}
예제 #4
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();
}
예제 #5
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;
}
예제 #6
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_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;
}
예제 #7
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;
}
예제 #8
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;
    }
}
예제 #9
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;
    }
}
예제 #10
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;
}
예제 #11
0
void doQuadTreeVPB(std::string basePath,std::vector<std::vector<string> > datalist_lod,Bounds bounds,CameraCalib &calib,texcache_t cachedDirs,int POTAtlasSize,bool useTextureArray,bool useReimage,bool useVirtualTex,const osg::BoundingBox &bbox,string src_proj4_coord_system,string dst_proj4_coord_system,double sparseRatio,bool no_hw_context,bool no_atlas){
    //vector<osg::KdTree*> trees;
    vpb::GeospatialExtents geo(bounds.bbox.xMin(), bounds.bbox.yMin(), bounds.bbox.xMax(),bounds.bbox.yMax(),false);
    int numlod=datalist_lod.size();
    if(useVirtualTex)
        useReimage=false;
    osg::ref_ptr<vpb::MyDataSet> m=new vpb::MyDataSet(calib,basePath,useTextureArray,useReimage,useVirtualTex);
    if(useVirtualTex)
        m->_atlas=createVTAtlas( m->viewProj, m->totalX, m->totalY,POTAtlasSize,
                                 m->mosaic_cells,
                               false);
    m->_cachedDirs=cachedDirs;
    m->_no_hw_context=no_hw_context;
    m->_zrange=osg::Vec4(bbox.zMin(),bbox.zMax(),bbox.zMin(),bbox.zMax());
    m->setNumReadThreadsToCoresRatio(1.5);
    m->setNumWriteThreadsToCoresRatio(1.5);
    m->setDestinationCoordinateSystem(dst_proj4_coord_system);
    m->setSourceCoordinateSystemProj4(src_proj4_coord_system);
    m->sparseRatio=sparseRatio;
    // m->setCompressionMethod(vpb::BuildOptions::NVTT);
    //m->setCompressionMethod(vpb::BuildOptions::GL_DRIVER);
    //vpb::ImageOptions *imageOptions = new vpb::ImageOptions();
    //imageOptions->setTextureType(vpb::ImageOptions::RGBA);
    //m->setLayerImageOptions(0,imageOptions);
    //  m->setMaximumVisibleDistanceOfTopLevel(1e11);
    if(useVirtualTex)
        m->setRadiusToMaxVisibleDistanceRatio(7);
    else
        m->setRadiusToMaxVisibleDistanceRatio(7);

    m->setDestinationName("mesh/real.ive");

    m->setLogFileName("tmp.log");
    osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
    for(int lod=0/*datalist_lod.size()-1*/; lod < (int)datalist_lod.size(); lod++){
        for(int i=0; i<(int)datalist_lod[lod].size(); i++){
            if(!osgDB::fileExists(datalist_lod[lod][i]))
                continue;
            std::string mf=datalist_lod[lod][i];
            int npos=mf.find("/");

            std::string bbox_file;
            TexturedSource *sourceModel;
          //  if(!useVirtualTex && !useReimage){
            bbox_file=osgDB::getFilePath(mf)+"/bbox-"+osgDB::getSimpleFileName(mf).substr(0,osgDB::getSimpleFileName(mf).size()-9)+".ply.txt";

                sourceModel =new TexturedSource(vpb::Source::MODEL,mf,bbox_file,!useVirtualTex && !useReimage,useVirtualTex || useReimage);
           // }else{
           //     sourceModel=new TexturedSource(vpb::Source::MODEL,mf);
           // }
            sourceModel->setMaxLevel(lod);
            sourceModel->setMinLevel(lod);
            sourceModel->setCoordinateSystem(new osg::CoordinateSystemNode("WKT",""));
            sourceModel->ids=NULL;
            osg::Node* model;/*
            ply::VertexDataMosaic vertexData;

           // if(!m->_useReImage && !m->_useVirtualTex)
           // {
                model= vertexData.readPlyFile(sourceModel->getFileName().c_str());
              //  cout <<vertexData._vertices->size() <<" "<<vertexData._triangles->size()<< " "<<vertexData._texCoord[0]->size()<<" "<<vertexData._texIds->size()<<endl;
                sourceModel->texAndAux->resize(vertexData._vertices->size());
                for(int k=0; k<(int)vertexData._triangles->size()-2; k+=3){
                    for(int l=0; l <3; l++)
                    sourceModel->texAndAux->at(vertexData._triangles->at(k+(2-l)))=osg::Vec4(vertexData._texCoord[0]->at(k+l)[0],vertexData._texCoord[0]->at(k+l)[1],
                                                         vertexData._texIds->at(k/3)[0],vertexData._texIds->at(k/3)[1]);

                }
                //toVert(model,vertexData._texCoord,vertexData._texIds,sourceModel->tex,sourceModel->ids);
            //}else*/

            model = osgDB::readNodeFile(sourceModel->getFileName());
          //  cout << model << " "<< sourceModel->getFileName()<<endl;
            if(lod == 0){
                osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
                model->accept(cbbv);
                osg::BoundingBox totalbb = cbbv.getBoundingBox();
                FILE *zrangefp=fopen("mesh/zrange.txt","w");
                if(!zrangefp ){
                    fprintf(stderr,"Cannot open mesh/zrange.txt\n");
                    exit(-1);
                }
                fprintf(zrangefp,"%f %f\n",totalbb.zMin(),totalbb.zMax());
                fclose(zrangefp);

            }
            //std::cerr << "aaa " << sourceModel->tex->at(0)->size() << " " << sourceModel->ids->size() <<endl;
            osg::ref_ptr<osg::KdTreeBuilder>  _kdTreeBuilder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
            model->accept(*_kdTreeBuilder);
            if (model)
            {
                vpb::SourceData* data = new vpb::SourceData(sourceModel);
                data->_model = model;
                data->_extents.expandBy(model->getBound());
             //   cout << model->getBound()._radius << " "<< model->getBound().center()<<endl;
                sourceModel->setSourceData(data);
                osg::Geode *geode= dynamic_cast<osg::Geode*>(model);
                if(geode && geode->getNumDrawables()){
                    osg::Drawable *drawable = geode->getDrawable(0);
                    osg::Geometry *geom = dynamic_cast< osg::Geometry*>(drawable);
                    sourceModel->colors=(osg::Vec4Array*)geom->getColorArray();
                    sourceModel->_kdTree = dynamic_cast<osg::KdTree*>(drawable->getShape());
                    // trees.push_back(sourceModel->_kdTree);
                }else{
                    osg::notify(osg::INFO) << "No drawbables \n";
                }
            }


            m->addSource(sourceModel);
        }
    }
    m->createNewDestinationGraph(geo,256,128,numlod);
    m->_run();
    //    for(int i=0; i<trees.size(); i++)
    //    delete trees[i];


}
예제 #12
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);
}