Home

Resume

Blog

Teikitu


/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
/*  »Project«   Teikitu Gaming System (TgS) (∂)
    »File«      TgS Collision - F - Triangle-Linear.c_inc
    »Keywords«  Collision;Distance;Closest;Intersect;Penetrate;Sweep;Triangle;Line;Ray;Segment;
    »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
    »Version«   4.51 / »GUID« A9981407-3EC9-42AF-8B6F-8BE6DD919615                                                                                                        */
/*   -------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
/*  Copyright: © 2002-2017, 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:
        Redistribution of source code must retain this copyright notice, this list of conditions and the following disclaimers.
        Redistribution 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.
    The name of the author may not 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".                                                   */
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */

MSVC_WARN_DISABLE_PUSH( 6285 ) /* Analysis - (<non-zero constant> || <non-zero constant>) is always a non-zero constant. */


/*                                                                                                                                                                        */
/* Triangle Definition: T0(α,β) = P0 + α•E0 + β•E1 | α ε [ 0, 1], β ε [ 0, 1], (α + β) ε [0, 1]                                                                           */
/*  Segment Definition:   G1(γ) = P3 + γ•D1 | γ ε [ 0, 1]                                                                                                                 */
/*                                                                                                                                                                        */
/* Derivation:                                                                                                                                                            */
/*                                                                                                                                                                        */
/*                                                                                                                                                                        */
/*         .    .              .    .                                                                                                                                     */
/*          . G .               . G .   NOTE: Keep in mind that in regions C, E and G, an obtuse angle can lead                                                           */
/*           .  .                .  .            to having significant projections along the other edge.                                                                  */
/*            . .                 . .      E0                                                                                                                             */
/*             ..                  ..     .                                                                                                                               */
/*              .2                  .  F .                                                                                                                                */
/*              |\                  |\  .                                                                                                                                 */
/*              | \                 | \.                                                                                                                                  */
/*          B   |  \   F         B  | /.  E                                                                                                                               */
/*              | A \               |/  .                                                                                                                                 */
/*         .....|____\..... E0      .O   .                                                                                                                                */
/*             O.     .1           ..     .                                                                                                                               */
/*              .      .          . .  D   .                                                                                                                              */
/*          C   .   D   .   E    .  .                                                                                                                                     */
/*              .        .      . C .                                                                                                                                     */
/*              .                   .                                                                                                                                     */
/*             E1                  E1                                                                                                                                     */
/*                                                                                                                                                                        */
/*                                                                                                                                                                        */
/*  Let P0,P1,P2 be the three defining vertices of a triangle with E0 = P1 - P0 and E1 = P2 - P0.                                                                         */
/*  Let P3, D1 by the origin and the vector of a line segment respectively.                                                                                               */
/*                                                                                                                                                                        */
/*  Let DS = P3 - P0                                                                                                                                                      */
/*                                                                                                                                                                        */
/*  Let TG1, TE0, TE1 represent the co-ordinates in their respective reference frames of the extrapolated point                                                           */
/*   of contact between the line(segment) and the plane(triangle).                                                                                                        */
/*                                                                                                                                                                        */
/*      [D1•D1  D1•E0  D1•E1] [TG1]     [DS•D1]                                                                                                                           */
/*      [D1•E0  E0•E0  E0•E1] [TE0]  =  [DS•E0]                                                                                                                           */
/*      [D1•E1  E0•E1  E1•E1] [TE1]     [DS•E1]                                                                                                                           */
/*                                                                                                                                                                        */
/*      Let C(ij) be the cofactor matrix of row i and column j We know that the determinant can be computed by                                                            */
/*       adding: det = (D1•E0)•C01 + (E0•E0)•C11 + (E0•E1)•C12                                                                                                            */
/*                                                                                                                                                                        */
/*      Let K = 1.0/det                                                                                                                                                   */
/*                                                                                                                                                                        */
/*      [TG1]     [C00  C01  C02] [K_(DS•D1,DIM)]                                                                                                                         */
/*      [TE0]  =  [C01  C11  C12] [K_(DS•E0,DIM)]                                                                                                                         */
/*      [TE1]     [C02  C12  C22] [K_(DS•E1,DIM)]                                                                                                                         */
/*                                                                                                                                                                        */
/*  However, it is known that TG1 ε [ 0, 1], TE0 ε [ 0, 1], TE1 ε [ 0, 1], and (TE0 + TE1) ε [ 0, 1]                                                                      */
/*  These limitations present us with these possible cases.                                                                                                               */
/*                                                                                                                                                                        */
/*  [1] TG1 ε (-∞, 0)                                                                                                                                                     */
/*      If the given condition is met, then the line segment is tested against the specified triangle edge.                                                               */
/*          Triangle Edge 2 • (TE0 + TE1) ε ( 1, ∞)                                                                                                                       */
/*          Triangle Edge 0 • TE0 ε (-∞, 0)                                                                                                                               */
/*          Triangle Edge 1 • TE1 ε (-∞, 0)                                                                                                                               */
/*  [2] TG1 ε [ 0, 1]                                                                                                                                                     */
/*     [A] (TE0 + TE1) ε (-∞, 1]                                                                                                                                          */
/*          Triangle Edge 0 • TE0 ε (-∞, 0)                                                                                                                               */
/*          Triangle Edge 1 • TE1 ε (-∞, 0)                                                                                                                               */
/*          Intersection • TE0 ε [ 0, 1], TE1 ε [ 0, 1]                                                                                                                   */
/*     [B] (TE0 + TE1) ε ( 1, ∞)                                                                                                                                          */
/*          Triangle Edge 2                                                                                                                                               */
/*          Triangle Edge 0 • TE0 ε (-∞, 0)                                                                                                                               */
/*          Triangle Edge 1 • TE1 ε (-∞, 0)                                                                                                                               */
/*  [3] TG1 ε ( 1, ∞)                                                                                                                                                     */
/*      If the given condition is met, then the line segment is tested against the specified triangle edge.                                                               */
/*          Triangle Edge 2 • (TE0 + TE1) ε ( 1, ∞)                                                                                                                       */
/*          Triangle Edge 0 • TE0 ε (-∞, 0)                                                                                                                               */
/*          Triangle Edge 1 • TE1 ε (-∞, 0)                                                                                                                               */
/*                                                                                                                                                                        */
/*  If the triangle and the segment happen to be parallel then,                                                                                                           */
/*    The distance between the line segment and the triangle can be found by checking the distance of the segment                                                         */
/*     against the three triangle edges (line segments) and the triangle against the two end points of the line                                                           */
/*     segment.  The resulting minimal value (with any corresponding extra information) will be the desired result.                                                       */
/*                                                                                                                                                                        */
/* == Collision ========================================================================================================================================================= */

