• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

              C++博客 :: 首頁 :: 聯系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 398977
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

            軌跡球控制
            By Terence J. Grant (tjgrant@tatewake.com)

            如果只用鼠標來控制你的模型是不是很酷?軌跡球可以幫你做到這一點,我將告訴你我的實現,你可以把它應用在你的工程里。

            我的實現是基于Bretton Wade’s,它是基于Ken Shoemake’s 實現的,最初的版本,你可以從游戲編程指南這本圖上找到。但我還是修正了一些錯誤,并優化了它。

            軌跡球實現的內容就是把二維的鼠標點映射到三維的軌跡球,并基于它完成旋轉變化。

            為了完成這個設想,首先我們把鼠標坐標映射到[-1,1]之間,它很簡單:

             

            MousePt.X  =  ((MousePt.X / ((Width  -1) / 2)) -1);
            MousePt.Y = -((MousePt.Y / ((Height -1) / 2))-1);
            這只是為了數學上的簡化,下面我們計算這個長度,如果它大于軌跡球的邊界,我們將簡單的把z軸設為0,否則我們把z軸設置為這個二維點映射到球面上對應的z值。

            一旦我們有了兩個點,就可以計算它的法向量了和旋轉角了。

            下面我們從構造函數開始,完整的講解這個類:

             

            ArcBall_t::ArcBall_t(GLfloat NewWidth, GLfloat NewHeight)
            當點擊鼠標時,記錄點擊的位置
            void    ArcBall_t::click(const Point2fT* NewPt)
            當拖動鼠標時,記錄當前鼠標的位置,并計算出旋轉的量。

            void ArcBall_t::drag(const Point2fT* NewPt, Quat4fT* NewRot)

            如果窗口大小改變,設置鼠標移動的范圍
            void    ArcBall_t::setBounds(GLfloat NewWidth, GLfloat NewHeight)
            下面是完成計算所要用到的數據結果,都是一些矩陣和向量

            Matrix4fT Transform = { 1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f };

            Matrix3fT LastRot = { 1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f };

            Matrix3fT ThisRot = { 1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f };

            ArcBallT ArcBall(640.0f, 480.0f);
            Point2fT MousePt;
            bool isClicked = false; // 是否點擊鼠標
            bool isRClicked = false; // 是否右擊鼠標
            bool isDragging = false; // 是否拖動

            在上面定義的變量中,transform是我們獲得的最終的變換矩陣,lastRot是上一次鼠標拖動得到的旋轉矩陣,thisRot為這次鼠標拖動得到的旋轉矩陣。

            當我們點擊鼠標時,創建一個單位旋轉矩陣,當我們拖動鼠標時,這個矩陣跟蹤鼠標的變化。

            為了更新鼠標的移動范圍,我們在函數ReshapeGL中加入下面一行:

             

            void ReshapeGL (int width, int height)
            {
            . . .
            ArcBall.setBounds((GLfloat)width, (GLfloat)height); // 更新鼠標的移動范圍
            }

            // 處理鼠標的按鍵操作
            LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            {
            . . .
            case WM_MOUSEMOVE:
            MousePt.s.X = (GLfloat)LOWORD(lParam);
            MousePt.s.Y = (GLfloat)HIWORD(lParam);
            isClicked = (LOWORD(wParam) & MK_LBUTTON) ? true : false;
            isRClicked = (LOWORD(wParam) & MK_RBUTTON) ? true : false;
            break;

            case WM_LBUTTONUP: isClicked = false; break;
            case WM_RBUTTONUP: isRClicked = false; break;
            case WM_LBUTTONDOWN: isClicked = true; break;
            case WM_RBUTTONDOWN: isRClicked = true; break;
            . . .
            }

            為了隨著輸入更新我們的的狀態,在Update函數中需要處理更新參數
            if (isRClicked)										// 如果右鍵按下,這重置所有的變量
            {
            Matrix3fSetIdentity(&LastRot);
            Matrix3fSetIdentity(&ThisRot);
            Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);
            }

            if (!isDragging) // 如果沒有拖動
            {
            if (isClicked) // 第一次按下
            {
            isDragging = true; // 設置拖動為變量為true
            LastRot = ThisRot;
            ArcBall.click(&MousePt);
            }
            }
            else
            {
            if (isClicked) //如果按住拖動
            {
            Quat4fT ThisQuat;

            ArcBall.drag(&MousePt, &ThisQuat); // 更新軌跡球的變量
            Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // 計算旋轉量
            Matrix3fMulMatrix3f(&ThisRot, &LastRot);
            Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);
            }
            else // 如果放開鼠標,設置拖動為false
            isDragging = false;
            }

            好了,完成了上面的內容。我們到了繪制的階段。
            記住在繪制前,把我們得到的矩陣乘以當前的模型變換矩陣。
            glPushMatrix();									// 保存當前的矩陣
            glMultMatrixf(Transform.M); // 應用我們的變換矩陣

            glBegin(GL_TRIANGLES); // 繪制模型
            . . .
            glEnd();

            glPopMatrix(); // 彈出保存的矩陣

            我已經在上面給掩飾了所有的技巧,你可以不使用我告訴你的數學技巧,因為我想你會有更好的。現在你已經看到了,這是多么的簡單,你完全可以按你的風格創造出更好的軌跡球。


            posted on 2008-01-07 16:25 sdfasdf 閱讀(3842) 評論(4)  編輯 收藏 引用 所屬分類: OPENGL

            Feedback

            # re: NEHE的OPENGL教程 第48課 軌跡球實現的鼠標旋轉 2008-01-08 08:49 tip
            這里的圖片都是紅叉叉,有沒有完整的打包下載?包括源程序,謝謝  回復  更多評論
              

            # re: NEHE的OPENGL教程 第48課 軌跡球實現的鼠標旋轉 2008-01-08 10:32 秦歌
            因為CPPBLOG的文件上傳不能大于2M,所以無法上傳全部的資料。NEHE的教程網上提供下載的地方很多。  回復  更多評論
              

            # re: NEHE的OPENGL教程 第48課 軌跡球實現的鼠標旋轉 2008-11-28 14:59 陳建新
            太陽系運行的三維動畫設計與MFC和OpenGL的軟件實現怎么做?????

            我把您的OPENGL課程都復制下來了,謝謝您網上提供的資料!!!

            我的電郵:deooayh@yahoo.com.cn

            我們導師說OpenGL編程月工資有8000-10000元,是真的嗎???

            010-51564583 13607829738  回復  更多評論
              

            # re: NEHE的OPENGL教程 第48課 軌跡球實現的鼠標旋轉 2008-11-28 15:00 陳建新
            陳建新QQ:402282636   回復  更多評論
              

            久久久久波多野结衣高潮| 欧美一区二区久久精品| 亚洲人成无码www久久久| 欧美黑人又粗又大久久久| 久久精品无码一区二区三区免费 | 四虎国产精品免费久久久| 7777精品伊人久久久大香线蕉| 久久久青草久久久青草| 性做久久久久久久| 亚洲国产成人久久精品99| 久久精品www| 久久精品人成免费| 国产精品美女久久福利网站| 国产精品免费看久久久香蕉| 新狼窝色AV性久久久久久| 国产精品久久久久久久久久影院| 91精品国产综合久久香蕉 | 国产精品久久免费| 99久久国产综合精品女同图片 | 久久久久综合网久久| 久久无码人妻一区二区三区 | 亚洲精品乱码久久久久久久久久久久 | 亚洲一级Av无码毛片久久精品| 国产精品免费久久久久久久久| 狠狠干狠狠久久| 99国产欧美久久久精品蜜芽| 性欧美丰满熟妇XXXX性久久久| 久久精品国产清自在天天线| 伊人久久五月天| 免费精品久久天干天干| 久久亚洲AV无码精品色午夜麻豆| 亚洲国产成人久久一区WWW| 手机看片久久高清国产日韩| 久久99免费视频| 97热久久免费频精品99| 无码乱码观看精品久久| 亚洲va国产va天堂va久久| 久久国产精品久久精品国产| 国产精品美女久久久| 精品久久久久久无码专区不卡| 久久精品中文无码资源站|