// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//
//  Project:   Talina Gaming System (TgS) (∂)
//  File:      TgS Collision - Box AA-Linear.cpp
//  Author:    Andrew Aye (EMail: andrew.aye@gmail.com, Web: http://www.andrewaye.com) 
//  Version:   3.11
//
// ------------------------------------------------------------------------------------------------------------------------------ //
//
//  Copyright: © 2002-2008, Andrew Aye.  All Rights Reserved.
//
//  This software is free for non-commercial use. Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met: 
//    Redistributions of source code must retain this copyright notice, this list of conditions and the following disclaimers. 
//    Redistributions in binary form must reproduce this copyright notice, this list of conditions and the following
//      disclaimers in the documentation and other materials provided with the distribution. 
//
//  Neither the names of the copyright owner nor the names of its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission. 
//
//  The intellectual property rights of the algorithms used reside with Andrew Aye.  You may not use this software, in whole or
//  in part, in support of any commercial product without the express written consent of the author.
//
//  There is no warranty or other guarantee of fitness of this software for any purpose. It is provided solely "as is".
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //




namespace TGS { // START TGS ///////////////////////////////////////////////////////////////////////////////////////////////////////
namespace COL { // START COL ///////////////////////////////////////////////////////////////////////////////////////////////////////

// ============================================================================================================================== //

// ---- TTgTST_BALN ------------------------------------------------------------------------------------------------------------- //
//  -- Internal Function -- bC0, bC1 : Indicate the termination condition of the linear {bc0,bC1}
//
// Input:  tgBA0: Box, Axis-Aligned primitive
// Input:  tvS0,tvD0: Origin and Direction for Linear
// Return: True if the two primitives are in contact, false otherwise.
// ------------------------------------------------------------------------------------------------------------------------------ //

template <typename TYPE, int DIM, bool bC0, bool bC1>
TgBOOL TTgTST_BALN<TYPE,DIM,bC0,bC1>::DO( CR_(BOXAA,DIM) tgBA0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0 )
{
    TgASSERT(tgBA0.Is_Valid() && MATH::F_Is_Point_Valid( tvS0 ) && MATH::F_Is_Vector_Valid( tvD0 ))

    TYPE                                tyT0,tyT1, tyMinT,tyMaxT, tyMinTX,tyMaxTX, tyMinTY,tyMaxTY, tyMinTZ,tyMaxTZ;

    tyT0 = (tgBA0.Query_MinX() - tvS0.X()) / tvD0.X();
    tyT1 = (tgBA0.Query_MinX() - tvS0.X()) / tvD0.X();
    tyMinTX = P::FSEL( tyT1 - tyT0, tyT0, tyT1 );
    tyMaxTX = P::FSEL( tyT1 - tyT0, tyT1, tyT0 );

    tyT0 = (tgBA0.Query_MinY() - tvS0.Y()) / tvD0.Y();
    tyT1 = (tgBA0.Query_MinY() - tvS0.Y()) / tvD0.Y();
    tyMinTY = P::FSEL( tyT1 - tyT0, tyT0, tyT1 );
    tyMaxTY = P::FSEL( tyT1 - tyT0, tyT1, tyT0 );

    tyMinT = P::FSEL( tyMinTX - tyMinTY, tyMinTY, tyMinTX );
    tyMaxT = P::FSEL( tyMaxTX - tyMaxTY, tyMaxTX, tyMaxTY );

    tyT0 = (tgBA0.Query_MinZ() - tvS0.Z()) / tvD0.Z();
    tyT1 = (tgBA0.Query_MinZ() - tvS0.Z()) / tvD0.Z();
    tyMinTZ = P::FSEL( tyT1 - tyT0, tyT0, tyT1 );
    tyMaxTZ = P::FSEL( tyT1 - tyT0, tyT1, tyT0 );

    tyMinT = P::FSEL( tyMinTZ - tyMinT, tyMinTZ, tyMinT );
    tyMaxT = P::FSEL( tyMaxTZ - tyMaxT, tyMaxT, tyMaxTZ );

    if (!bC0 && !bC1) //« Check to see if the line overlaps the AABB
    {
        return (tyMinT < tyMaxT);
    }

    if (bC0 && !bC1) //« Check to see if the ray overlaps the AABB and is directed away from it.
    {
        return (tyMinT < tyMaxT && tyMaxT > TYPE(0.0));
    };

    if (bC0 && bC1) //« Check to see if the segment overlaps the AABB
    {
        return (tyMinT < tyMaxT && (tyMaxT > TYPE(0.0) && tyMinT < TYPE(1.0)));
    };

    return (TgFALSE);
};


// ============================================================================================================================== //

    template struct TTgTST_BALN<TgFLOAT32,4,0,0>;
    template struct TTgTST_BALN<TgFLOAT32,4,1,0>;
    template struct TTgTST_BALN<TgFLOAT32,4,1,1>;

// ============================================================================================================================== //

}; // END COL //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////