多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 射線檢測算法在游戲中應用

射線檢測算法在游戲中應用

來源:程序員人生   發布時間:2017-02-04 09:36:28 閱讀次數:5827次

筆者介紹:姜雪偉IT公司技術合伙人,IT高級講師,CSDN社區專家,特邀編輯,暢銷書作者,國家專利發明人;已出版書籍:《手把手教你架構3D游戲引擎》電子工業出版社和《Unity3D實戰核心技術詳解》電子工業出版社等。

 射線檢測在游戲中使用的非常廣泛,我們利用射線開發時,開發者只是調用引擎的接口便可實現,但是我們要了解其內部實現原理,這樣我們也能夠自己封裝射線檢測算法,射線檢測算法利用程度非常高,不論是使用鼠標還是觸摸屏,都需要用到射線檢測,比如在虛擬仿真中,導彈追蹤物體時,它需要通過從導彈上發出的射線1直朝向物體,角色尋路也能夠通過在身體發出的射線檢測與物體本身的碰撞盒接觸后,用于查看物體是不是產生了碰撞。射線檢測還用于對物體身上的材質處理,比如墻體的遮擋關系,使用攝像機發出的射線方向指向角色,如果它們之間的射線檢測到物體比如墻體,可以編寫邏輯改變角色的材質進行透明處理,效果以下圖所示:



固然我們也能夠使用對墻體進行透明設置,這也是1種處理方式,是將墻體進行透明設置效果以下圖所示:


其在程序中表現的效果以下所示:



從相機發出兩條射線,射線與墻體的碰撞體產生接觸,程序會改變墻體的Shader,替換其材質,讓其透明。以下是Unity3D引擎使用案例,核心代碼以下所示:

 if (Physics.Linecast(pos, transform.position, out hit))
            {
                last_obj = hit.collider.gameObject;
                int length = last_obj.transform.childCount;
                string name_tag = last_obj.tag;

                if (name_tag == "wall")
                {
                    Material mat = new Material(Shader.Find("Transparent/Diffuse"));

                    curr_obj = last_obj;
                    for (int i = 0; i < length; i++)
                    {
                        Transform child = last_obj.transform.GetChild(i);
                        child.GetComponent<Renderer>().material = mat;
                        mat.mainTexture = (Texture)Resources.Load("Atlas/test_pub_tm");
                    }

                }  
}

射線也能夠用于物體的拾取操作,拾取物體時從觸摸點發出1條射線與要拾取的物體的包圍盒產生碰撞,表示物體被拾取到。

下面給開發者介紹1下,射線碰撞的原理,把1個物體放到場景中做了1個局部坐標到世界坐標變換,效果以下圖所示:


將物體投影后,假定紅的表示X軸,綠的表示Y軸,中間表示物體的碰撞盒,1條射線穿過后效果以下所示:


射線穿過我們要計算其是不是與碰撞盒產生碰撞,主要是通過射線與碰撞盒相交值的大小進行判斷,效果以下圖所示:


射線與碰撞體產生碰撞后的判定效果圖以下所示:



根據以上的判斷我們可以寫下代碼,對3D物體,我們要分別判斷X,Y,Z3個軸。核心代碼以下所示:

