Пример #1
0
kmBool kmRay3IntersectAABB3(const kmRay3* ray, const kmAABB3* aabb, kmVec3* intersection, kmScalar* distance) {
    //http://gamedev.stackexchange.com/a/18459/15125
    kmVec3 rdir, dirfrac, diff;
    kmVec3Normalize(&rdir, &ray->dir);
    kmVec3Fill(&dirfrac, 1.0 / rdir.x, 1.0 / rdir.y, 1.0 / rdir.z);

    kmScalar t1 = (aabb->min.x - ray->start.x) * dirfrac.x;
    kmScalar t2 = (aabb->max.x - ray->start.x) * dirfrac.x;
    kmScalar t3 = (aabb->min.y - ray->start.y) * dirfrac.y;
    kmScalar t4 = (aabb->max.y - ray->start.y) * dirfrac.y;
    kmScalar t5 = (aabb->min.z - ray->start.z) * dirfrac.z;
    kmScalar t6 = (aabb->max.z - ray->start.z) * dirfrac.z;

    kmScalar tmin = kmMax(kmMax(kmMin(t1, t2), kmMin(t3, t4)), kmMin(t5, t6));
    kmScalar tmax = kmMin(kmMin(kmMax(t1, t2), kmMax(t3, t4)), kmMax(t5, t6));

    // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behind us
    if(tmax < 0) {
        return KM_FALSE;
    }

    // if tmin > tmax, ray doesn't intersect AABB
    if (tmin > tmax) {
        return KM_FALSE;
    }

    if(distance) *distance = tmin;
    if(intersection) {
        kmVec3Scale(&diff, &rdir, tmin);
        kmVec3Add(intersection, &ray->start, &diff);
    }
    return KM_TRUE;
}
Пример #2
0
kmBool kmRay2IntersectLineSegment(const kmRay2* ray, const kmVec2* p1, const kmVec2* p2, kmVec2* intersection) {

    float x1 = ray->start.x;
    float y1 = ray->start.y;
    float x2 = ray->start.x + ray->dir.x;
    float y2 = ray->start.y + ray->dir.y;
    float x3 = p1->x;
    float y3 = p1->y;
    float x4 = p2->x;
    float y4 = p2->y;

    float denom = (y4 -y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
    float ua, x, y;
    //If denom is zero, the lines are parallel
    if(denom > -kmEpsilon && denom < kmEpsilon) {
        return KM_FALSE;
    }

    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
//    float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;

    x = x1 + ua * (x2 - x1);
    y = y1 + ua * (y2 - y1);

    if(x < kmMin(p1->x, p2->x) - kmEpsilon ||
       x > kmMax(p1->x, p2->x) + kmEpsilon ||
       y < kmMin(p1->y, p2->y) - kmEpsilon ||
       y > kmMax(p1->y, p2->y) + kmEpsilon) {
        //Outside of line
        //printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
        return KM_FALSE;
    }

    if(x < kmMin(x1, x2) - kmEpsilon ||
       x > kmMax(x1, x2) + kmEpsilon ||
       y < kmMin(y1, y2) - kmEpsilon ||
       y > kmMax(y1, y2) + kmEpsilon) {
        //printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
        return KM_FALSE;
    }

    intersection->x = x;
    intersection->y = y;

    return KM_TRUE;


/*
    kmScalar A1, B1, C1;
    kmScalar A2, B2, C2;

    A1 = ray->dir.y;
    B1 = ray->dir.x;
    C1 = A1 * ray->start.x + B1 * ray->start.y;

    A2 = p2->y - p1->y;
    B2 = p2->x - p1->x;
    C2 = A2 * p1->x + B2 * p1->y;

    double det = (A1 * B2) - (A2 * B1);
    if(det == 0) {
        printf("Parallel\n");
        return KM_FALSE;
    }

    double x = (B2*C1 - B1*C2) / det;
    double y = (A1*C2 - A2*C1) / det;

    if(x < min(p1->x, p2->x) - kmEpsilon ||
       x > max(p1->x, p2->x) + kmEpsilon ||
       y < min(p1->y, p2->y) - kmEpsilon ||
       y > max(p1->y, p2->y) + kmEpsilon) {
        //Outside of line
        printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1->x, p1->y, p2->x, p2->y);
        return KM_FALSE;
    }

    kmScalar x1 = ray->start.x;
    kmScalar x2 = ray->start.x + ray->dir.x;

    kmScalar y1 = ray->start.y;
    kmScalar y2 = ray->start.y + ray->dir.y;

    if(x < min(x1, x2) - kmEpsilon ||
       x > max(x1, x2) + kmEpsilon ||
       y < min(y1, y2) - kmEpsilon ||
       y > max(y1, y2) + kmEpsilon) {
        printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
        return KM_FALSE;
    }

    intersection->x = x;
    intersection->y = y;

    return KM_TRUE;*/
}