• 鼠标拖动物体DEMO


    在项目中,为了是设计更人性化,经常会要用鼠标去拖动物体,于是我就花时间写了个demo。

    之前我没有知道有MOUSEMOVE这个消息,于是就自己去想用LBUTTONDOWN和LBUTTONUP去实现MOUSEMOVE这个功能,最后悲剧了。

    开始我的想法是这样的,用POINT记录前后两次鼠标的位置,然后通过射线碰撞求出两个交点,进而求出平移矩阵。

    定义结构体记录鼠标点击的信息。

    typedef struct CursorInfo

    {

    Point oldpoint;

    Point newpoint;

    bool oldclick;

    }CursorInfo;

    响应鼠标点击事件:

    1、  LBUTTONDOWN。如果oldclickfalse,则令oldclicktrue,并记录鼠标点击位置oldpoint;如果oldclicktrue,则记录当前鼠标点击位置newpoint,并将oldclick置为false。通过oldpointnewpoint计算平移矩阵与物体原来的矩阵相乘即可。只有当oldpoint与物体相交时才计算平移矩阵并且进行矩阵的相关运算。

    2、  LBUTTONDOWNUPoldclick置为false

    后来我发现,如果你一直按着鼠标左键,是只响应一次LBUTTONDOWN消息的,这样的话就无法执行oldclick为true的情况,也几是说无法移动物体。

    在我查看LBUTTONDOWN的宏定义的时候发现了MOUSEMOVE这个消息,然后就想出了响应鼠标移动的消息。有了MOUSEMOVE,整个算法就很简单了,只要在LBUTTONDOWN和LBUTTONUP一对消息之间对MOUSEMOVE消息进行处理就行了,也就是不停的获取鼠标的位置,利用新旧两个鼠标的位置就可以求出平移矩阵,主要代码如下

    代码
    //改变移动后的物体的矩阵,uMsg为消息,World为物体原来的矩阵,plane为与xoy平面平行的平面,即y=plane
        void MoveMesh(UINT uMsg, ID3DXMesh *pMesh, D3DXMATRIX &World, float Plane)
        {
            
    float u, v, t;
            ::GetCursorPos(
    &m_NewPoint);
            ::ScreenToClient(DXUTGetHWND(), 
    &m_NewPoint);

            
    switch(uMsg)
            {
            
    case WM_LBUTTONDOWN:
                {
                    
    if!m_LClick )
                    {
                        m_LClick 
    = true;
                        m_Pick 
    = m_pPickManager->IsPick(m_NewPoint.x, m_NewPoint.y, pMesh, World, t, u, v );        
                        m_OldPoint 
    = m_NewPoint;            
                    }
                }
                
    break;

            
    case WM_LBUTTONUP:
                {
                    m_LClick 
    = false;
                    m_Pick 
    = false;
                }
                
    break;

            
    case WM_MOUSEMOVE:
                
    if( m_Pick )
                {
                    ::GetCursorPos(
    &m_NewPoint);
                    ::ScreenToClient(DXUTGetHWND(), 
    &m_NewPoint);
                    
    if(m_pPickManager->IsPick(m_OldPoint.x, m_OldPoint.y, pMesh, World, t, u, v ))
                    {
                        D3DXMATRIX world;
                        CaculateMatrix( world, m_OldPoint, m_NewPoint, Plane  );
                        World 
    *= world;
                    }
                    m_OldPoint 
    = m_NewPoint;            
                }
                
    break;
            }
        }

     

  • 相关阅读:
    Asp.Net2.0中的缓存
    webpartzone无法显示最小化和关闭按钮?
    TransactionScope分布式事务和非分布式事务
    JS获取GET参数的两种方法
    js 文件上传下载功能
    android动态设置布局LayoutInflater的使用详解
    Eclipse大括号换行显示
    Java强引用、 软引用、 弱引用、虚引用(转载)
    Android扭曲图像(水面落叶壁纸初步实现)
    win7系统自带的屏幕录制软件
  • 原文地址:https://www.cnblogs.com/littlethank/p/1816248.html
Copyright © 2020-2023  润新知