Thanks JS, fix merged and submitted to SVN.

On Thu, Nov 27, 2008 at 5:25 AM, Jean-Sébastien Guay
<[EMAIL PROTECTED]> wrote:
> Hello Robert,
>
> osgautocapture uses M_PI to convert degrees to radians, which didn't compile
> on Win32. Switched to using osg::DegreesToRadians. Also removed the "convert
> to radians" comment on each line, as the code clearly conveys this without
> needing a comment now.
>
> With this, OSG SVN as of tonight (~22:00 EST) compiles cleanly with examples
> on Windows Vista, Visual C++ 8.0 (2005) SP1.
>
> J-S
> --
> ______________________________________________________
> Jean-Sebastien Guay    [EMAIL PROTECTED]
>                               http://www.cm-labs.com/
>                        http://whitestar02.webhop.org/
>
> /**
>  * TODO:
>  * 1) Change example to use offscreen rendering (pbuffer) so that it becomes
> a true commandline tool with now windows
>  * 2) Make example work with other threading models than SingleThreaded
>  * 3) Add support for autocapture to movies
>  *
>  */
> #include <osg/ArgumentParser>
> #include <osg/CoordinateSystemNode>
> #include <osg/Matrix>
> #include <osg/NodeVisitor>
>
> #include <osgUtil/IntersectionVisitor>
> #include <osgUtil/GLObjectsVisitor>
>
> #include <osgDB/ReadFile>
> #include <osgDB/WriteFile>
>
> #include <osgGA/DriveManipulator>
> #include <osgGA/FlightManipulator>
> #include <osgGA/KeySwitchMatrixManipulator>
> #include <osgGA/TerrainManipulator>
> #include <osgGA/TrackballManipulator>
>
> #include <osgTerrain/Terrain>
> #include <osgTerrain/GeometryTechnique>
>
> #include <osgViewer/Viewer>
> #include <osgViewer/ViewerEventHandlers>
> #include <osgViewer/Renderer>
>
> #include <iostream>
> #include <sstream>
>
> /** Helper class*/
> template<class T>
> class FindTopMostNodeOfTypeVisitor : public osg::NodeVisitor
> {
> public:
>    FindTopMostNodeOfTypeVisitor():
>        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
>        _foundNode(0)
>    {}
>
>    void apply(osg::Node& node)
>    {
>        T* result = dynamic_cast<T*>(&node);
>        if (result)
>             _foundNode = result;
>         else
>             traverse(node);
>     }
>
>    T* _foundNode;
> };
>
> /** Convenience function*/
> template<class T>
> T* findTopMostNodeOfType(osg::Node* node)
> {
>    if (!node) return 0;
>
>    FindTopMostNodeOfTypeVisitor<T> fnotv;
>    node->accept(fnotv);
>
>    return fnotv._foundNode;
> }
>
> /** Capture the frame buffer and write image to disk*/
> class WindowCaptureCallback : public osg::Camera::DrawCallback
> {
> public:
>    WindowCaptureCallback(GLenum readBuffer, const std::string& name):
>        _readBuffer(readBuffer),
>        _fileName(name)
>        {
>            _image = new osg::Image;
>        }
>
>    virtual void operator () (osg::RenderInfo& renderInfo) const
>        {
>            glReadBuffer(_readBuffer);
>
>            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
>            osg::GraphicsContext* gc =
> renderInfo.getState()->getGraphicsContext();
>            if (gc->getTraits())
>            {
>                GLenum pixelFormat;
>
>                if (gc->getTraits()->alpha)
>                    pixelFormat = GL_RGBA;
>                else
>                    pixelFormat = GL_RGB;
>
>                int width = gc->getTraits()->width;
>                int height = gc->getTraits()->height;
>
>                std::cout<<"Capture: size="<<width<<"x"<<height<<",
> format="<<(pixelFormat == GL_RGBA ? "GL_RGBA":"GL_RGB")<<std::endl;
>
>                _image->readPixels(0, 0, width, height, pixelFormat,
> GL_UNSIGNED_BYTE);
>            }
>
>            if (!_fileName.empty())
>            {
>                std::cout << "Writing to: " << _fileName << std::endl;
>                osgDB::writeImageFile(*_image, _fileName);
>            }
>        }
>
> protected:
>    GLenum                      _readBuffer;
>    std::string                 _fileName;
>    osg::ref_ptr<osg::Image>    _image;
>    mutable OpenThreads::Mutex  _mutex;
> };
>
>
> /** Do Culling only while loading PagedLODs*/
> class CustomRenderer : public osgViewer::Renderer
> {
> public:
>    CustomRenderer(osg::Camera* camera)
>        : osgViewer::Renderer(camera),
>          _cullOnly(true)
>        {
>            setTargetFrameRate(1);
>            setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1);
>        }
>
>    /** Set flag to omit drawing in renderingTraversals */
>    void setCullOnly(bool on) { _cullOnly = on; }
>
>    virtual void operator () (osg::GraphicsContext* /*context*/)
>        {
>            if (_graphicsThreadDoesCull)
>            {
>                if (_cullOnly)
>                    cull();
>                else
>                    cull_draw();
>            }
>        }
>
>    virtual void cull()
>        {
>            osgUtil::SceneView* sceneView = _sceneView[0].get();
>            if (!sceneView || _done ) return;
>
>            updateSceneView(sceneView);
>
>            osgViewer::View* view =
> dynamic_cast<osgViewer::View*>(_camera->getView());
>            if (view)
> sceneView->setFusionDistance(view->getFusionDistanceMode(),
> view->getFusionDistanceValue());
>
>            sceneView->inheritCullSettings(*(sceneView->getCamera()));
>            sceneView->cull();
>        }
>
>    bool _cullOnly;
> };
>
>
> //===============================================================
> // MAIN
> //
> int main( int argc, char **argv )
> {
>    osg::ArgumentParser arguments(&argc, argv);
>    osg::ApplicationUsage* usage = arguments.getApplicationUsage();
>
>    usage->setApplicationName(arguments.getApplicationName());
>    usage->setDescription(arguments.getApplicationName()+" loads a model,
> sets a camera position and automatically captures screenshot to disk");
>    usage->setCommandLineUsage(arguments.getApplicationName()+" [options]
> filename ...");
>    usage->addCommandLineOption("--camera <lat> <lon> <alt> <heading>
> <incline> <roll>", "Specify camera position for image capture. Angles are
> specified in degrees and altitude in meters above sealevel (e.g. --camera 55
> 10 300000 0 30 0)");
>    usage->addCommandLineOption("--filename", "Filename for the captured
> image", "autocapture.jpg");
>    usage->addCommandLineOption("--db-threads", "Number of DatabasePager
> threads to use", "2");
>    usage->addCommandLineOption("--active", "Use active rendering instead of
> passive / lazy rendering");
>
>    // Construct the viewer and register options arguments.
>    osgViewer::Viewer viewer(arguments);
>
>    if (arguments.argc()<=1)
>    {
>
>  
> arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
>        return 1;
>    }
>
>    // Get user specified number of DatabaseThreads
>    int dbThreads = 2;
>    arguments.read("--db-threads", dbThreads);
>    if (dbThreads < 1) dbThreads = 1;
>
>    osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint(dbThreads);
>
>    // Get user specified file name
>    std::string fileName("autocapture.jpg");
>    arguments.read("--filename", fileName);
>
>    // Rendering mode is passive by default
>    bool activeMode = false;
>    if (arguments.read("--active"))
>        activeMode = true;
>
>    // Read camera settings for screenshot
>    double lat=50;
>    double lon=10;
>    double alt=2000;
>    double heading=0;
>    double incline=45;
>    double roll=0;
>    bool camera_specified=false;
>    if (arguments.read("--camera", lat, lon, alt, heading, incline, roll))
>    {
>        camera_specified=true;
>        lat = osg::DegreesToRadians(lat);
>        lon = osg::DegreesToRadians(lon);
>        heading = osg::DegreesToRadians(heading);
>        incline = osg::DegreesToRadians(incline);
>        roll = osg::DegreesToRadians(roll);
>    }
>
>    // load the data
>    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
>    if (!loadedModel)
>    {
>        std::cout << arguments.getApplicationName() <<": No data loaded" <<
> std::endl;
>        return 1;
>    }
>
>     // any option left unread are converted into errors to write out later.
>     arguments.reportRemainingOptionsAsUnrecognized();
>
>    // report any errors if they have occurred when parsing the program
> arguments.
>    if (arguments.errors())
>    {
>        arguments.writeErrorMessages(std::cout);
>        return 1;
>    }
>
>    // Setup specified camera
>    if (camera_specified)
>    {
>        osg::CoordinateSystemNode* csn =
> findTopMostNodeOfType<osg::CoordinateSystemNode>(loadedModel.get());
>        if(!csn) return 1;
>
>        // Compute eye point in world coordiantes
>        osg::Vec3d eye;
>        csn->getEllipsoidModel()->convertLatLongHeightToXYZ(lat, lon, alt,
> eye.x(), eye.y(), eye.z());
>
>        // Build matrix for computing target vector
>        osg::Matrixd target_matrix = osg::Matrixd::rotate(-heading,
> osg::Vec3d(1,0,0),
>                                                          -lat,
> osg::Vec3d(0,1,0),
>                                                          lon,
>  osg::Vec3d(0,0,1));
>
>        // Compute tangent vector ...
>        osg::Vec3d tangent = target_matrix.preMult(osg::Vec3d(0, 0, 1));
>
>        // Compute non-inclined, non-rolled up vector ...
>        osg::Vec3d up(eye);
>        up.normalize();
>
>        // Incline by rotating the target- and up vector around the
> tangent/up-vector
>        // cross-product ...
>        osg::Vec3d up_cross_tangent = up ^ tangent;
>        osg::Matrixd incline_matrix = osg::Matrixd::rotate(incline,
> up_cross_tangent);
>        osg::Vec3d target = incline_matrix.preMult(tangent);
>
>        // Roll by rotating the up vector around the target vector ...
>        osg::Matrixd roll_matrix = incline_matrix *
> osg::Matrixd::rotate(roll, target);
>        up = roll_matrix.preMult(up);
>
>        viewer.getCamera()->setViewMatrixAsLookAt(eye, eye+target, up);
>    }
>    else
>    {
>        // Only add camera manipulators if camera is not specified
>        camera_specified=false;
>        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator
> = new osgGA::KeySwitchMatrixManipulator;
>
>        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new
> osgGA::TrackballManipulator() );
>        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new
> osgGA::FlightManipulator() );
>        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new
> osgGA::DriveManipulator() );
>        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new
> osgGA::TerrainManipulator() );
>    }
>
>
>    // Optimize DatabasePager for auto-capture
>    osgDB::DatabasePager* pager = viewer.getDatabasePager();
>    pager->setDoPreCompile(false);
>
>    // Install custom renderer
>    osg::ref_ptr<CustomRenderer> customRenderer = new
> CustomRenderer(viewer.getCamera());
>    viewer.getCamera()->setRenderer(customRenderer.get());
>
>    // Override threading model
>    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
>
>    // Set the final SceneData to show
>    viewer.setSceneData(loadedModel.get());
>
>    // Realize GUI
>    viewer.realize();
>
>    //--- Load PageLOD tiles ---
>
>    // Initiate the first PagedLOD request
>    viewer.frame();
>
>    osg::Timer_t beforeLoadTick = osg::Timer::instance()->tick();
>
>    // Keep updating and culling until full level of detail is reached
>    while(!viewer.done() && pager->getRequestsInProgress())
>    {
> //        std::cout <<pager->getRequestsInProgress()<<" ";
>        viewer.updateTraversal();
>        viewer.renderingTraversals();
>    }
> //    std::cout<<std::endl;
>
>    osg::Timer_t afterLoadTick = osg::Timer::instance()->tick();
>    std::cout<<"Load and Compile time =
> "<<osg::Timer::instance()->delta_s(beforeLoadTick, afterLoadTick)<<"
> seconds"<<std::endl;
>
>
>    //--- Capture the image!!! ---
>    if (!activeMode)
>    {
>        // Do cull and draw to render the scene correctly
>        customRenderer->setCullOnly(false);
>
>        // Add the WindowCaptureCallback now that we have full resolution
>        viewer.getCamera()->setFinalDrawCallback(new
> WindowCaptureCallback(GL_BACK, fileName));
>
>        osg::Timer_t beforeRenderTick = osg::Timer::instance()->tick();
>
>        // Do rendering with capture callback
>         viewer.renderingTraversals();
>
>        osg::Timer_t afterRenderTick = osg::Timer::instance()->tick();
>        std::cout<<"Rendring time =
> "<<osg::Timer::instance()->delta_s(beforeRenderTick, afterRenderTick) <<"
> seconds"<<std::endl;
>
>        return 0;
>    }
>    else
>    {
>        return viewer.run();
>    }
> }
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to