bool TestRayOBBIntersection(
    glm::vec3 ray_origin,        // Ray origin, in world space
    glm::vec3 ray_direction,     // Ray direction (NOT target position!), in world space. Must be normalize()'d.
    glm::vec3 aabb_min,          // Minimum X,Y,Z coords of the mesh when not transformed at all.
    glm::vec3 aabb_max,          // Maximum X,Y,Z coords. Often aabb_min*⑴ if your mesh is centered, but it's not always the case.
    glm::mat4 ModelMatrix,       // Transformation applied to the mesh (which will thus be also applied to its bounding box)
    float& intersection_distance // Output : distance between ray_origin and the intersection with the OBB
){

    // Intersection method from Real-Time Rendering and Essential Mathematics for Games

    float tMin = 0.0f;
    float tMax = 100000.0f;

    glm::vec3 OBBposition_worldspace(ModelMatrix[3].x, ModelMatrix[3].y, ModelMatrix[3].z);

    glm::vec3 delta = OBBposition_worldspace - ray_origin;

    // Test intersection with the 2 planes perpendicular to the OBB's X axis
    {
        glm::vec3 xaxis(ModelMatrix[0].x, ModelMatrix[0].y, ModelMatrix[0].z);
        float e = glm::dot(xaxis, delta);
        float f = glm::dot(ray_direction, xaxis);

        if ( fabs(f) > 0.001f ){ // Standard case

            float t1 = (e+aabb_min.x)/f; // Intersection with the "left" plane
            float t2 = (e+aabb_max.x)/f; // Intersection with the "right" plane
            // t1 and t2 now contain distances betwen ray origin and ray-plane intersections

            // We want t1 to represent the nearest intersection, 
            // so if it's not the case, invert t1 and t2
            if (t1>t2){
                float w=t1;t1=t2;t2=w; // swap t1 and t2
            }

            // tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs)
            if ( t2 < tMax )
                tMax = t2;
            // tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs)
            if ( t1 > tMin )
                tMin = t1;

            // And here's the trick :
            // If "far" is closer than "near", then there is NO intersection.
            // See the images in the tutorials for the visual explanation.
            if (tMax < tMin )
                return false;

        }else{ // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection"
            if(-e+aabb_min.x > 0.0f || -e+aabb_max.x < 0.0f)
                return false;
        }
    }


    // Test intersection with the 2 planes perpendicular to the OBB's Y axis
    // Exactly the same thing than above.
    {
        glm::vec3 yaxis(ModelMatrix[1].x, ModelMatrix[1].y, ModelMatrix[1].z);
        float e = glm::dot(yaxis, delta);
        float f = glm::dot(ray_direction, yaxis);

        if ( fabs(f) > 0.001f ){

            float t1 = (e+aabb_min.y)/f;
            float t2 = (e+aabb_max.y)/f;

            if (t1>t2){float w=t1;t1=t2;t2=w;}

            if ( t2 < tMax )
                tMax = t2;
            if ( t1 > tMin )
                tMin = t1;
            if (tMin > tMax)
                return false;

        }else{
            if(-e+aabb_min.y > 0.0f || -e+aabb_max.y < 0.0f)
                return false;
        }
    }


    // Test intersection with the 2 planes perpendicular to the OBB's Z axis
    // Exactly the same thing than above.
    {
        glm::vec3 zaxis(ModelMatrix[2].x, ModelMatrix[2].y, ModelMatrix[2].z);
        float e = glm::dot(zaxis, delta);
        float f = glm::dot(ray_direction, zaxis);

        if ( fabs(f) > 0.001f ){

            float t1 = (e+aabb_min.z)/f;
            float t2 = (e+aabb_max.z)/f;

            if (t1>t2){float w=t1;t1=t2;t2=w;}

            if ( t2 < tMax )
                tMax = t2;
            if ( t1 > tMin )
                tMin = t1;
            if (tMin > tMax)
                return false;

        }else{
            if(-e+aabb_min.z > 0.0f || -e+aabb_max.z < 0.0f)
                return false;
        }
    }

    intersection_distance = tMin;
    return true;

}

射線與碰撞盒的判定就結束了,雖然市面上的各個引擎都提供了接口,我們可以直接使用,但是如果我們能明白其原理,更有助于我們理解射線碰撞算法。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 午夜色综合| 另类小说图片 | 亚洲精品第一区二区三区 | 久久久精品456亚洲影院 | 羞羞动漫网页 | 中文字幕成人 | 欧美高清成人videosex | 欧美xxxx极品流血 | 毛片网站大全 | 男人懂的网站 | 美国一级毛片视频 | 欧美另类在线观看 | jizz中文字幕 | 日本free护士videosxxxx动漫 | 日本一区二区三区免费看 | 中文字幕一区二区三区有限公司 | 一级毛片在线完整观看 | 色哟哟tv | 亚洲最新| 亚洲 欧美 自拍 另类 | 又黄又爽又色的性视频 | 日本xxxxx黄区免费看动漫 | 国产九九免费视频网站 | 日本欧美在线观看 | 最新亚洲 | 亚洲一本之道在线观看不卡 | 欧美一级网站 | 成年人视频在线免费观看 | 日韩精品综合 | 手机看片福利日韩国产 | 亚洲v天堂 | 日本免费不卡视频一区二区三区 | 一二三四视频中文字幕在线看 | 亚洲校园春色小说 | 亚洲色图日韩 | 在线观看h视频播放高清 | 国产jlzzjlzz视频免费 | 欧美一区二区三区不卡 | 欧美a级v片不卡在线观看 | 日本大片aa特黄 | 欧美一级久久久久久久大 |