예제 #1
0
bool ray4::hitsTriangle(const float4 *points, float &length) const
{
    const float4 p0p1(points[1] - points[0]);
    const float4 p0p2(points[2] - points[0]);

    const float4 normal = float4(p0p1.cross(p0p2));

    //	n * p = n * (s + t*d) = n*s + n*d*t
    //	n(p-s) = ndt
    //	(n(p-s))/(n*d) = t

    float4 dir = direction();
    float4 outFactor = float4(-1.0f);

    float4 normalTimesDirection = normal.prod(dir);

    outFactor = (normalTimesDirection != float4(0.0f)).select(normal.prod(points[0] - start()) / normalTimesDirection, outFactor);

    if((outFactor < float4(0.0f)).all())
        return false;
    if(outFactor.max() > 1.0f)
        return false;

    const float4 location = this->point(outFactor.max());

    length = outFactor.max();

    return location.isOnTriangle(points);
}
예제 #2
0
bool float4::isOnTriangle(const float4 *points) const
{
    const float4 zero(0.0f);
    const float4 one(1.0f);

    const float4 p0p1(points[1] - points[0]);
    const float4 p0p2(points[2] - points[0]);

    const float4 normal(p0p1.cross(p0p2));
    if(std::abs((normal * *this) - (normal * points[0])) >= 0.001f)
        return false;

    const float4 p0hp(*this - points[0]);

    //	dot00 = dot(v0, v0)
    //	dot01 = dot(v0, v1)
    //	dot02 = dot(v0, v2)
    //	dot11 = dot(v1, v1)
    //	dot12 = dot(v1, v2)
    //
    //	// Compute barycentric coordinates
    //	invDenom = 1 / (dot00 * dot11 - dot01 * dot01)
    //	u = (dot11 * dot02 - dot01 * dot12) * invDenom
    //	v = (dot00 * dot12 - dot01 * dot02) * invDenom
    //
    //	// Check if point is in triangle
    //	return (u > 0) && (v > 0) && (u + v < 1)

    const float4 dot00(p0p1.vdot(p0p1));
    const float4 dot01(p0p1.vdot(p0p2));
    const float4 dot02(p0p1.vdot(p0hp));
    const float4 dot11(p0p2.vdot(p0p2));
    const float4 dot12(p0p2.vdot(p0hp));

    const float4 invDenom = one / (dot00.prod(dot11) - dot01.prod(dot01));
    const float4 u = (dot11.prod(dot02) - dot01.prod(dot12)).prod(invDenom);
    const float4 v = (dot00.prod(dot12) - dot01.prod(dot02)).prod(invDenom);

    return (u >= zero).all() && (v >= zero).all() && (u + v <= one).all();
}