[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//
//  Project:   Talina Gaming System (TgS) (∂)
//  File:      TgS Collision - Box AA-Plane.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_Contact_Penetrate ----------------------------------------------------------------------------------------------------- //
// Input:  tgPacket: The current series of contact points for this query-series, and contact generation parameters.
// Input:  tgPN0: Plane Triangle primitive
// Input:  tgBA0: Box, Axis-Aligned primitive - 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>
TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(PLANE,DIM) tgPN0, CR_(BOXAA,DIM) tgBA0 )
{
    TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgPLANE<<16)|(TgUINT)ETgBOX))

    TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) ))
    TgASSERT(tgPN0.Is_Valid() && tgBA0.Is_Valid())

    if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact)
    {
        return (TgE_FAIL);
    };

    T_(VECTOR,DIM)                      tvBA0;

    tvBA0 = MATH::F_SETP<TYPE,DIM>(
        P::FSEL( tgPN0.Query_Normal().X(), tgBA0.Query_MinX(), tgBA0.Query_MaxX() ),
        P::FSEL( tgPN0.Query_Normal().Y(), tgBA0.Query_MinY(), tgBA0.Query_MaxY() ),
        P::FSEL( tgPN0.Query_Normal().Z(), tgBA0.Query_MinZ(), tgBA0.Query_MaxZ() )
    );
    const TYPE                          tyDist = F_Sign_Dist( tgPN0, tvBA0 );

    if (tyDist >= TYPE(0.0))
    {
        return (TgE_NOINTERSECT);
    };

    P_(CONTACT,DIM)                     ptgContact;

    ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);

    ptgContact->m_tvPos = tvBA0;
    ptgContact->m_tvNormal = tgPN0.Query_Normal();
    ptgContact->m_tyT0 = TYPE(0.0);
    ptgContact->m_tyDepth = -tyDist;

    ++ptgPacket->m_niContact;

    return (TgS_OK);
};

template TgRESULT F_Contact_Penetrate( PC_TgF4CONTACT_PACKET, CR_TgF4PLANE, CR_TgF4BOXAA );


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

// ---- F_Contact_Sweep --------------------------------------------------------------------------------------------------------- //
// Input:  tgPacket: The current series of contact points for this query-series, and contact generation parameters.
// Input:  tyPM: Current normalized time of first contact.
// Input:  bPenetrate: If the swept primitives are in penetration, if true the function will return points of penetration.
// Input:  tgPN0: Plane primitive
// Input:  tgBA0: Box, Axis-Aligned Primitive
// Input:  tgDT: A structure holding the swept primitive displacement for the entire duration of the test period
// Output: tgPacket: Contact points are added or replace the current set depending on the time comparison and given parameters
// Output: tyPM: New normalized time of first contact
// Return: Result Code
// ------------------------------------------------------------------------------------------------------------------------------ //

template <typename TYPE, int DIM>
TgRESULT F_Contact_Sweep( PC_(CONTACT_PACKET,DIM) ptgPacket, TYPE *ptyPM, CR_(PLANE,DIM) tgPN0, CR_(BOXAA,DIM) tgBA0, CR_(DELTA,DIM) tgDT )
{
    TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_SWEEP, (((TgUINT)ETgPLANE<<16)|(TgUINT)ETgBOX))

    TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) ))
    TgASSERT(tgPN0.Is_Valid() && tgBA0.Is_Valid())

    if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact)
    {
        return (TgE_FAIL);
    };

    const TYPE                          tyDT_N = MATH::F_DOT(tgDT.m_tvDT,tgPN0.Query_Normal());

    T_(VECTOR,DIM)                      tvBA0;

    tvBA0 = MATH::F_SETP<TYPE,DIM>(
        P::FSEL( tgPN0.Query_Normal().X(), tgBA0.Query_MinX(), tgBA0.Query_MaxX() ),
        P::FSEL( tgPN0.Query_Normal().Y(), tgBA0.Query_MinY(), tgBA0.Query_MaxY() ),
        P::FSEL( tgPN0.Query_Normal().Z(), tgBA0.Query_MinZ(), tgBA0.Query_MaxZ() )
    );
    const TYPE                          tyDist = F_Sign_Dist( tgPN0, tvBA0 );

    if (tyDist < TYPE(0.0))
    {
        if (*ptyPM > ptgPacket->m_tySweepTol)
        {
            ptgPacket->m_niContact = 0;
        };

        C_TgBOOL                            bPenetrate = TgTRUE == ptgPacket->m_bReport_Penetration;

        *ptyPM = TYPE(0.0);

        if (bPenetrate && TgS_MAXCONTACTS == F_Contact_Penetrate( ptgPacket, tgPN0, tgBA0 ))
        {
            return (TgE_PREPENETRATION_MAXCONTACTS);
        };

        return (TgE_PREPENETRATION);
    };

    if (tyDist >= TYPE(0.0) && tyDist + tyDT_N >= TYPE(0.0))
    {
        return (TgE_NOINTERSECT);
    };

    const TYPE                          tyT0 = tyDist / (-tyDT_N);

    if (tyT0 > *ptyPM + ptgPacket->m_tySweepTol)
    {
        return (TgE_NOINTERSECT);
    };

    if (tyT0 < *ptyPM - ptgPacket->m_tySweepTol)
    {
        ptgPacket->m_niContact = 0;
        *ptyPM = tyT0;
    };

    P_(CONTACT,DIM)                     ptgContact;

    ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);

    ptgContact->m_tvPos = tvBA0;
    ptgContact->m_tvNormal = tgPN0.Query_Normal();
    ptgContact->m_tyT0 = tyT0;
    ptgContact->m_tyDepth =  TYPE(0.0);

    ++ptgPacket->m_niContact;

    return (TgS_OK);
};

template TgRESULT F_Contact_Sweep( PC_TgF4CONTACT_PACKET, P_TgFLOAT32, CR_TgF4PLANE, CR_TgF4BOXAA,CR_TgF4DELTA );


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

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