• <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>

            天行健 君子當自強而不息

            設計一個靈活的Camera類(1)

            新建網(wǎng)頁 1

            我們使用D3DXMatrixLookAtLH函數(shù)來計算視圖空間變換矩陣。這個函數(shù)對于在固定位置布置和對準攝像機是非常好用的,不過它的用戶接口對于要響應用戶輸入來實現(xiàn)攝像機移動就不那么好用了。這就激發(fā)我們用我們自己的方法來解決,這里我們展示了怎樣實現(xiàn)一個Camera類,它使我們能夠比D3DXMatrixLookAtLH函數(shù)更好地操作攝像機,并且可以用來作為飛行模擬攝像機和第一人稱視角攝像機。


            12.1攝像機設計

            我們定義一個相對于世界坐標系的位置和攝像機的方向,這里使用四個攝像機向量:right vector ,  up vector,look vector 以及 position vector,如圖12.1所示。這些向量用來為攝像機定義一個坐標系來描述在世界坐標中的對應關(guān)系。因為 right up look 向量定義了攝像機在世界中的方向,我們有時把它們?nèi)齻€向量一起稱為方向向量(orientation vectors)。方向向量必須被標準化。假如彼此互相垂直且都是單位長度,那么我們就稱它們是正交標準化向量。我們做這些限制是因為等一會兒我們要將方向向量插入到一個行矩陣中。因為行向量是正交標準化的,所以該矩陣也就是正交矩陣。回憶一下,正交矩陣有一個特性就是它的逆矩陣等于它的轉(zhuǎn)置矩陣。

            有了這四個向量來描述攝像機,我們的攝像機就能夠按照下面六種方式變化了:

            圍繞right向量旋轉(zhuǎn)(pitch傾斜)

            圍繞up向量旋轉(zhuǎn)(yaw偏航)

            圍繞look向量旋轉(zhuǎn)(roll滾轉(zhuǎn))

            沿著right向量平移(strafe

            沿著up向量飛行(fly

            沿著look向量移動(move

            通過這六種操作,我們能夠沿著三個軸移動以及饒著三個軸旋轉(zhuǎn),這給了我們一個六度的自由。下面的Camera類定義了我們要的描述數(shù)據(jù)以及想要的方法:

               enum eCameraType { LAND_OBJECT, AIR_CRAFT };
               
               
            class cCamera
                {
               
            private:
                    eCameraType        m_camera_type;
                    D3DXVECTOR3        m_right;
                    D3DXVECTOR3        m_up;
                    D3DXVECTOR3        m_look;    
               
               
            public:
                    D3DXVECTOR3        m_pos;
               
               
            public:
                    cCamera();
                    cCamera(eCameraType camera_type);
                    ~cCamera() { };
               
                    
            void strafe(float units);    // left/right
               
                void fly(float units);        // up/down
               
                void walk(float units);        // forward/backward
               

                    
            void pitch(float angle);    // rotate on right vector
               
                void yaw(float angle);        // rotate on up vector
               
                void roll(float angle);        // rotate on look vector
               

                    
            void get_view_matrix(D3DXMATRIX* v);
                    
            void set_camera_type(eCameraType camera_type);
                    
                    
            void get_right(D3DXVECTOR3* right);
                    
            void get_up(D3DXVECTOR3* up);
                    
            void get_look(D3DXVECTOR3* look);
                };

            在類中我們定義了一個還沒有討論的eCameraType枚舉類型。目前,我們的攝像機支持兩種攝像機模式,LANDO_BJECT模式和AIR_CRAFT模式。AIR_CRAFT模式允許我們在空間中完全自由的移動。不過,在有些游戲中,比如第一人稱設計游戲,人是不能飛的;因此我們必須限制它在某些軸上的運動。指定為LAND_OBJECT模式的攝像機就限制了這些

            12.2 實現(xiàn)細節(jié)

            12.2.1計算視圖矩陣

            我們現(xiàn)在演示怎樣根據(jù)攝像機向量來計算視圖矩陣變換的。讓 p = (px,py,pz),r = (rx,ry,rz),u = (ux,uy,uz)以及 d = (dx,dy,dz)分別表示 position, right, up 以及 look 向量。

            視圖空間變換是指在世界坐標系中進行幾何變換以便將照相機平移變換到坐標系的原點并把它的方向旋轉(zhuǎn)至朝向Z軸的正方向(如圖12.2)。

            因此,我們希望有一個象這樣的變換矩陣V

             pV = (0, 0, 0)—矩陣V能將攝像機移動到原點。

             rV = (1, 0, 0)—矩陣V能將攝像機的right向量與世界坐標系中的x軸對齊。

             uV = (0, 1, 0)—矩陣V能將攝像機的up向量與世界坐標系中的y軸對齊。

            dV = (0, 0, 1)—矩陣V能將攝像機的look向量與世界坐標系中的z軸對齊。

            我們能將變換任務分為兩個部分:1)平移部分,將攝像機的位置移動到原點;2)旋轉(zhuǎn)部分,將攝像機的方向向量與世界坐標系的軸對齊。

            12.2.1.1 第一部分:平移

            平移只需要利用 p就可簡單地將 p 移動到原點,因為 pp=0。因此我們能夠用下面的矩陣來描述視圖變換中的平移部分:

            12.2.1.2 第二部分:旋轉(zhuǎn)

            矯正攝像機的三個方向向量使其與世界坐標系的軸對齊需要更多的工作。我們需要一個3*3的旋轉(zhuǎn)矩陣A,它能將rightuplook分別與x-y-以及z軸對齊。這個矩陣將滿足如下三個等式:

            注意:我們在這里使用3*3矩陣來工作是因為現(xiàn)在不需要額外的信息來表現(xiàn)旋轉(zhuǎn)。等一下我們將它增加到常用的4*4矩陣。

            因為這三個等式都有一個相同系數(shù)矩陣A ,所以我們能夠把它們合在一起。我們把它們從新寫到一起來:

            A有很多方法,但是我們知道AB逆矩陣因為BA = BB-1 = I。因為B 是一個正交矩陣(它的行向量是正交標準化的),我們知道它的逆矩陣就是它的轉(zhuǎn)置矩陣。因此,將方向向量和世界坐標系中的坐標軸對齊的變換如下:

            12.2.1.3 將兩部分合并

            最后,將A增加為4*4矩陣,同時將平移部分合并到旋轉(zhuǎn)部分形成的視圖變換矩陣V

            我們在cCamera::get_view_matrix方法中建立這個矩陣:

                void cCamera::get_view_matrix(D3DXMATRIX* v)
                {
                    
            // keep camera's axis orthogonal to each other
               
                    D3DXVec3Normalize(&m_look, &m_look);
               
                    D3DXVec3Cross(&m_up, &m_look, &m_right);
                    D3DXVec3Normalize(&m_up, &m_up);
               
                    D3DXVec3Cross(&m_right, &m_up, &m_look);
                    D3DXVec3Normalize(&m_right, &m_right);
               
                    
            // build the view matrix
               
                float x = -D3DXVec3Dot(&m_right, &m_pos);
                    
            float y = -D3DXVec3Dot(&m_up,    &m_pos);
                    
            float z = -D3DXVec3Dot(&m_look,  &m_pos);
               
                    (*v)(0, 0) = m_right.x;        (*v)(0, 1) = m_up.x;    (*v)(0, 2) = m_look.x;        (*v)(0, 3) = 0.0f;
                    (*v)(1, 0) = m_right.y;        (*v)(1, 1) = m_up.y;    (*v)(1, 2) = m_look.y;        (*v)(1, 3) = 0.0f;
                    (*v)(2, 0) = m_right.z;        (*v)(2, 1) = m_up.z;    (*v)(2, 2) = m_look.z;        (*v)(2, 3) = 0.0f;
                    (*v)(3, 0) = x;                (*v)(3, 1) = y;            (*v)(3, 2) = z;                (*v)(3, 3) = 1.0f;
                }

            你可能想知道方法中前面幾行代碼是干什么的。在幾次旋轉(zhuǎn)后,攝像機的方向向量可能變的不相互垂直了。因此,每當該函數(shù)被調(diào)用時,我們根據(jù)look向量重新計算upright向量,使它們保持相互垂直。新的up向量是這樣計算的up = look × right。 接著新的right向量是這樣計算的right = up × look

            posted on 2008-03-30 14:52 lovedday 閱讀(2190) 評論(1)  編輯 收藏 引用

            評論

            # re: 設計一個靈活的Camera類(1) 2011-10-12 16:10 Daywei

            前輩 請教 一下如何實現(xiàn) 相機的縮放  回復  更多評論   

            公告

            導航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            久久婷婷五月综合色奶水99啪| 久久人人爽人人爽人人片AV麻豆| 久久综合久久综合久久| 久久精品国产99久久无毒不卡| 综合网日日天干夜夜久久| 亚洲欧美一级久久精品| 香蕉久久夜色精品升级完成| 精品久久久久久无码专区| 久久影视国产亚洲| 久久午夜伦鲁片免费无码| 国产精品热久久无码av| 国产成人精品综合久久久| 久久99久久无码毛片一区二区 | 久久只这里是精品66| 亚洲精品蜜桃久久久久久| 久久久久18| AV狠狠色丁香婷婷综合久久| 午夜视频久久久久一区 | 久久久99精品一区二区| 久久人人添人人爽添人人片牛牛| 精品久久久噜噜噜久久久| 久久精品无码av| 亚洲国产精品无码久久一线| 欧美一级久久久久久久大| 国产精久久一区二区三区| 精品久久久久久中文字幕人妻最新| 亚洲日韩欧美一区久久久久我 | 精品国产热久久久福利| 国产V综合V亚洲欧美久久| 青青草原综合久久大伊人| 久久亚洲国产成人影院网站| 99久久精品免费看国产免费| 久久91精品国产91久久户| 国产精品久久久久久福利漫画| 久久精品国产色蜜蜜麻豆| 久久久青草久久久青草| 久久精品中文字幕大胸| 2021国产精品久久精品| 久久亚洲日韩看片无码| 久久99这里只有精品国产| 久久婷婷五月综合成人D啪|