• <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>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            GRE的空間變換,對(duì)于新手來說是一個(gè)頭疼的問題,而其中的陷阱也是一堆一堆,即使我已經(jīng)爬出這些陷阱,我還是覺得有必要講一下.

            translate()這個(gè)神秘的函數(shù).網(wǎng)上發(fā)現(xiàn)一個(gè)朋友中了陷阱:

            以下黑體字為論壇某個(gè)網(wǎng)友的錯(cuò)誤理解:

            ----------------------------------------------------------------------------------------------------------------------------------

            在CSDN和gameres上都發(fā)了這個(gè)問題,一直沒人解答,不知道這兒怎么樣?
            void createScene() { 
            ... //第一個(gè)物體(坐標(biāo)原點(diǎn))  
            Entity* head = mSceneMgr->createEntity("object1", "ogrehead.mesh");   
            head->setMaterialName("Examples/Rockwall"); 
            SceneNode* node1 = rootNode->createChildSceneNode();
            node1->attachObject(head);

            //第二個(gè)物體 
            head = mSceneMgr->createEntity("object2", "ogrehead.mesh"); 
            SceneNode* node2 = node1->createChildSceneNode(); 
            node2->attachObject(head); 
            node2->translate(Vector3(50, 0, 0), SceneNode::TS_PARENT); 

            //第三個(gè)物體 
            head = mSceneMgr->createEntity("object3", "ogrehead.mesh");
            SceneNode* node3 = node2->createChildSceneNode(); 
            node3->attachObject(head);
            node3->translate(Vector3(0, 50, 0), SceneNode::TS_WORLD); 
            node3->yaw(Degree(90), SceneNode::TS_LOCAL); 
            }
            按照空間變換分析,node1在原點(diǎn),node2的世界坐標(biāo)是(50, 0, 0),node3的世界坐標(biāo)是(0, 50, 0),
            但是從顯示的結(jié)果來看node3是(50, 50, 0),
            無論用哪個(gè)TransformSpace值,結(jié)果都是一樣的:translate都是相對(duì)于parent,旋轉(zhuǎn)都是在loacal中。

             

            我對(duì)這個(gè)參數(shù)的理解是:
            TS_WORLD:不管當(dāng)前節(jié)點(diǎn)是在哪個(gè)節(jié)點(diǎn)下,他的操作都是相對(duì)于世界坐標(biāo)系的原點(diǎn)的。
                如node3是在node2下面,所以他的初始世界坐標(biāo)應(yīng)該是(50,0,0),
                如果它translate(Vector3(0, 50, 0), SceneNode::TS_LOCAL), 世界坐標(biāo)應(yīng)該是(50, 50, 0)
                如果它translate(Vector3(0, 50, 0), SceneNode::TS_WORLD), 相對(duì)于世界坐標(biāo)原點(diǎn)的平移,世界坐標(biāo)應(yīng)該是(0, 50, 0)

            -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

             

            這個(gè)網(wǎng)友遇到的問題,其實(shí)就是translate變換的問題,為什么他會(huì)這么理解,我們慢慢分析:

             

            translate()這個(gè)函數(shù),其實(shí)是相對(duì)于父節(jié)點(diǎn)的相對(duì)移動(dòng),而不是那個(gè)網(wǎng)友理解的絕對(duì)移動(dòng).

            但是如果是相對(duì)于父節(jié)點(diǎn)的相對(duì)移動(dòng),還要選擇3個(gè)參考空間干嘛???

            這就是關(guān)鍵所在,這3個(gè)參考空間,是決定相對(duì)移動(dòng)量的方向的,而不是那個(gè)網(wǎng)友理解成的移動(dòng)的位置!!!

             

            為什么他的代碼中的第3個(gè)節(jié)點(diǎn)無論怎么改變參考空間結(jié)果都一樣?如果理解成方向,就豁然開朗了.
            因?yàn)槭澜缭c(diǎn),父節(jié)點(diǎn),他本身,這3個(gè)節(jié)點(diǎn)的面向的方向都是一樣的(默認(rèn)-Z方向),所以相對(duì)移動(dòng)的值是一樣,都是Y方向相對(duì)移動(dòng)50


            如果世界原點(diǎn),父節(jié)點(diǎn)都是默認(rèn)面向Z正方向,本身節(jié)點(diǎn)旋轉(zhuǎn)90度面向Y的方向
            如果他在本地空間translate(Vector3(0, 50, 0),SceneNode::TS_LOCAL),
            因?yàn)樗旧沓験, 在本地空間Y方向移動(dòng)50, 在世界空間,其實(shí)就是-Z方向移動(dòng)了50.

            一句話:都是相對(duì)父節(jié)點(diǎn)移動(dòng)50單位,而參考空間只是決定這50個(gè)單位移動(dòng)的方向!

            所以參考空間理解成朝向,就對(duì)了
            世界空間----------認(rèn)定世界原點(diǎn)的朝向?yàn)闃?biāo)準(zhǔn)朝向,默認(rèn)-Z方向
            父節(jié)點(diǎn)空間----------認(rèn)定父節(jié)點(diǎn)的朝向?yàn)闃?biāo)準(zhǔn)朝向
            本地空間--------------認(rèn)定本身節(jié)點(diǎn)的朝向?yàn)闃?biāo)準(zhǔn)朝向

             

            那個(gè)網(wǎng)友的理解,其實(shí)合情合理,他的理解其實(shí)就是下面假想的函數(shù):

            setPosition(TS_WORLD); 
            setPosition(TS_PARENT); 
            setPosition(TS_LOCAL);

            可惜這只是假想,設(shè)置位置的函數(shù)并沒有參考空間可以選~~~

            OGRE為什么不設(shè)置這樣的函數(shù)呢?因?yàn)槠鋵?shí)已經(jīng)有替代的函數(shù)了:
            setPosition()   // 相對(duì)父空間坐標(biāo)

            setDerivedPosition()  // 世界空間絕對(duì)坐標(biāo)

            而本地空間的設(shè)置位置函數(shù)根本不需要....

             

            最后,回頭一想,為什么容易把translate()理解錯(cuò)....原因就是translate(TS_PARENT)相對(duì)父空間移動(dòng)
            的時(shí)候,如果把參考空間父空間理解成方向或者位置,2種情況下結(jié)果是正好是一樣的,巧合啊
            就是這種巧合,暗藏了一個(gè)陷進(jìn),讓很多人認(rèn)為理解成位置正好是對(duì)的...

            不信看源碼:

             

             

            void Node::translate(const Vector3& d, TransformSpace relativeTo)  
            {  
                
            switch(relativeTo)  
                {  
                
            case TS_LOCAL:  
                    
            // position is relative to parent so transform downwards  
                    mPosition += mOrientation * d;  
                    
            break;  
                
            case TS_WORLD:  
                    
            // position is relative to parent so transform upwards  
                    if (mParent)  
                    {  
                        mPosition 
            += (mParent->_getDerivedOrientation().Inverse() * d)  
                            
            / mParent->_getDerivedScale();  
                    }  
                    
            else  
                    {  
                        mPosition 
            += d;  
                    }  
                    
            break;  
                
            case TS_PARENT:  
                    mPosition 
            += d;  
                    
            break;  
                }  
                needUpdate();  
              
            }  

             

             

             

            因?yàn)閙Position相對(duì)于父節(jié)點(diǎn)的位置和方向,

            所以計(jì)算結(jié)果都要換算成父空間相加.

             

            本地空間,朝本身節(jié)點(diǎn)的朝向移動(dòng)d,換到mPosition的所在的父空間只需要旋轉(zhuǎn)一定角度,

            這個(gè)角度應(yīng)該是本身節(jié)點(diǎn)方向和父節(jié)點(diǎn)的方向的夾角,正好是mOrientation

            mPosition += mOrientation * d;

             

            世界空間,朝世界原點(diǎn)的朝向移動(dòng)d ,換到mPosition的所在父空間只需要旋轉(zhuǎn)一定角度,

            這個(gè)角度應(yīng)該是世界原點(diǎn)方向和父節(jié)點(diǎn)的方向的夾角,正好是父節(jié)點(diǎn)世界絕對(duì)角度再取反.

            (為什么要取反,2個(gè)四元數(shù)相乘是不能交換的,因?yàn)槭澜绻?jié)點(diǎn)和父節(jié)點(diǎn)夾角 != 父節(jié)點(diǎn)和世界節(jié)點(diǎn)夾角,正好相反)

                   mPosition += (mParent->_getDerivedOrientation().Inverse() * d)
                                / mParent->_getDerivedScale();

             

            父節(jié)點(diǎn)空間,朝父節(jié)點(diǎn)的朝向移動(dòng)d ,換到mPosition的所在父空間只需要旋轉(zhuǎn)一定角度,

            父空間轉(zhuǎn)到父空間....其實(shí)角度就是一致的

            應(yīng)該是mPosition += Quaternion::IDENTITY * d;

            等價(jià)于mPosition +=  d;

            青青国产成人久久91网| 亚洲精品乱码久久久久久不卡| 亚洲国产精品无码久久一线 | 狠狠色丁香久久综合婷婷| 久久综合狠狠综合久久激情 | 久久er国产精品免费观看2| 免费精品久久久久久中文字幕 | 亚洲精品无码成人片久久| 久久久久亚洲AV无码专区体验| 国产精品久久精品| 性做久久久久久久久久久| 精品久久久久久国产91| 亚洲精品tv久久久久| 99久久超碰中文字幕伊人| 热久久视久久精品18| 色综合久久综精品| 无码久久精品国产亚洲Av影片| 久久男人AV资源网站| 国产成年无码久久久久毛片| 热99RE久久精品这里都是精品免费 | 中文国产成人精品久久不卡| 国产福利电影一区二区三区久久久久成人精品综合 | 久久99国产精品久久99果冻传媒| 老男人久久青草av高清| 精品久久久久久久中文字幕| 色综合久久无码中文字幕| 亚洲精品国产自在久久| 精品国产综合区久久久久久 | 久久影视综合亚洲| 欧美精品一区二区精品久久| 老色鬼久久亚洲AV综合| 2020国产成人久久精品| 久久综合狠狠综合久久97色| AA级片免费看视频久久| 亚洲精品国产成人99久久| 国内精品久久久久影院免费| 精品久久久久久中文字幕人妻最新| 精品久久久久久国产| 热99RE久久精品这里都是精品免费 | 九九热久久免费视频| 99久久免费只有精品国产|