/* ---- VI(tgCO_FI_ST_ParamSq_LR) --------------------------------------------------------------------------------------------------------------------------------------- */
/* Input:  psST0: Space triangle primitive                                                                                                                                */
/* Input:  vS0,vD0: Origin and Direction for the Linear                                                                                                                   */
/* Output: _fET0, _fET1: Parametric parameters to generate point of minimal distance on the triangle                                                                      */
/* Output: _fLN0: Parametric parameter to generate point of minimal distance on the linear                                                                                */
/* Return: Minimal distance between the two primitives or negative type max if they intersect or are invalid.                                                             */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TYPE VI(tgCO_FI_ST_ParamSq_LR)( TYPE *pfET0, TYPE *pfET1, TYPE *pfLN0, V(CPC_TgSTRI) psST0, V(CPC_TgVEC) pvS0, V(CPC_TgVEC) pvD0 )
{
    TgERROR( V(tgGM_ST_Is_Valid)( psST0 ) && V(F_Is_Point_Valid)( pvS0 ) && V(F_Is_Vector_Valid)( pvD0 ) );

    /* == Perform the requested primitive-primitive data function. == */

    /* If the linear is not parallel to the triangle, check to see if the two geometries intersect each other. */

    if (!F(tgCM_NR0)( V(F_DOT)( pvD0, &psST0->m_sCT.m_sET.m_sPT.m_vNormal ) ))
    {
        C_TgRESULT iResult = VI(tgCO_FI_ET_Intersect_Param_LR)( pfET0, pfET1, pfLN0, &psST0->m_sCT.m_sET, pvS0, pvD0 );

        if (TgSUCCEEDED(iResult) || (TgFAILED(iResult) && KTgE_NO_INTERSECT != iResult))
        {
            /* Some property of the triangle was illegal - return back an error state. */
            /* The linear may have intersected the triangle. */

            return (-F(KTgMAX));
        };
    }

    {
        V(C_TgVEC)                          vS2 = V(F_ADD)( pvS0, pvD0 );
        TgSINT32                            iTest = 0;
        TYPE                                fET0 = F(KTgMAX), fET1 = F(KTgMAX), fL1 = F(KTgMAX);
        TYPE                                fT0, fT1, fDistSq = F(KTgMAX);

        /* Determine which feature tests need to be executed given the linear parameters. */

    #if 1 == LN_CAP_0
        const TYPE                          f00 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 0, pvS0 );
        const TYPE                          f01 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 1, pvS0 );
        const TYPE                          f02 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 2, pvS0 );

    #if 1 == LN_CAP_1
        const TYPE                          f10 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 0, &vS2 );
        const TYPE                          f11 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 1, &vS2 );
        const TYPE                          f12 = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + 2, &vS2 );

        iTest |= (f10 > -F(KTgEPS) && f11 > -F(KTgEPS) && f12 > -F(KTgEPS)) ? (1 << 4) : 0;
        iTest |= (f10 < F(KTgEPS)) ? (1 << 0) : 0;
        iTest |= (f11 < F(KTgEPS)) ? (1 << 1) : 0;
        iTest |= (f12 < F(KTgEPS)) ? (1 << 2) : 0;
    #else
        const TYPE                          fK0 = V(F_DOT)( &psST0->m_avPlane[0].m_vNormal, pvD0 );
        const TYPE                          fK1 = V(F_DOT)( &psST0->m_avPlane[1].m_vNormal, pvD0 );
        const TYPE                          fK2 = V(F_DOT)( &psST0->m_avPlane[2].m_vNormal, pvD0 );

        iTest |= (fK0 < -F(KTgEPS)) ? (1 << 0) : 0;
        iTest |= (fK1 < -F(KTgEPS)) ? (1 << 1) : 0;
        iTest |= (fK2 < -F(KTgEPS)) ? (1 << 2) : 0;
    #endif

        iTest |= (f00 > -F(KTgEPS) && f01 > -F(KTgEPS) && f02 > -F(KTgEPS)) ? (1 << 3) : 0;
        iTest |= (f00 < F(KTgEPS)) ? (1 << 0) : 0;
        iTest |= (f01 < F(KTgEPS)) ? (1 << 1) : 0;
        iTest |= (f02 < F(KTgEPS)) ? (1 << 2) : 0;

    #else
        const TYPE                          fK0 = V(F_DOT)( &psST0->m_avPlane[0].m_vNormal, pvD0 );
        const TYPE                          fK1 = V(F_DOT)( &psST0->m_avPlane[1].m_vNormal, pvD0 );
        const TYPE                          fK2 = V(F_DOT)( &psST0->m_avPlane[2].m_vNormal, pvD0 );

        iTest |= (F(tgPM_ABS)(fK0) > F(KTgEPS)) ? (1 << 0) : 0;
        iTest |= (F(tgPM_ABS)(fK1) > F(KTgEPS)) ? (1 << 1) : 0;
        iTest |= (F(tgPM_ABS)(fK2) > F(KTgEPS)) ? (1 << 2) : 0;
    #endif

        /* Test the first capped point if it is contained within the triangle space. */

        if (0 != (iTest & (1 << 3)))
        {
            const TYPE fTest = V(tgCO_F_ET_ParamSq_VT)( &fT0, &fT1, &psST0->m_sCT.m_sET, pvS0 );

            if (fTest < fDistSq)
            {
                fDistSq = fTest;
                fL1 = MKL(0.0);
                fET0 = fT0;
                fET1 = fT1;
            };
        };

        /* Test the second capped point if it is contained within the triangle space. */

        if (0 != (iTest & (1 << 4)))
        {
            const TYPE fTest = V(tgCO_F_ET_ParamSq_VT)( &fT0, &fT1, &psST0->m_sCT.m_sET, &vS2 );

            if (fTest < fDistSq)
            {
                fDistSq = fTest;
                fL1 = MKL(1.0);
                fET0 = fT0;
                fET1 = fT1;
            };
        };

        if (0 != (iTest & (3 << 3)))
        {
            return (fDistSq);
        };

        TgERROR( 0 != iTest );

        /* Check minimal distance between linear and edge 0, if any part crosses into the negative space of the edge plane. */

        if (0 != (iTest & (1 << 0)))
        {
            const TYPE fTest = VI(tgCO_F_LR11_ParamSq_LR)( &fT0, &fT1, psST0->m_sCT.m_sET.m_sPT.m_avPoint + 0, psST0->m_sCT.m_sET.m_avEdge + 0, pvS0, pvD0 );

            if (fTest < fDistSq)
            {
                fDistSq = fTest;
                fL1 = fT1;
                fET0 = fT0;
                fET1 = MKL(0.0);
            };
        };

        /* Check minimal distance between linear and edge 1, if any part crosses into the negative space of the edge plane. */

        if (0 != (iTest & (1 << 1)))
        {
            const TYPE fTest = VI(tgCO_F_LR11_ParamSq_LR)( &fT0, &fT1, psST0->m_sCT.m_sET.m_sPT.m_avPoint + 1, psST0->m_sCT.m_sET.m_avEdge + 1, pvS0, pvD0 );

            if (fTest < fDistSq)
            {
                fDistSq = fTest;
                fL1 = fT1;
                fET0 = MKL(1.0) - fT0;
                fET1 = fT0;
            };
        };

        /* Check minimal distance between linear and edge 2, if any part crosses into the negative space of the edge plane. */

        if (0 != (iTest & (1 << 2)))
        {
            const TYPE fTest = VI(tgCO_F_LR11_ParamSq_LR)( &fT0, &fT1, psST0->m_sCT.m_sET.m_sPT.m_avPoint + 2, psST0->m_sCT.m_sET.m_avEdge + 2, pvS0, pvD0 );

            if (fTest < fDistSq)
            {
                fDistSq = fTest;
                fL1 = fT1;
                fET0 = MKL(0.0);
                fET1 = MKL(1.0) - fT0;
            };
        };

        *pfET0 = fET0;
        *pfET1 = fET1;
        *pfLN0 = fL1;

        return (fDistSq);
    };
}


/* ---- VI(tgCO_FI_ET_Intersect_Param_LR) ------------------------------------------------------------------------------------------------------------------------------- */
/* Input:  psET0: Edge triangle primitive                                                                                                                                 */
/* Input:  vS0,vD0: Origin and Direction for the Linear                                                                                                                   */
/* Output: _fET0, _fET1: Parametric parameters to generate point of contact on the triangle                                                                               */
/* Output: _fLN0: Parametric parameter to generate point of contact on the linear                                                                                         */
/* Return: Result Code                                                                                                                                                    */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgRESULT VI(tgCO_FI_ET_Intersect_Param_LR)( TYPE *pfET0, TYPE *pfET1, TYPE *pfLN0, V(CPC_TgETRI) psET0, V(CPC_TgVEC) pvS0, V(CPC_TgVEC) pvD0 )
{
    V(C_TgVEC)                          vDS = V(F_SUB)( pvS0, psET0->m_sPT.m_avPoint );
    const TYPE                          fDS_DS = V(F_LSQ)( &vDS );

    TgERROR( V(tgGM_ET_Is_Valid)( psET0 ) && V(F_Is_Point_Valid)( pvS0 ) && V(F_Is_Vector_Valid)( pvD0 ) );

    if (fDS_DS <= F(KTgEPS))
    {
        /* Quick Out - the segment origin is within tolerance of triangle origin. */

        *pfET0 = MKL(0.0);
        *pfET1 = MKL(0.0);
        *pfLN0 = MKL(0.0);

        return (KTgS_OK);
    }
    else
    {
        const TYPE                          fD1_N = V(F_DOT)( pvD0, &psET0->m_sPT.m_vNormal );

        if (F(tgPM_ABS)(fD1_N) <= F(KTgEPS))
        {
            /* Linear is parallel to the plane of the triangle. */
            return (KTgE_NO_INTERSECT);
        }
        else
        {
            const TYPE                          fK0 = MKL(1.0) / fD1_N;
            const TYPE                          fT0 = fK0*V(F_DOT)( &vDS, &psET0->m_sPT.m_vNormal );

            if ((LN_CAP_0 && fT0 < MKL(0.0)) || (LN_CAP_1 && fT0 > MKL(1.0)))
            {
                return (KTgE_NO_INTERSECT);
            }
            else
            {
                V(C_TgVEC)                          vK0 = V(F_CX)( psET0->m_avEdge + 1, &vDS );
                const TYPE                          fET0 = fK0*V(F_DOT)( pvD0, &vK0 );

                if (fET0 < MKL(0.0) || fET0 > MKL(1.0))
                {
                    return (KTgE_NO_INTERSECT);
                }
                else
                {
                    V(C_TgVEC)                          vK1 = V(F_CX)( psET0->m_avEdge + 0, &vDS );
                    const TYPE                          fET1 = fK0*V(F_DOT)( pvD0, &vK1 );

                    if (fET1 < MKL(0.0) || fET0 + fET1 > MKL(1.0))
                    {
                        return (KTgE_NO_INTERSECT);
                    };

                    *pfLN0 = fT0;
                    *pfET0 = fET0;
                    *pfET1 = fET1;

                    return (KTgS_OK);
                };
            };
        };
    };
}


/* ---- VI(tgCO_FI_ST_Clip_Param_F_LR) ---------------------------------------------------------------------------------------------------------------------------------- */
/* Input:  psST0: Space triangle primitive - F_Clip-space is the region defined by the infinite extrusion along the normal.                                               */
/* Input:  vS0,vD0: Origin and Direction for the Linear                                                                                                                   */
/* Output: _fLN0,_fLN1: Parametric parameter to generate point of contact on the linear                                                                                   */
/* Output: _iCode: PT0 Valid | PT1 Valid | PT0 Not Reduced | PT1 Not Reduced                                                                                              */
/* Return: Result Code                                                                                                                                                    */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgRESULT VI(tgCO_FI_ST_Clip_Param_F_LR)( TYPE *pfLN0, TYPE *pfLN1, PC_TgSINT32 piCode, V(CPC_TgSTRI) psST0, V(CPC_TgVEC) pvS0, V(CPC_TgVEC) pvD0 )
{
    TYPE                                fT0 = MKL(0.0), fT1 = MKL(0.0);
    TgSINT32                            iCode = 0;
    TgSINT32                            iEdge;

    for (iEdge = 0; iEdge < 3; ++iEdge)
    {
        const TYPE                          fD1_N = V(F_DOT)( &psST0->m_avPlane[iEdge].m_vNormal, pvD0 );
        const TYPE                          fDist = V(tgCO_F_PN_Dist_VT)( psST0->m_avPlane + iEdge, pvS0 );

        if (fDist < MKL(0.0))
        {
            /*  Check to see if its impossible for this linear to intersect the triangle space by seeing if it rests entirely in the exterior half-space of the */
            /* triangle-edge normal space.  This can occur if the linear is near parallel to the resulting partitioning plane, if the linear is start-capped and directed */
            /* away from the plane and if its end-capped and the end point is also behind the plane. */

            if ((F(tgPM_ABS)(fD1_N) <= F(KTgEPS)) || (LN_CAP_0 && fD1_N < MKL(0.0)) || (LN_CAP_1 && (fD1_N + fDist < MKL(0.0))))
            {
                *piCode = 0;
                return (KTgE_NO_INTERSECT);
            };
        };

        if (fD1_N > F(KTgEPS))
        {
            const TYPE                          fK0 = (LN_CAP_1 && fDist > fD1_N) ? MKL(1.0) : fDist / fD1_N;
            const TYPE                          fTest = (LN_CAP_0 && fDist < MKL(0.0)) ? MKL(0.0) : fK0;

            if (iCode & 1)
            {
                if (fT0 < fTest)
                {
                    fT0 = fTest;
                    iCode &= V(tgGM_ST_Test_Edge)( psST0, iEdge ) ? ~0 : ~4;
                };
            }
            else
            {
                fT0 = fTest;
                iCode |= V(tgGM_ST_Test_Edge)( psST0, iEdge ) ? (1 + 4) : 1;
            };
        }
        else if (fD1_N < -F(KTgEPS))
        {
            const TYPE                          fK1 = (LN_CAP_1 && fDist < fD1_N) ? MKL(1.0) : fDist / fD1_N;
            const TYPE                          fTest = (LN_CAP_0 && fDist > MKL(0.0)) ? MKL(0.0) : fK1;

            if (iCode & 2)
            {
                if (fT1 > fTest)
                {
                    fT1 = fTest;
                    iCode &= V(tgGM_ST_Test_Edge)( psST0, iEdge ) ? ~0 : ~8;
                };
            }
            else
            {
                fT1 = fTest;
                iCode |= V(tgGM_ST_Test_Edge)( psST0, iEdge ) ? (2 + 8) : 2;
            };
        };
    };

    TgERROR( iCode == 3 );

    *pfLN0 = fT0;
    *pfLN1 = fT1;
    *piCode = iCode;

    return (KTgS_OK);
}


/* ---- VI(tgCO_FI_ST_Clip_F_LR) ---------------------------------------------------------------------------------------------------------------------------------------- */
/* Input:  psST0: Space triangle primitive - F_Clip-space is the region defined by the infinite extrusion along the normal.                                               */
/* Input:  vS0,vD0: Origin and Direction for the Linear                                                                                                                   */
/* Output: tgCL: The resulting point list - points created from clipping on a reduced edge are not added to the list.                                                     */
/* Return: Result Code                                                                                                                                                    */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgRESULT VI(tgCO_FI_ST_Clip_F_LR)( V(PC_STg2_CO_Clip_List) psCL, PC_TgSINT32 piCode, V(CPC_TgSTRI) psST0, V(CPC_TgVEC) pvS0, V(CPC_TgVEC) pvD0 )
{
    TYPE                                fT0, fT1;
    TgSINT32                            iCode;
    TgRESULT                            iResult;

    if (psCL->m_niMax < 2)
    {
        return (KTgE_FAIL);
    };

    iResult = VI(tgCO_FI_ST_Clip_Param_F_LR)( &fT0, &fT1, &iCode, psST0, pvS0, pvD0 );

    *piCode = iCode;

    if (TgFAILED( iResult ) || 0 == (iCode & 12))
    {
        psCL->m_niPoint = 0;
        return (iResult);
    };

    if (12 != (iCode & 12))
    {
        if (F(tgPM_ABS)(fT0 - fT1) <= F(KTgEPS))
        {
            V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT0, pvD0 );

            psCL->m_avPoint[0] = V(F_ADD)(pvS0, &vK0);
            psCL->m_niPoint = 1;
        }
        else
        {
            V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT0, pvD0 );
            V(C_TgVEC)                          vK1 = V(F_MUL_SV)( fT1, pvD0 );

            psCL->m_avPoint[0] = V(F_ADD)( pvS0, &vK0 );
            psCL->m_avPoint[1] = V(F_ADD)( pvS0, &vK1 );
            psCL->m_niPoint = 2;
        };
    }
    else if (4 != (iCode & 4))
    {
        V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT0, pvD0 );

        psCL->m_avPoint[0] = V(F_ADD)( pvS0, &vK0 );
        psCL->m_niPoint = 1;
    }
    else if (8 != (iCode & 8))
    {
        V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT1, pvD0 );

        psCL->m_avPoint[0] = V(F_ADD)( pvS0, &vK0 );
        psCL->m_niPoint = 1;
    };

    return (KTgS_OK);
}


/* ---- VI(tgCO_FI_ST_Clip_LR) ------------------------------------------------------------------------------------------------------------------------------------------ */
/* Input:  psST0: Space triangle primitive - F_Clip-space is the region defined by the infinite extrusion along the normal.                                               */
/* Input:  vS0,vD0: Origin and Direction for the Linear                                                                                                                   */
/* Output: tgCL: The resulting segment list.                                                                                                                              */
/* Return: Result Code                                                                                                                                                    */
/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
TgRESULT VI(tgCO_FI_ST_Clip_LR)( V(PC_STg2_CO_Clip_List) psCL, V(CPC_TgSTRI) psST0, V(CPC_TgVEC) pvS0, V(CPC_TgVEC) pvD0 )
{
    TYPE                                fT0, fT1;
    TgSINT32                            iCode;
    TgRESULT                            iResult;

    if (psCL->m_niMax < 2)
    {
        return (KTgE_FAIL);
    };

    iResult = VI(tgCO_FI_ST_Clip_Param_F_LR)( &fT0, &fT1, &iCode, psST0, pvS0, pvD0 );

    if (TgFAILED( iResult ))
    {
        psCL->m_niPoint = 0;
        return (iResult);
    };

    if (F(tgPM_ABS)(fT0 - fT1) <= F(KTgEPS))
    {
        V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT0, pvD0 );

        psCL->m_avPoint[0] = V(F_ADD)( pvS0, &vK0 );
        psCL->m_niPoint = 1;
    }
    else
    {
        V(C_TgVEC)                          vK0 = V(F_MUL_SV)( fT0, pvD0 );
        V(C_TgVEC)                          vK1 = V(F_MUL_SV)( fT1, pvD0 );

        psCL->m_avPoint[0] = V(F_ADD)( pvS0, &vK0 );
        psCL->m_avPoint[1] = V(F_ADD)( pvS0, &vK1 );
        psCL->m_niPoint = 2;
    };

    return (KTgS_OK);
}


MSVC_WARN_DISABLE_POP( 6285 )