• <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++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            (地基工)Ogre動畫拾取函數優化版本

            Posted on 2011-09-28 16:39 點點滴滴 閱讀(558) 評論(0)  編輯 收藏 引用 所屬分類: 08 游戲SDK
            bool GraphicalWorld::pickPoint(const Ray& ray, Vector3 &hitpoint, const WS::StringVector& excludeobjects, Real max_distance/* = 9999.0f*/, uint32 mask /*= 0xFFFFFFFF*/)
            {
                WS_ASSERT( msCore );

                
            //const unsigned long mask = 0xFFFFFFFF;
                Ogre::Vector3 pOrigin = VEC_WS2OGRE(ray.getOrigin());
                Ogre::Vector3 pDirection 
            = VEC_WS2OGRE(ray.getDirection());
                Ogre::Ray ogreRay(pOrigin, pDirection);
                
            if (!mpRaySceneQuery)
                {
                    mpRaySceneQuery 
            = msCore->getSceneMgr()->createRayQuery( ogreRay, mask );
                }
                
            else
                {
                    mpRaySceneQuery
            ->setRay(ogreRay );    
                    mpRaySceneQuery
            ->setQueryMask(mask);
                }        
                mpRaySceneQuery
            ->setSortByDistance(true);

                
            if (mpRaySceneQuery->execute().size() <= 0return (false);

                
            // at this point we have raycast to a series of different objects bounding boxes.
                
            // we need to test these different objects to see which is the first polygon hit.
                
            // there are some minor optimizations (distance based) that mean we wont have to
                
            // check all of the objects most of the time, but the worst case scenario is that
                
            // we need to test every triangle of every object.
                Ogre::Real closest_distance = max_distance;
                Ogre::Vector3 closest_result;
                Ogre::RaySceneQueryResult 
            &query_result = mpRaySceneQuery->getLastResults();
                Ogre::MovableObject
            * movable;

                
            for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
                {
                    
            // stop checking if we have found a raycast hit that is closer
                    
            // than all remaining entities
                    if ((closest_distance >= 0.0f&& (closest_distance < query_result[qr_idx].distance))
                    {
                        
            break;
                    }
                    movable 
            = query_result[qr_idx].movable;
                    
            // only check this result if its a hit against an entity
                    if ((query_result[qr_idx].movable != NULL) && (query_result[qr_idx].movable->getMovableType().compare("Entity"== 0&& movable->isVisible())
                    {
                        Ogre::Entity
            * pOgreEntity = static_cast<Ogre::Entity*>(movable);
                        EntityMap::const_iterator itFind 
            = mEntityMap.find(pOgreEntity);
                        
            if (itFind == mEntityMap.end())
                            
            continue;

                        
            // get the entity to check
                        graphics::IEntity *pEntity = itFind->second;

                        
            const String& pname = pEntity->getPoolableObjectID();

                        
            bool foundinlist = false;
                        
            for(unsigned int lit = 0;lit < excludeobjects.size();lit++)
                        {
                            
            if(excludeobjects[lit] == pname)
                            {
                                foundinlist 
            = true;
                                
            break;
                            }
                        }

                        
            if(foundinlist) continue;

                        
            //parentOrientation * (parentScale * mPosition)
                        std::pair<bool, Ogre::Real> hit = HitMesh(ogreRay, pOgreEntity);

                        
            // if it was a hit check if its the closest
                        if (!hit.first) continue;

                        
            bool new_closest_found = false;
                        
            if ((closest_distance < 0.0f|| (hit.second< closest_distance))
                        {
                            
            // this is the closest so far, save it off
                            closest_distance = hit.second;
                            new_closest_found 
            = true;
                        }

                        
            // if we found a new closest raycast for this object, update the
                        
            // closest_result before moving on to the next object.
                        if (new_closest_found)
                        {
                            closest_result 
            = ogreRay.getPoint(closest_distance);
                        }
                    }
                }

                
            // return the result
                if (closest_distance != max_distance)
                {
                    hitpoint 
            = VEC_OGRE2WS(closest_result);
                    
            return true;
                }
                
            else
                {
                    
            return false;
                }
            }


            拾取Mesh
            std::pair<bool, Real> GraphicalWorld::HitMesh(const Ogre::Ray& ray,Ogre::Entity *entity)
            {
                
            //parentOrientation * (parentScale * mPosition)
                Ogre::Vector3 pPostion = entity->getParentNode()->_getDerivedPosition();
                Ogre::Vector3 pScale 
            = entity->getParentNode()->_getDerivedScale();
                Ogre::Quaternion q 
            = entity->getParentNode()->_getDerivedOrientation();

                Ogre::Ray localRay(q.Inverse() 
            * (ray.getOrigin() - pPostion) / pScale,(q.Inverse() * ray.getDirection() / pScale).normalisedCopy());

                
            bool added_shared = false;
                size_t current_offset 
            = 0;
                size_t shared_offset 
            = 0;
                size_t next_offset 
            = 0;
                size_t index_offset 
            = 0;

                std::pair
            <bool, Ogre::Real> hit(false0);    
                Ogre::MeshPtr mesh 
            = entity->getMesh();

                
            bool useSoftwareBlendingVertices = entity->hasSkeleton();

                
            if (useSoftwareBlendingVertices)
                {
                    entity
            ->_updateAnimation();
                }
                added_shared 
            = false;

                
            // Run through the submeshes again, adding the data into the arrays
                for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
                {
                    Ogre::SubMesh
            * submesh = mesh->getSubMesh(i);
                    
            //----------------------------------------------------------------
                    
            // GET VERTEXDATA
                    
            //----------------------------------------------------------------
                    Ogre::VertexData* vertex_data;

                    
            if(useSoftwareBlendingVertices)
                        vertex_data 
            = submesh->useSharedVertices ? entity->_getSkelAnimVertexData() : entity->getSubEntity(i)->_getSkelAnimVertexData();
                    
            else
                        vertex_data 
            = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;


                    
            if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
                    {
                        
            if(submesh->useSharedVertices)
                        {
                            added_shared 
            = true;
                        }
                    }
                    
            //////////////////////////////////////////////////////////////////////////Vertex
                    const Ogre::VertexElement* posElem =
                        vertex_data
            ->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

                    Ogre::HardwareVertexBufferSharedPtr vbuf 
            =
                        vertex_data
            ->vertexBufferBinding->getBuffer(posElem->getSource());

                    unsigned 
            char* vertex =
                        static_cast
            <unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
                    
            //////////////////////////////////////////////////////////////////////////Index
                    Ogre::IndexData* index_data = submesh->indexData;
                    size_t numTris 
            = index_data->indexCount / 3;
                    Ogre::HardwareIndexBufferSharedPtr ibuf 
            = index_data->indexBuffer;
                    
            bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
                    unsigned 
            long*  pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
                    unsigned 
            short* pShort = reinterpret_cast<unsigned short*>(pLong);

                    size_t offset 
            = (submesh->useSharedVertices)? shared_offset : current_offset;
                    size_t index_start 
            = index_data->indexStart;
                    size_t last_index 
            = numTris * 3 + index_start;
                    
            float *pReal0, *pReal1, *pReal2;
                    Ogre::Vector3 pVector30, pVector31,pVector32;

                    
            if (use32bitindexes)
                    {
                        
            for (size_t k = index_start; k < last_index;)
                        {                            
                            posElem
            ->baseVertexPointerToElement(vertex + (pLong[k] + static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal0);
                            pVector30.x 
            = pReal0[0];
                            pVector30.y 
            = pReal0[1];
                            pVector30.z 
            = pReal0[2];
                            posElem
            ->baseVertexPointerToElement(vertex + (pLong[k + 1+ static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal1);
                            pVector31.x 
            = pReal1[0];
                            pVector31.y 
            = pReal1[1];
                            pVector31.z 
            = pReal1[2];
                            posElem
            ->baseVertexPointerToElement(vertex + (pLong[k + 2+ static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal2);
                            pVector32.x 
            = pReal2[0];
                            pVector32.y 
            = pReal2[1];
                            pVector32.z 
            = pReal2[2];

                            hit 
            = Ogre::Math::intersects(localRay, pVector30,pVector31,pVector32, truefalse);
                            
            if (hit.first)
                            {
                                
            //parentOrientation * (parentScale * mPosition);
                                hit = Ogre::Math::intersects(ray, q *(pVector30 * pScale) + pPostion ,q *(pVector31 * pScale) + pPostion, q *(pVector32 * pScale) + pPostion, truefalse);
                                
            if (hit.first) break;
                            }
                            
            //
                            k+=3;
                        }                        
                    }
                    
            else
                    {
                        
            for (size_t k = index_start; k < last_index;)
                        {
                            posElem
            ->baseVertexPointerToElement(vertex + (static_cast<unsigned long>( pShort[k] ) + static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal0);
                            pVector30.x 
            = pReal0[0];
                            pVector30.y 
            = pReal0[1];
                            pVector30.z 
            = pReal0[2];
                            posElem
            ->baseVertexPointerToElement(vertex + (static_cast<unsigned long>( pShort[k + 1] ) + static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal1);
                            pVector31.x 
            = pReal1[0];
                            pVector31.y 
            = pReal1[1];
                            pVector31.z 
            = pReal1[2];
                            posElem
            ->baseVertexPointerToElement(vertex + (static_cast<unsigned long>( pShort[k + 2] ) + static_cast<unsigned long>( offset )) * vbuf->getVertexSize(), &pReal2);
                            pVector32.x 
            = pReal2[0];
                            pVector32.y 
            = pReal2[1];
                            pVector32.z 
            = pReal2[2];
                            hit 
            = Ogre::Math::intersects(localRay, pVector30,pVector31,pVector32, truefalse);
                            
            if (hit.first)
                            {
                                hit 
            = Ogre::Math::intersects(ray, q *(pVector30 * pScale) + pPostion ,q *(pVector31 * pScale) + pPostion, q *(pVector32 * pScale) + pPostion, truefalse);
                                
            if (hit.first) break;
                            }
                            k
            +=3;
                        }
                    }                    
                    ibuf
            ->unlock();                
                    vbuf
            ->unlock();
                }
                
            return hit;
            }

            久久伊人五月天论坛| 亚洲国产精品无码久久九九| 国产V亚洲V天堂无码久久久| 99久久成人国产精品免费| 国产成人久久777777| 久久人人爽人人爽人人片AV东京热| 囯产精品久久久久久久久蜜桃| 日韩人妻无码精品久久免费一| 成人国内精品久久久久影院VR| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久久亚洲AV波多野结衣| 亚洲av日韩精品久久久久久a| 久久99精品国产| 精品久久久久久久国产潘金莲 | 亚洲人成电影网站久久| 久久国产精品久久精品国产| 国内精品伊人久久久久网站| 老色鬼久久亚洲AV综合| 久久久久99精品成人片| 久久亚洲国产午夜精品理论片| 中文字幕精品久久| 久久精品国产亚洲7777| 久久国产高潮流白浆免费观看| 欧美一级久久久久久久大片| 99久久综合国产精品二区| 日产精品久久久一区二区| 一级a性色生活片久久无少妇一级婬片免费放 | 欧美一区二区三区久久综| 久久精品国产亚洲7777| 99久久精品国产毛片| 国产精品久久久久久福利漫画| 精品久久久久久中文字幕大豆网| 久久久久18| 日韩十八禁一区二区久久| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久人人爽人人爽人人片AV东京热 | 狠狠综合久久综合88亚洲| 国内精品伊人久久久久妇| 久久国内免费视频| 久久精品aⅴ无码中文字字幕不卡 久久精品成人欧美大片 | 国内精品久久久久影院一蜜桃|