[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//
//  Project:   Talina Gaming System (TgS) (∂)
//  File:      TgS Collision - Box-Box.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 ///////////////////////////////////////////////////////////////////////////////////////////////////////

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

// ---- F_Axis_Seperation ------------------------------------------------------------------------------------------------------- //
// Input:  tgBX0, tgBX1: Box primitives
// Output: tgAxS: Structure holds the resulting axis separation information necessary to create a contact set.
// Return: False if a separating axis exists, true otherwise
// ------------------------------------------------------------------------------------------------------------------------------ //

template <typename TYPE, int DIM>
TgBOOL F_Axis_Seperation( PC_(AXIS_RESULT,DIM) ptgAxS, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 )
{
    TYPE                                tyMinBox0, tyMaxBox0, tyMinBox1, tyMaxBox1;
    TgBOOL                              bUseAxis[3] = { TgTRUE, TgTRUE, TgTRUE };

    // -- Axis: Box Face/Plane Normals -------------------------

    for (TgUINT iIndex = 0; iIndex < 3; ++iIndex)
    {
        // Determine the extents of the primitives along the chosen axis.

        C_(VECTOR,DIM)                      &tvAxisUnit0 = tgBX0.Query_AxisUnit( iIndex );
        const TYPE                          tyB0_AU = MATH::F_DOT( tgBX0.Query_Origin(), tvAxisUnit0 );

        tyMinBox0 = tyB0_AU - tgBX0.Query_Extent( iIndex );
        tyMaxBox0 = tyB0_AU + tgBX0.Query_Extent( iIndex );
        tgBX1.Project( &tyMinBox1, &tyMaxBox1, tvAxisUnit0 );

        if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test.
        {
            return (TgFALSE);
        };

        {   // Selection of the best (minimal depth) axis.
            const TYPE                          tyMinDepth = tyMaxBox1 - tyMinBox0;
            const TYPE                          tyMaxDepth = tyMaxBox0 - tyMinBox1;
            C_TgBOOL                            bNegAxis = tyMinDepth > tyMaxDepth;

            if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth)
            {
                ptgAxS->m_tvNormal = bNegAxis ? tvAxisUnit0 : MATH::F_NEG( tvAxisUnit0 );
                ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth;
                ptgAxS->m_iAxis = bNegAxis ? iIndex + 3 : iIndex;
            };
        };

        //  Check this unit axis of box 0 against the three axis of box 1.  If there is a match then we mark this axis to
        // be ignored during the cross product phase.

        if (
            Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit0(), tvAxisUnit0 ) ) ||
            Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit1(), tvAxisUnit0 ) ) ||
            Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit2(), tvAxisUnit0 ) )
        ) {
            bUseAxis[iIndex] = TgFALSE;
        };

        // Determine the extents of the primitives along the chosen axis.

        C_(VECTOR,DIM)                      &tvAxisUnit1 = tgBX1.Query_AxisUnit( iIndex );
        const TYPE                          tyB1_AU = MATH::F_DOT( tgBX1.Query_Origin(), tvAxisUnit1 );

        tgBX0.Project( &tyMinBox0, &tyMaxBox0, tvAxisUnit1  );
        tyMinBox1 = tyB1_AU - tgBX1.Query_Extent( iIndex );
        tyMaxBox1 = tyB1_AU + tgBX1.Query_Extent( iIndex );

        if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test.
        {
            return (TgFALSE);
        };

        {   // Selection of the best (minimal depth) axis.
            const TYPE                          tyMinDepth = tyMaxBox1 - tyMinBox0;
            const TYPE                          tyMaxDepth = tyMaxBox0 - tyMinBox1;
            C_TgBOOL                            bNegAxis = tyMinDepth > tyMaxDepth;

            if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth)
            {
                ptgAxS->m_tvNormal = bNegAxis ? tvAxisUnit1 : MATH::F_NEG( tvAxisUnit1 );
                ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth;
                ptgAxS->m_iAxis = bNegAxis ? iIndex + 9 : iIndex + 6;
            };
        };
    };

    // -- Axis: Axis-Box Cross Product -------------------------

    for (TgUINT iBox0 = 0; iBox0 < 3; ++iBox0)
    {
        if (!bUseAxis[iBox0])
        {
            continue;
        };

        for (TgUINT iBox1 = 0; iBox1 < 3; ++iBox1)
        {
            // Axis is created by taking the cross product of the triangle edge and a box axis.

            T_(VECTOR,DIM)                      tvAxis;

            const TYPE tyAxis = MATH::F_UCX( &tvAxis, tgBX1.Query_AxisUnit( iBox1 ), tgBX0.Query_AxisUnit( iBox0 ) );

            if (Near_Zero( tyAxis )) //« Sanity/Parallel check for the resulting vector.
            {
                continue;
            };

            tgBX0.Project( &tyMinBox0, &tyMaxBox0, tvAxis  );
            tgBX1.Project( &tyMinBox1, &tyMaxBox1, tvAxis  );

            if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test.
            {
                return (TgFALSE);
            };

            // Selection of the best (minimal depth) axis.

            const TYPE                          tyMinDepth = tyMaxBox1 - tyMinBox0;
            const TYPE                          tyMaxDepth = tyMaxBox0 - tyMinBox1;
            C_TgBOOL                            bNegAxis = tyMinDepth > tyMaxDepth;

            if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth)
            {
                ptgAxS->m_tvNormal = bNegAxis ? tvAxis : MATH::F_NEG( tvAxis );
                ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth;
                ptgAxS->m_iAxis = iBox0*3 + iBox1 + (bNegAxis ? 21 : 12);
            };
        };
    };

    return (TgTRUE);
};

