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

            亚洲欧洲久久久精品| 狠狠久久亚洲欧美专区| 无码精品久久一区二区三区| 久久九九久精品国产| 久久亚洲AV无码精品色午夜| 亚洲AV无码久久精品狠狠爱浪潮| 亚洲AV无码久久精品色欲| 久久r热这里有精品视频| 婷婷久久综合九色综合98| 中文成人久久久久影院免费观看| 色综合久久久久久久久五月| 国产精品久久久久久一区二区三区| 久久这里只精品国产99热| 久久影视综合亚洲| 久久精品人人槡人妻人人玩AV | 成人a毛片久久免费播放| 伊人久久大香线蕉综合热线| 久久超碰97人人做人人爱| 久久久WWW免费人成精品| 日产精品久久久久久久性色| 久久综合九色综合久99| 久久国产AVJUST麻豆| 国产成人精品久久亚洲| 久久久亚洲裙底偷窥综合| 激情五月综合综合久久69| 国产成人久久激情91| 欧美亚洲国产精品久久高清| 国产精品免费久久久久久久久 | 亚洲国产成人久久精品影视| 影音先锋女人AV鲁色资源网久久| 久久亚洲2019中文字幕| 国产精品狼人久久久久影院 | 伊人精品久久久久7777| 久久99精品久久久久久齐齐 | 99久久婷婷国产综合亚洲| 热99RE久久精品这里都是精品免费| 91精品国产91久久久久久青草| 久久精品国产亚洲αv忘忧草| 亚洲欧美精品一区久久中文字幕 | 久久久久久噜噜精品免费直播| 99久久精品免费看国产一区二区三区|