• <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 點點滴滴 閱讀(551) 評論(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;
            }

            国内精品久久久久久99| 日本久久中文字幕| 狠狠色噜噜狠狠狠狠狠色综合久久| 久久婷婷五月综合色奶水99啪| 久久久久亚洲AV无码麻豆| 久久se精品一区二区| 久久久久久久久久免免费精品| 综合人妻久久一区二区精品| 97久久超碰国产精品2021| 久久这里有精品视频| 波多野结衣中文字幕久久| 天天影视色香欲综合久久| 99久久99久久久精品齐齐| 少妇久久久久久被弄到高潮| AV无码久久久久不卡蜜桃| 亚洲伊人久久综合中文成人网| 国产精品一区二区久久不卡| 99久久这里只精品国产免费| 久久精品一区二区三区不卡| 久久精品中文字幕一区| 国产成人无码精品久久久久免费 | 久久久久国产一级毛片高清版| 精品多毛少妇人妻AV免费久久| 亚洲精品乱码久久久久久自慰| 国产成人无码精品久久久久免费| 日产精品久久久久久久| 久久婷婷五月综合97色直播| 国産精品久久久久久久| 青青青青久久精品国产| 久久精品a亚洲国产v高清不卡| 久久久久久伊人高潮影院| 中文字幕亚洲综合久久菠萝蜜| 国产精品综合久久第一页| 国产一久久香蕉国产线看观看 | 无码久久精品国产亚洲Av影片| 欧洲性大片xxxxx久久久| 国产精品99久久久久久猫咪| 一级做a爰片久久毛片人呢| 久久久青草久久久青草| 久久这里只精品国产99热| 国产精品成人久久久久三级午夜电影|