template TgBOOL F_Axis_Seperation( PC_TgF4AXIS_RESULT, CR_TgF4BOX, CR_TgF4BOX );


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

// ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------------------------------------------------------ //

template <typename TYPE, int DIM>
TgRESULT F_Contact_Penetrate_BoxAxis1( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(AXIS_RESULT,DIM) tgAxS, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 )
{
    TTgAXIS_PROJECT<TYPE,DIM>           tgConfig;

    F_Axis_ProjInfo( &tgConfig, tgAxS.m_tvNormal, tgBX0 );

    switch (tgConfig.m_niMinDepth)
    {
        case 1: { //« Vertex-Face Contact

            //C_(VECTOR,DIM)                      &tvP0 = tgConfig.m_atvMinVert[0];
            return (TgS_OK);
        };
        case 2: { //« Edge-Face Contact

            return (TgS_OK);
        };
        case 4: { //« Face-Face Contact

            return (TgS_OK);
        };
        default:
            TgASSERT(TgFALSE);
            return (TgE_FAIL);
    };

    return (TgE_FAIL);
};

template TgRESULT F_Contact_Penetrate_BoxAxis1( PC_TgF4CONTACT_PACKET, CR_TgF4AXIS_RESULT, CR_TgF4BOX, CR_TgF4BOX );


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

// ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- //
// Input:  tgPacket: The current series of contact points for this query-series, and contact generation parameters.
// Input:  tgBX0: Box primitive
// Input:  tgBX1: Box - contact points are generated on this primitive
// Output: tgPacket: Points of penetration between the two primitives are added to it
// Return: Result Code
// ------------------------------------------------------------------------------------------------------------------------------ //

//template <typename TYPE, int DIM>
//C_TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 )
//{
//    TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgBOX<<16)|(TgUINT)ETgBOX))
//
//    TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) ))
//    TgASSERT(tgBX0.Is_Valid() && tgBX1.Is_Valid())
//
//    if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact)
//    {
//        return (TgE_FAIL);
//    };
//
//    // Find the minimal axis of separation, or return if the primitives are not in contact.
//
//    TTgAXIS_RESULT<TYPE,DIM>            tgAxS;
//
//    if (!F_Axis_Seperation( tgAxS, tgBX0,tgBX1 ))
//    {
//        return (TgE_NOINTERSECT);
//    };
//
//    TgASSERT( Near_One( MATH::F_LSQ(tgAxS.tvNormal) ) && tgAxS.tyDepth >= TYPE(0.0) )
//
//    // == Contact Generation ==================================================================================================== //
//
//    C_TgINT                             niContact = ptgPacket->m_niContact;
//    P_(CONTACT,DIM)                     ptgContact;
//
//    if (tgAxS.iAxis >= 12)
//    {
//    }
//    else
//    {
//        if (tgAxS.iAxis >= 6)
//        {
//            return (F_Contact_Penetrate_BoxAxis(  ));
//        }
//        else
//        {
//            return (F_Contact_Penetrate_BoxAxis(  ));
//        };
//    };
//
//
//
//
//    return (TgE_FAIL);
//};
//
//template TgRESULT F_Contact_Penetrate( R_TgF4CONTACT_PACKET, CR_TgF4BOX, CR_TgF4BOX );

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

}; // END COL //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[an error occurred while processing this directive]