zoukankan      html  css  js  c++  java
  • OSG例程(2) 碰撞检测

    OSG程序设计教程,第六章漫游,矩阵操作器。

    CSouth.cpp稍有不同: 

    1.将判断keydown值的多个if换成了switch。

    2.button拖动的旋转增量*0.001 

    3.RIGHT/LEFT key的旋转增量*0.1 

    CSouth.h
    /************************************************************************/
    /* Management Class of Manipulator                                                               */
    /************************************************************************/
    #pragma once
    #include 
    <osgViewer/Viewer>
    #include 
    <osgGA/MatrixManipulator>
    #include 
    <osgUtil/IntersectVisitor>
    #include 
    <osg/LineSegment>

    class CSouth:public osgGA::MatrixManipulator
    {
    public:
        CSouth();
        
    ~CSouth();
    private:
        
        osg::ref_ptr
    <osg::Node> m_node;    // node for detect collide
        unsigned int m_nID;    // camera operator
        float m_fMoveSpeed;    // move speed
        osg::Vec3 m_vPosition;    // position
        osg::Vec3 m_vRotation;    // rotation;
        bool m_bleftButtonDown;    // if the left btn is down
        float m_fpushX;         // x when left btn was down
        float m_fpushY;         // y ....
        bool m_bCollide;     // switch for detect collide

    public:
        
    void setCollide(bool collide);
        
    bool getCollide();
        
    void setFcollide();
        
        
    virtual void setNode(osg::Node*);

        
    virtual void setByMatrix(const osg::Matrix &matrix);
        
    virtual void setByInverseMatrix(const osg::Matrix &matrix);
        
    virtual osg::Matrix getMatrix(voidconst;
        
    virtual osg::Matrix getInverseMatrix(voidconst;

        
    virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us);

        
    float m_fAngle;
        
    void ChangePosition(osg::Vec3 &delta);

        
    float getSpeed();
        
    void setSpeed(float);

        
    void SetPosition(osg::Vec3 &position);
        
    void SetPosition(double * );

        osg::Vec3 GetPosition();

        
    void computeHomePosition();
    };
    CSouth.cpp
    /************************************************************************/
    /* Management Class of Manipulator                                      */
    /************************************************************************/

    #include 
    "CSouth.h"

    // constructor func
    CSouth::CSouth(void):m_fMoveSpeed(1.5f)
        ,m_bleftButtonDown(
    false)
        ,m_fpushX(
    0)
        ,m_fpushY(
    0)
        ,m_fAngle(
    2.5)
        ,m_bCollide(
    false)
    {
        m_vPosition 
    = osg::Vec3(0.0f,0.0f,5.0f);
        m_vRotation 
    = osg::Vec3(osg::PI_2,0.0f,0.0f);
    }

    // destructor
    CSouth::~CSouth(void)
    {
    }


    void CSouth::setByMatrix(const osg::Matrix &matrix)
    {}

    void CSouth::setByInverseMatrix(const osg::Matrix &matrix)
    {}

    osg::Matrix CSouth::getMatrix(
    voidconst
    {
        osg::Matrix mat;
        mat.makeRotate(m_vRotation._v[
    0],osg::Vec3(1.0f,0.0f,0.0f),
            m_vRotation._v[
    1],osg::Vec3(0.0f,1.0f,0.0f),
            m_vRotation._v[
    2],osg::Vec3(0.0f,0.0f,1.0f) );
        
    return mat * osg::Matrixd::translate(m_vPosition);
    }

    osg::Matrix CSouth::getInverseMatrix(
    voidconst
    {
        osg::Matrix mat;
        mat.makeRotate(m_vRotation._v[
    0],osg::Vec3(1.0f,0.0f,0.0f),
            m_vRotation._v[
    1],osg::Vec3(0.0f,1.0f,0.0f),
            m_vRotation._v[
    2],osg::Vec3(0.0f,0.0f,1.0f) );
        
    return osg::Matrixd::inverse( mat * osg::Matrixd::translate(m_vPosition) );
    }

    bool CSouth::handle(const osgGA::GUIEventAdapter &ea
        , osgGA::GUIActionAdapter 
    &us)
    {
        
    float mouseX = ea.getX();
        
    float mouseY = ea.getY();

        
    switch (ea.getEventType())
        {
            
    // keydown event
        case (osgGA::GUIEventAdapter::KEYDOWN):
            {
                
    switch (ea.getKey())
                {
                
    case (0x20):    // SPACE
                    
    // redraw
                    us.requestRedraw();
                    us.requestContinuousUpdate(
    false);
                    
    return true;
                
    case (0xFF50):    // HOME
                    ChangePosition(osg::Vec3(0,0,m_fMoveSpeed));
                    
    return true;
                
    case (0xFF57):    // END
                    ChangePosition(osg::Vec3(0,0,-m_fMoveSpeed));
                    
    return true;
                
    case (0x2B):    // +
                    m_fMoveSpeed += 1.0f;
                    
    return true;
                
    case (0x50):    // -
                    m_fMoveSpeed -= 1.0f;
                    
    if (m_fMoveSpeed < 1.0f)
                    {
                        m_fMoveSpeed 
    = 1.0f;
                    }
                    
    return true;
                
    case (0xFF52):    // UP
                case (0x57):    // W
                case (0x77):    // w
                    ChangePosition( osg::Vec3(0 , m_fMoveSpeed*sinf(osg::PI_2 + m_vRotation._v[2]) , 0 ) );
                    ChangePosition( osg::Vec3( m_fMoveSpeed
    *cosf(osg::PI_2 + m_vRotation._v[2]), 0 , 0 ) );
                    
    return true;
                
    case (0xFF54):    // DOWN
                case (0x53):    // S
                case (0x73):    // s
                    ChangePosition( osg::Vec3(0 , -m_fMoveSpeed*sinf(osg::PI_2 + m_vRotation._v[2]) , 0 ) );
                    ChangePosition( osg::Vec3( 
    -m_fMoveSpeed*cosf(osg::PI_2 + m_vRotation._v[2]), 0 , 0 ) );
                    
    return true;
                
    case (0x61):    // a
                case (0x41):    // A
                    ChangePosition( osg::Vec3(0 , m_fMoveSpeed*cosf(osg::PI_2 + m_vRotation._v[2]) , 0 ) );
                    ChangePosition( osg::Vec3( 
    -m_fMoveSpeed*sinf(osg::PI_2 + m_vRotation._v[2]), 0 , 0 ) );
                    
    return true;
                
    case (0x64):    // d
                case (0x44):    // D
                    ChangePosition( osg::Vec3(0 , -m_fMoveSpeed*cosf(osg::PI_2 + m_vRotation._v[2]) , 0 ) );
                    ChangePosition( osg::Vec3( m_fMoveSpeed
    *sinf(osg::PI_2 + m_vRotation._v[2]), 0 , 0 ) );
                    
    return true;
                
    case (0xFF53):    // ->RIGHT
                    m_vRotation._v[2-= osg::DegreesToRadians(m_fAngle*0.1);
                    
    return true;
                
    case (0xFF51):    // <-LEFT
                    m_vRotation._v[2+= osg::DegreesToRadians(m_fAngle*0.1);
                    
    return true;
                
    case (0x66):    // f
                case (0x46):    // F
                    computeHomePosition();
                    m_fAngle 
    -=0.2;
                    
    return true;
                
    case (0x67):    // g
                case (0x47):    // G
                    m_fAngle +=0.2;
                    
    return true;
                
    default:
                    
    return false;
                }
            }
        
    case (osgGA::GUIEventAdapter::PUSH):
            
    // left button
            if (ea.getButton() == 1)
            {
                m_fpushX 
    = mouseX;
                m_fpushY 
    = mouseY;
                m_bleftButtonDown 
    = true;
            }
            
    return false;
        
    case (osgGA::GUIEventAdapter::DRAG):
            
    if (m_bleftButtonDown)
            {
                m_vRotation._v[
    2-= osg::DegreesToRadians(m_fAngle * (mouseX - m_fpushX)* 0.001);
                m_vRotation._v[
    0+= osg::DegreesToRadians(1.1 * (mouseY - m_fpushY)* 0.001);
                
    if (m_vPosition._v[0>=3.14)
                    m_vPosition._v[
    0= 3.14;
                
    if (m_vPosition._v[0<= 0)
                    m_vPosition._v[
    0= 0;
            }
            
    return false;
        
    case (osgGA::GUIEventAdapter::RELEASE):
            
    // left button
            if (ea.getButton()==1)
            {
                m_bleftButtonDown 
    = false;
            }
            
    return false;
        
    default:
            
    return false;
        }
    }

    void CSouth::ChangePosition(osg::Vec3 &delta)
    {
        
    if (m_bCollide)
        {
            osg::Vec3 newPos 
    = m_vPosition + delta;
            osgUtil::IntersectVisitor iv;
            osg::ref_ptr
    <osg::LineSegment> line = new osg::LineSegment(newPos, m_vPosition);
            osg::ref_ptr
    <osg::LineSegment> lineZ = new osg::LineSegment(newPos + osg::Vec3(0.0f,0.0f, m_fMoveSpeed),
                newPos 
    - osg::Vec3(0.0f,0.0f, m_fMoveSpeed));
            iv.addLineSegment(lineZ.
    get());
            iv.addLineSegment(line.
    get());
            m_node
    ->accept(iv);
            
    if (!iv.hits())
            {
                m_vPosition 
    += delta;
            }
        }
        
    else
            m_vPosition 
    += delta;
    }

    float CSouth::getSpeed()
    {
        
    return m_fMoveSpeed;
    }

    void CSouth::setSpeed(float sp)
    {
        m_fMoveSpeed 
    = sp;
    }

    void CSouth::SetPosition(osg::Vec3 &position)
    {
        m_vPosition 
    = position;
    }
    void CSouth::SetPosition(double * position)
    {
        m_vPosition._v[
    0= position[0];
        m_vPosition._v[
    1= position[1];
        m_vPosition._v[
    2= position[2];
    }

    osg::Vec3 CSouth::GetPosition()
    {
        
    return m_vPosition;
    }

    void CSouth::setNode(osg::Node * node)
    {
        m_node 
    = node;
    }

    void CSouth::computeHomePosition()
    {
        
    if (m_node.get())
        {
            
    const osg::BoundingSphere &boudingSphere = m_node -> getBound();
            osg::Vec3 bp 
    = boudingSphere._center;
            SetPosition(bp);
        }
    }

    void CSouth::setCollide(bool collide)
    {
        m_bCollide 
    = collide;
    }

    bool CSouth::getCollide()
    {
        
    return m_bCollide;
    }

    void CSouth::setFcollide()
    {
        m_bCollide 
    = !m_bCollide;
    }

      

    main.cpp
    #include <osgDB/ReadFile>
    #include 
    <osgViewer/Viewer>
    #include 
    <osg/Node>
    #include 
    "CSouth.h"

    int main()
    {

        osg::ref_ptr
    <osgViewer::Viewer> viewer = new osgViewer::Viewer();

        viewer
    ->setSceneData(osgDB::readNodeFile("..\\ceep.ive"));

        viewer
    ->setCameraManipulator(new CSouth());

        viewer
    ->realize();
        viewer
    ->run();

    }

      

    其中使用到的ceep.ive,随便用max扔俩box什么的,导出即可。
  • 相关阅读:
    由asp的一个错误,看语言的不同:asp & java
    chrome 显示图片遇到的问题,与 淘宝图片服务器 缓存 有关系
    asp 调用 vb(activex dll) ,参数传递(传引用)需要注意
    asp <----> vb(com,dll) <---> c 来回的调用,生命在于折腾
    HTTP/1.1 100 Continue
    java 线程栈 & java.lang.StackOverflowError
    硬盘分区的意义
    硬盘性能 & 文件碎片的一些思考
    Java并发——ReentrantLock类源码阅读
    使用Windows的NAT功能
  • 原文地址:https://www.cnblogs.com/mumuliang/p/1884494.html
Copyright © 2011-2022 走看看