osg开关门

    /* -*-c++-*- OpenSceneGraph Cookbook 
     * Chapter 5 Recipe 1 
     * Author: Wang Rui <wangray84 at gmail dot com> 
    */  
      
    #include <osg/ShapeDrawable>  
    #include <osg/MatrixTransform>  
    #include <osgAnimation/BasicAnimationManager>  
    #include <osgAnimation/UpdateMatrixTransform>  
    #include <osgAnimation/StackedRotateAxisElement>  
    #include <osgViewer/Viewer>  
    #include <algorithm>  
      
    #include "CommonFunctions"  
      
    osg::Node* createWall()  
    {  
        osg::ref_ptr<osg::ShapeDrawable> wallLeft =  
            new osg::ShapeDrawable( new osg::Box(osg::Vec3(-5.5f, 0.0f, 0.0f), 10.0f, 0.3f, 10.0f) );  
        osg::ref_ptr<osg::ShapeDrawable> wallRight =  
            new osg::ShapeDrawable( new osg::Box(osg::Vec3(10.5f, 0.0f, 0.0f), 10.0f, 0.3f, 10.0f) );  
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;  
        geode->addDrawable( wallLeft.get() );  
        geode->addDrawable( wallRight.get() );  
        return geode.release();  
    }  
      
    osg::MatrixTransform* createDoor()  
    {  
        osg::ref_ptr<osg::ShapeDrawable> doorShape =  
            new osg::ShapeDrawable( new osg::Box(osg::Vec3(2.5f, 0.0f, 0.0f), 6.0f, 0.2f, 10.0f) );  
        doorShape->setColor( osg::Vec4(1.0f, 1.0f, 0.8f, 1.0f) );  
          
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;  
        geode->addDrawable( doorShape.get() );  
          
        osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform;  
        trans->addChild( geode.get() );  
        return trans.release();  
    }  
      
    void generateDoorKeyframes( osgAnimation::FloatLinearChannel* ch, bool closed )  
    {  
        osgAnimation::FloatKeyframeContainer* kfs = ch->getOrCreateSampler()->getOrCreateKeyframeContainer();  
        kfs->clear();  
        if ( closed )  
        {  
            kfs->push_back( osgAnimation::FloatKeyframe(0.0, 0.0f) );  
            kfs->push_back( osgAnimation::FloatKeyframe(1.0, osg::PI_2) );  
        }  
        else  
        {  
            kfs->push_back( osgAnimation::FloatKeyframe(0.0, osg::PI_2) );  
            kfs->push_back( osgAnimation::FloatKeyframe(1.0, 0.0f) );  
        }  
    }  
      
    class OpenDoorHandler : public osgCookBook::PickHandler  
    {  
    public:  
        OpenDoorHandler() : _closed(true) {}  
          
        virtual void doUserOperations( osgUtil::LineSegmentIntersector::Intersection& result )  
        {  
            osg::NodePath::iterator itr = std::find(  
                result.nodePath.begin(), result.nodePath.end(), _door.get() );  
            if ( itr!=result.nodePath.end() )  
            {  
                if ( _manager->isPlaying(_animation.get()) )  
                    return;  
                  
                osgAnimation::FloatLinearChannel* ch = dynamic_cast<osgAnimation::FloatLinearChannel*>(  
                    _animation->getChannels().front().get() );  
                if ( ch )  
                {  
                    generateDoorKeyframes( ch, _closed );  
                    _closed = !_closed;  
                }  
                _manager->playAnimation( _animation.get() );  
            }  
        }  
          
        osg::observer_ptr<osgAnimation::BasicAnimationManager> _manager;  
        osg::observer_ptr<osgAnimation::Animation> _animation;  
        osg::observer_ptr<osg::MatrixTransform> _door;  
        bool _closed;  
    };  
      
    int main( int argc, char** argv )  
    {  
        // Create the animation callback  
        osg::ref_ptr<osgAnimation::FloatLinearChannel> ch = new osgAnimation::FloatLinearChannel;  
        ch->setName( "euler" );  
        ch->setTargetName( "DoorAnimCallback" );  
        generateDoorKeyframes( ch.get(), true );  
          
        osg::ref_ptr<osgAnimation::Animation> animation = new osgAnimation::Animation;  
        animation->setPlayMode( osgAnimation::Animation::ONCE );  
        animation->addChannel( ch.get() );  
          
        osg::ref_ptr<osgAnimation::UpdateMatrixTransform> updater =  
            new osgAnimation::UpdateMatrixTransform("DoorAnimCallback");  
        updater->getStackedTransforms().push_back(  
            new osgAnimation::StackedRotateAxisElement("euler", osg::Z_AXIS, 0.0) );  
          
        osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;  
        manager->registerAnimation( animation.get() );  
          
        // Create the scene graph  
        osg::MatrixTransform* animDoor = createDoor();  
        animDoor->setUpdateCallback( updater.get() );  
          
        osg::ref_ptr<osg::Group> root = new osg::Group;  
        root->addChild( createWall() );  
        root->addChild( animDoor );  
        root->setUpdateCallback( manager.get() );  
          
        osg::ref_ptr<OpenDoorHandler> handler = new OpenDoorHandler;  
        handler->_manager = manager.get();  
        handler->_animation = animation.get();  
        handler->_door = animDoor;  
          
        osgViewer::Viewer viewer;  
        viewer.addEventHandler( handler.get() );  
        viewer.setSceneData( root.get() );  
        return viewer.run();  
    }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值