[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//
//  Project:   Talina Gaming System (TgS) (∂)
//  File:      TgS Collision - Linear-Linear.inl
//  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".
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
#if !defined(_TGS_COLLISION_LINEAR_POINT_INL_)
#define _TGS_COLLISION_LINEAR_POINT_INL_
#pragma once

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

// Functions used for internal use - primitive based functions should be the primary system calls.

//  A linear is a generic term used to describe the set of 1D primitives.  To avoid code duplication these functions are normally
// created through templates where two boolean template parameters are used to indicate if the free variable is closed on a
// particular side of the number line.

// tvS0         Point (Input)
// tvD0         Direction (Input)
// tvS1         Point (Input)
// tvD1         Direction (Input)

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




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

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

template <typename TYPE, int DIM> struct TTgFSQ_LNPT<TYPE,DIM,0,0>
{
    TgFORCEINLINE static const TYPE                          DO( M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid line.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        return (tyDS_DS - tyDS_D0*(tyDS_D0 / tyD0_D0));
    };
};


template <typename TYPE, int DIM> struct TTgFSQ_LNPT<TYPE,DIM,1,0>
{
    TgFORCEINLINE static const TYPE                          DO( M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid ray.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        return (tyDS_DS - P::FSEL( tyDS_D0, tyDS_D0*(tyDS_D0 / tyD0_D0), TYPE(0.0) ));
    };
};


template <typename TYPE, int DIM> struct TTgFSQ_LNPT<TYPE,DIM,1,1>
{
    TgFORCEINLINE static const TYPE                          DO( M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid segment.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        const TYPE                          tyTA = P::FSEL( tyD0_D0 - tyDS_D0, tyDS_D0*(tyDS_D0 / tyD0_D0), TYPE(2.0)*tyDS_D0 + tyD0_D0 );
        return (tyDS_DS - P::FSEL( tyDS_D0, tyTA, TYPE(0.0) ));
    };
};


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

template <typename TYPE, int DIM> struct TTgCSQ_LNPT<TYPE,DIM,0,0>
{
    TgFORCEINLINE static const TYPE                          DO( TYPE *ptyLN0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid line.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        const TYPE                          tyLN0 = tyDS_D0 / tyD0_D0;

        *ptyLN0 = tyLN0;
        return (tyDS_DS - tyDS_D0*tyLN0);
    };

    TgFORCEINLINE static const TYPE                          DO( PC_(VECTOR,DIM) ptvT0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        register TYPE                       tyT0;
        const TYPE                          tyDistSq = DO( &tyT0, tvS0,tvD0, tvS1 );

        *ptvT0 = MATH::F_ADD( tvS0, MATH::F_MUL( tyT0, tvD0 ) );
        return (tyDistSq);
    };
};


template <typename TYPE, int DIM> struct TTgCSQ_LNPT<TYPE,DIM,1,0>
{
    TgFORCEINLINE static const TYPE                          DO( TYPE *ptyRY0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid ray.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        const TYPE                          tyRY0 = P::FSEL( tyDS_D0, tyDS_D0/tyD0_D0, TYPE(0.0) );

        *ptyRY0 = tyRY0;
        return (tyDS_DS - tyDS_D0*tyRY0);
    };

    TgFORCEINLINE static const TYPE                          DO( PC_(VECTOR,DIM) ptvT0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        register TYPE                       tyT0;
        const TYPE                          tyDistSq = DO( &tyT0, tvS0,tvD0, tvS1 );

        *ptvT0 = MATH::F_ADD( tvS0, MATH::F_MUL( tyT0, tvD0 ) );
        return (tyDistSq);
    };
};


template <typename TYPE, int DIM> struct TTgCSQ_LNPT<TYPE,DIM,1,1>
{
    TgFORCEINLINE static const TYPE                          DO( TYPE *ptySG0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        C_(VECTOR,DIM)                      tvDS = MATH::F_SUB( tvS1, tvS0 );
        const TYPE                          tyD0_D0 = MATH::F_LSQ( tvD0 );

        TgASSERT( tyD0_D0 > LIMITS<TYPE>::EPSILON ); //« Must have a valid segment.

        const TYPE                          tyDS_DS = MATH::F_LSQ( tvDS );
        const TYPE                          tyDS_D0 = MATH::F_DOT(tvDS,tvD0);

        const TYPE                          tyTA = P::FSEL( tyD0_D0 - tyDS_D0, tyDS_D0/tyD0_D0, TYPE(1.0) );
        const TYPE                          tySG0 = P::FSEL( tyDS_D0, tyTA, TYPE(0.0) );

        *ptySG0 = tySG0;
        return (tyDS_DS - tyDS_D0*tySG0 + P::FSEL( tyD0_D0 - tyDS_D0, TYPE(0.0), tyD0_D0 - tyDS_D0 ));
    };

    TgFORCEINLINE static const TYPE                          DO( PC_(VECTOR,DIM) ptvT0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0, M_(VECTOR,DIM) tvS1 )
    {
        register TYPE                       tyT0;
        const TYPE                          tyDistSq = DO( &tyT0, tvS0,tvD0, tvS1 );

        *ptvT0 = MATH::F_ADD( tvS0, MATH::F_MUL( tyT0, tvD0 ) );
        return (tyDistSq);
    };
};


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

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