コード例 #1
0
bool KRTriangle3::containsPoint(const KRVector3 &p) const
{
    /*
    // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle
    
    const float SMALL_NUM = 0.00000001f;     // anything that avoids division overflow
    // KRVector3 A = m_c[0], B = m_c[1], C = m_c[2];
    if (_sameSide(p, m_c[0], m_c[1], m_c[2]) && _sameSide(p, m_c[1], m_c[0], m_c[2]) && _sameSide(p, m_c[2], m_c[0], m_c[1])) {
        KRVector3 vc1 = KRVector3::Cross(m_c[0] - m_c[1], m_c[0] - m_c[2]);
        if(fabs(KRVector3::Dot(m_c[0] - p, vc1)) <= SMALL_NUM) {
            return true;
        }
    }
    
    return false;
    */
    
    // From: http://blogs.msdn.com/b/rezanour/archive/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests.aspx
    
    KRVector3 A = m_c[0];
    KRVector3 B = m_c[1];
    KRVector3 C = m_c[2];
    KRVector3 P = p;
    
    // Prepare our barycentric variables
    KRVector3 u = B - A;
    KRVector3 v = C - A;
    KRVector3 w = P - A;
    
    KRVector3 vCrossW = KRVector3::Cross(v, w);
    KRVector3 vCrossU = KRVector3::Cross(v, u);
    
    // Test sign of r
    if (KRVector3::Dot(vCrossW, vCrossU) < 0)
        return false;
    
    KRVector3 uCrossW = KRVector3::Cross(u, w);
    KRVector3 uCrossV = KRVector3::Cross(u, v);
    
    // Test sign of t
    if (KRVector3::Dot(uCrossW, uCrossV) < 0)
        return false;
    
    // At this point, we know that r and t and both > 0.
    // Therefore, as long as their sum is <= 1, each must be less <= 1
    float denom = uCrossV.magnitude();
    float r = vCrossW.magnitude() / denom;
    float t = uCrossW.magnitude() / denom;
    
    return (r + t <= 1);
}
コード例 #2
0
bool _intersectSphere(const KRVector3 &start, const KRVector3 &dir, const KRVector3 &sphere_center, float sphere_radius, float &distance)
{
    // dir must be normalized

    // From: http://archive.gamedev.net/archive/reference/articles/article1026.html
    
    // TODO - Move to another class?
    KRVector3 Q = sphere_center - start;
    float c = Q.magnitude();
    float v = KRVector3::Dot(Q, dir);
    float d = sphere_radius * sphere_radius - (c * c - v * v);
    

    
    if(d < 0.0) {
        // No intersection
        return false;
    }
    
    // Return the distance to the [first] intersecting point
    
    distance = v - sqrt(d);
    if(distance < 0.0f) {
        return false;
    }
    return true;

}