關於DirectX中三角形檢測代碼的解釋


bool IntersectTriangle(const D3DXVECTOR3& orig, const D3DXVECTOR3& dir,
    D3DXVECTOR3& v0, D3DXVECTOR3& v1, D3DXVECTOR3& v2, FLOAT* t, FLOAT* u, FLOAT* v) { // Find vectors for two edges sharing vert0 D3DXVECTOR3 edge1 = v1 - v0; D3DXVECTOR3 edge2 = v2 - v0; // Begin calculating determinant - also used to calculate U parameter  D3DXVECTOR3 pvec; D3DXVec3Cross(&pvec, &dir, &edge2); // If determinant is near zero, ray lies in plane of triangle FLOAT det = D3DXVec3Dot(&edge1, &pvec); D3DXVECTOR3 tvec; if (det > 0) { tvec = orig - v0; } else { tvec = v0 - orig; det = -det; } if (det < 0.0001f) return FALSE; // Calculate U parameter and test bounds *u = D3DXVec3Dot(&tvec, &pvec); if (*u < 0.0f || *u > det) return FALSE; // Prepare to test V parameter  D3DXVECTOR3 qvec; D3DXVec3Cross(&qvec, &tvec, &edge1); // Calculate V parameter and test bounds *v = D3DXVec3Dot(&dir, &qvec); if (*v < 0.0f || *u + *v > det) return FALSE; // Calculate t, scale parameters, ray intersects triangle *t = D3DXVec3Dot(&edge2, &qvec); FLOAT fInvDet = 1.0f / det; *t *= fInvDet; *u *= fInvDet; *v *= fInvDet; return TRUE; }

首先:我們來解釋一下理論上是如何計算的:

以上的理論部分很多大佬解釋了:

大部分代碼其實也很好理解,只有

if (det > 0)
    {
        tvec = orig - v0;
    }
    else
    {
        tvec = v0 - orig;
        det = -det;
    }
這一段可能有朋友會有跟我一樣的困惑,為什么這么處理?
我們求出的t其實也是一個限定條件,如果t小於o那么也是沒交點的。
這里的代碼則並沒有討論t,也就是說,這里對於T的調整是為了保證參數t是正的。
我們可以看到 DxE2*E1可以寫成E2xE1*D所以det大於0則說明 D的方向與E2xE1指向同一側,而t的正負號由【TE1E2】=【E1E2T】決定也就是說T必須要跟E1xE2在同一側,大家可以在腦海里想象一下,det大於0那么是不是就直接V0--》Orig,det小於0是不是就是Orig--》V0?
很明顯就是這樣的。簡而言之,demo里的那句調整T的代碼的作用就是在此。但是這個方法貌似不能檢測射線跟平面背對着的情況。不信你可以用最簡單的數據試一試,還是返回true的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM