/* collide.c
 *
 * Collision code
 *
 * Created: 9/7/97
 */

/****  This version is full of bugs  ****/

#include "brender.h"

#include "bsp.h"
#include "collide.h"

br_scalar c_CompareVertexWithPlane(br_vector3 *v, br_vector4 *p)
{
    return v->v[0]*p->v[0]+v->v[1]*p->v[1]+v->v[2]*p->v[2]-p->v[3];
}

br_scalar c_CompareVertexWithTree(br_vector3 *v, c_bsp *root)
{
    br_scalar diff = c_CompareVertexWithPlane(v, &root->plane);

    if(diff < 0) {
        if(root->in)
            return c_CompareVertexWithTree(v, root->in);
        else
            return diff;
    } else {
        if(root->out)
            return c_CompareVertexWithTree(v, root->out);
        else
            return diff;
    }
}

br_scalar c_CompareLineWithTree(br_vector4 **plane, br_vector3 *v1,
                              br_vector3 *v2, c_bsp *root)
{
    br_scalar diff1 = c_CompareVertexWithPlane(v1, &root->plane),
              diff2 = c_CompareVertexWithPlane(v2, &root->plane);

    if(diff1 < 0 && diff2 < 0) {
        *plane = &root->plane;
        if(root->in)
            return c_CompareLineWithTree(plane, v1, v2, root->in);
        else
            return diff1;
    } else if(diff1 >= 0 && diff2 >= 0) {
        if(root->out)
            return c_CompareLineWithTree(plane, v1, v2, root->out);
        else
            return diff1;
    } else {
        br_vector3 v3;
        v3.v[0] = v2->v[0]+
            BR_DIV(BR_MUL((v1->v[0]-v2->v[0]), diff2), (diff2-diff1));
        v3.v[1] = v2->v[1]+
            BR_DIV(BR_MUL((v1->v[1]-v2->v[1]), diff2), (diff2-diff1));
        v3.v[2] = v2->v[2]+
            BR_DIV(BR_MUL((v1->v[2]-v2->v[2]), diff2), (diff2-diff1));

        if(diff1 < 0){
            if(root->in)
                diff1 = c_CompareLineWithTree(plane, v1, &v3, root->in);
            if(diff1 < 0)
                return diff1;
            else
                if(root->out)
                    return c_CompareLineWithTree(plane, &v3, v2, root->out);
                else
                    return diff2;
        } else {
            if(root->in)
                diff2 = c_CompareLineWithTree(plane, v2, &v3, root->in);
            if(diff2 < 0)
                return diff2;
            else
                if(root->out)
                    return c_CompareLineWithTree(plane, &v3, v1, root->out);
                else
                    return diff1;
        }
    }
}


