Home

Resume

Blog

Teikitu


// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//  »Project«   Teikitu Gaming System (TgS) (∂)
//  »File«      TgS Collision - F - Axis Projection.c_inc
//  »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
//  »Version«   4.0
// ------------------------------------------------------------------------------------------------------------------------------ //
//  Copyright: © 2002-2010, 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".
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
// == Collision ================================================================================================================= //

// ---- tgCO_F_Test_Seperating_Axis --------------------------------------------------------------------------------------------- //
//  Contact occurs between the two primitives when they overlap along all possible axis of separation.  Thus, contact will occur
// at the maximum contact start time until the minimal contact end time.
// ------------------------------------------------------------------------------------------------------------------------------ //
TgSINT32 V(tgCO_F_Test_Seperating_Axis)( V(PCU_STg2_CO_Axis_Test) psAxTest )
{
    TgSINT32                            iResult = 0;

    if (psAxTest->m_fMax1 < psAxTest->m_fMin0)
    {
        // Primitive 1's projection is in the negative direction of the projection of primitive 0.

        if (psAxTest->m_fSpeed <= MKL(0.0)) //« Primitive 1 is moving away from primitive 0, no possible contact.
        {
            return (-1);
        }
        else
        {
                                                // Compute first, and last time of contact - current maximum and minimum
            const TYPE                          fT0 = (psAxTest->m_fMin0 - psAxTest->m_fMax1) / psAxTest->m_fSpeed;
            const TYPE                          fT1 = (psAxTest->m_fMax0 - psAxTest->m_fMin1) / psAxTest->m_fSpeed;
            const TYPE                          fMinT = F(tgPM_FSEL)( psAxTest->m_fMinT - fT0, psAxTest->m_fMinT, fT0 );
            const TYPE                          fMaxT = F(tgPM_FSEL)( fT1 - psAxTest->m_fMaxT, psAxTest->m_fMaxT, fT1 );

            psAxTest->m_fMinT = fMinT;
            psAxTest->m_fMaxT = fMaxT;
            iResult = fT0 <= psAxTest->m_fMinT ? iResult : 1;

            // No contact occurs if t-value exceeds the imposed limit or the current min and max pass each other.
            if ((fMinT > psAxTest->m_fLimitT) || (fMinT > fMaxT))
            {
                return (-1);
            };
        };
    }
    else if (psAxTest->m_fMax0 < psAxTest->m_fMin1)
    {
        // Primitive 1's projection is in the positive direction of the projection of primitive 0.

        if (psAxTest->m_fSpeed <= MKL(0.0)) //« Primitive 1 is moving away from primitive 0, no possible contact.
        {
            return (-1);
        }
        else
        {
                                                // Compute first, and last time of contact - current maximum and minimum
            const TYPE                          fT0 = (psAxTest->m_fMax0 - psAxTest->m_fMin1) / psAxTest->m_fSpeed;
            const TYPE                          fT1 = (psAxTest->m_fMin0 - psAxTest->m_fMax1) / psAxTest->m_fSpeed;
            const TYPE                          fMinT = F(tgPM_FSEL)( psAxTest->m_fMinT - fT0, psAxTest->m_fMinT, fT0 );
            const TYPE                          fMaxT = F(tgPM_FSEL)( fT1 - psAxTest->m_fMaxT, psAxTest->m_fMaxT, fT1 );

            psAxTest->m_fMinT = fMinT;
            psAxTest->m_fMaxT = fMaxT;
            iResult = fT0 <= psAxTest->m_fMinT ? iResult : 1;

            // No contact occurs on this axis if it now exceeds the limit imposed on the t-value.
            if ((fMinT > psAxTest->m_fLimitT) || (fMinT > fMaxT))
            {
                return (-1);
            };
        };
    }
    else if (!F(tgCM_NR0)( psAxTest->m_fSpeed )) // V and U on overlapping interval
    {
        const TYPE                          fK0 = psAxTest->m_fMax0 - psAxTest->m_fMin1;
        const TYPE                          fK1 = psAxTest->m_fMin0 - psAxTest->m_fMax1;
        const TYPE                          fT = (psAxTest->m_fSpeed > MKL(0.0)) ? fK0 : fK1;
        const TYPE                          fT1 = fT / psAxTest->m_fSpeed; //« Compute first time of contact.
        const TYPE                          fMaxT = F(tgPM_FSEL)( fT1 - psAxTest->m_fMaxT, psAxTest->m_fMaxT, fT1 );

        psAxTest->m_fMaxT = fMaxT;

        if (psAxTest->m_fMinT > fMaxT) //« No contact occurs on this axis if the current if the min and max pass each other.
        {
            return (-1);
        };
    };

    return (iResult);
}