[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // // Project: Talina Gaming System (TgS) (∂) // File: TgS Collision - Box-Linear.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 /////////////////////////////////////////////////////////////////////////////////////////////////////// // ============================================================================================================================== // // ---- Box_DoF3 ------------------------------------------------------------------------------------------------------- // // -- Internal Function -- (Helper to create contact points the box and linear - three degrees of freedom) // Input: tvDS: The difference vector between the origin of the two primitives (absolute value) // Input: tvD0: Direction of the Linear // Input: tgBX0: Box primitive // Output: tyLN0: Parametric parameter to generate the point of proximity on the linear // Output: tvDS: The difference vector between the two points of closest proximity // Return: Result Code // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TYPE Box_DoF3( TYPE *ptyLN0, PC_(VECTOR,DIM) ptvDS, M_(VECTOR,DIM) tvD0, CR_(BOX,DIM) tgBX0 ) { T_(VECTOR,DIM) tvD1_D1, tvD1_MN, tvD1_MX, tvMN_MN, tvMX_MX; C_(VECTOR,DIM) tvMN = MATH::F_SUB( *ptvDS, tgBX0.Query_ExtentList() ); C_(VECTOR,DIM) tvMX = MATH::F_ADD( *ptvDS, tgBX0.Query_ExtentList() ); C_(VECTOR,DIM) tvD1xMN = MATH::F_CX( tvD0, tvMN ); tvD1_D1 = MATH::F_MUL( tvD0, tvD0 ); tvD1_MN = MATH::F_MUL( tvD0, tvMN ); tvD1_MX = MATH::F_MUL( tvD0, tvMX ); tvMN_MN = MATH::F_MUL( tvMN, tvMN ); tvMX_MX = MATH::F_MUL( tvMX, tvMX ); const TYPE tyD1_D1 = MATH::F_LSQ( tvD0 ); TgUINT i0, i1, i2; if (tvD1xMN.Z() >= TYPE(0.0)) { i0 = tvD1xMN.X() >= TYPE(0.0) ? 2 : 1; i1 = tvD1xMN.X() >= TYPE(0.0) ? 0 : 2; i2 = tvD1xMN.X() >= TYPE(0.0) ? 1 : 0; } else { i0 = tvD1xMN.Y() >= TYPE(0.0) ? 0 : 2; i1 = tvD1xMN.Y() >= TYPE(0.0) ? 1 : 0; i2 = tvD1xMN.Y() >= TYPE(0.0) ? 2 : 1; } (*ptvDS)(i0) = tgBX0.Query_Extent(i0); if (tvD0(i0)*tvMX(i2) >= tvD0(i2)*tvMN(i0) && tvD0(i0)*tvMX(i1) >= tvD0(i1)*tvMN(i0)) { const TYPE tyINV = TYPE(1.0) / tvD0(i0); (*ptvDS)(i1) -= tvD0(i1)*tvMN(i0)*tyINV; (*ptvDS)(i2) -= tvD0(i2)*tvMN(i0)*tyINV; *ptyLN0 = -tvMN(i0)*tyINV; return (TYPE(0.0)); }; const TYPE tyTMP = tvMX(i1) - tvD0(i1)*(tvD1_MN(i0) + tvD1_MX(i2)) / (tvD1_D1(i0) + tvD1_D1(i2)); if (tvD0(i0)*tvMX(i1) >= tvD0(i1)*tvMN(i0) || (tyTMP >= TYPE(0.0) && tvD0(i0)*tvMX(i2) < tvD0(i2)*tvMN(i0))) { const TYPE tyLength = TYPE(2.0)*tgBX0.Query_Extent(i1); const TYPE tyT = P::FSEL(tyLength - tyTMP, P::FSEL( tyTMP, tyTMP, TYPE(0.0) ), tyLength ); const TYPE tyTB = tvMX(i1) - tyT; const TYPE tyDT = tvD1_MN(i0) + tvD1_MX(i2) + tvD0(i1)*tyTB; const TYPE tyPM = -tyDT / tyD1_D1; (*ptvDS)(i1) = -tgBX0.Query_Extent(i1) + tyT; (*ptvDS)(i2) = -tgBX0.Query_Extent(i2); *ptyLN0 = tyPM; return (tvMN_MN(i0) + tvMX_MX(i2) + tyDT*tyPM + tyTB*tyTB); } else { const TYPE tyTMP = tvMX(i2) - tvD0(i2)*(tvD1_MN(i0) + tvD1_MX(i1)) / (tvD1_D1(i0) + tvD1_D1(i1)); const TYPE tyLength = TYPE(2.0)*tgBX0.Query_Extent(i2); const TYPE tyT = P::FSEL(tyLength - tyTMP, P::FSEL( tyTMP, tyTMP, TYPE(0.0) ), tyLength ); const TYPE tyTB = tvMX(i2) - tyT; const TYPE tyDT = tvD1_MN(i0) + tvD1_MX(i1) + tvD0(i2)*tyTB; const TYPE tyPM = -tyDT / tyD1_D1; (*ptvDS)(i1) = -tgBX0.Query_Extent(i1); (*ptvDS)(i2) = -tgBX0.Query_Extent(i2) + tyT; *ptyLN0 = tyPM; return (tvMN_MN(i0) + tvMX_MX(i1) + tyDT*tyPM + tyTB*tyTB); }; }; template TgFLOAT32 Box_DoF3( P_TgFLOAT32, PC_TgF4VECTOR, M_TgF4VECTOR, CR_TgF4BOX ); // ============================================================================================================================== // // ---- Box_DoF2 ------------------------------------------------------------------------------------------------------- // // -- Internal Function -- (Helper to create contact points the box and linear - two degrees of freedom) // Input: tvDS: The difference vector between the origin of the two primitives // Input: tvD0: Direction of the Linear // Input: i0,i1,i2: Used to give the face order for the test // Input: tgBX0: Box primitive // Output: tyLN0: Parametric parameter to generate the point of proximity on the linear // Output: tvDS: The difference vector between the two points of closest proximity // Return: Result Code // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TYPE Box_DoF2( TYPE *ptyLN0, PC_(VECTOR,DIM) ptvDS, M_(VECTOR,DIM) tvD0, C_TgINT i0, C_TgINT i1, C_TgINT i2, CR_(BOX,DIM) tgBX0 ) { // Construct the direction vector from the box corner at the positive extents to the line origin. const TYPE tyMinDT0 = (*ptvDS)(i0) - tgBX0.Query_Extent(i0); const TYPE tyMinDT1 = (*ptvDS)(i1) - tgBX0.Query_Extent(i1); const TYPE tyMinDT1_DN0 = tvD0(i0)*tyMinDT1; const TYPE tyMinDT0_DN1 = tvD0(i1)*tyMinDT0; T_(VECTOR,DIM) tvD1_D1; tvD1_D1 = MATH::F_MUL( tvD0, tvD0 ); //const TYPE tyD1_D1 = MATH::F_LSQ( tvD0 ); if (tyMinDT0_DN1 >= tyMinDT1_DN0) { (*ptvDS)(i0) = tgBX0.Query_Extent(i0); const TYPE tyMaxDT1 = (*ptvDS)(i1) + tgBX0.Query_Extent(i1); const TYPE tyDT = tyMinDT0_DN1 - tvD0(i0)*tyMaxDT1; if (tyDT >= TYPE(0.0)) //« Line is outside of the box. { const TYPE tyTMP0 = TYPE(1.0) / (tvD1_D1(i0) + tvD1_D1(i1)); (*ptvDS)(i1) = -tgBX0.Query_Extent(i1); *ptyLN0 = -(tvD0(i0)*tyMinDT0 + tvD0(i1)*tyMaxDT1)*tyTMP0; return (tyDT*tyDT*tyTMP0); } else //« Line intersects the box. { const TYPE tyTMP0 = TYPE(1.0) / tvD0(i0); (*ptvDS)(i1) -= tyMinDT0_DN1*tyTMP0; *ptyLN0 = -tyMinDT0*tyTMP0; return (TYPE(0.0)); } } else { (*ptvDS)(i1) = tgBX0.Query_Extent(i1); const TYPE tyMaxDT0 = (*ptvDS)(i0) + tgBX0.Query_Extent(i0); const TYPE tyDT = tyMinDT1_DN0 - tvD0(i1)*tyMaxDT0; if (tyDT >= TYPE(0.0)) //« Line is outside of the box. { const TYPE tyTMP0 = TYPE(1.0) / (tvD1_D1(i0) + tvD1_D1(i1)); (*ptvDS)(i0) = -tgBX0.Query_Extent(i0); *ptyLN0 = -(tvD0(i0)*tyMaxDT0 + tvD0(i1)*tyMinDT1)*tyTMP0; return (tyDT*tyDT*tyTMP0); } else //« Line intersects the box. { const TYPE tyTMP0 = TYPE(1.0) / tvD0(i1); (*ptvDS)(i0) -= tyMinDT1_DN0*tyTMP0; *ptyLN0 = -tyMinDT1*tyTMP0; return (TYPE(0.0)); } } } template TgFLOAT32 Box_DoF2( P_TgFLOAT32, PC_TgF4VECTOR, M_TgF4VECTOR, C_TgINT, C_TgINT, C_TgINT, CR_TgF4BOX ); // ============================================================================================================================== // // ---- TTgCSQ_BXLN ------------------------------------------------------------------------------------------------------------- // // -- Internal Function -- // Input: tgBX0: Box primitive // Input: tvS0,tvD0: Origin and Direction for Linear // Output: tyB0,tyB1,tyB2: Parametric parameters to generate the point of closest proximity on the box (one for each axis) // Output: tyLN0: Parametric parameter to generate the point of proximity on the linear // Return: Minimal distance between the two primitives or negative type max if they intersect or are invalid. // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM, bool bC0, bool bC1> TYPE TTgCSQ_BXLN<TYPE,DIM,bC0,bC1>::DO( TYPE *ptyB0, TYPE *ptyB1, TYPE *ptyB2, TYPE *ptyLN0, CR_(BOX,DIM) tgBX0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0 ) { // Compute coordinates of line in box coordinate system T_(VECTOR,DIM) tvDS = MATH::F_SUB( tvS0, tgBX0.Query_Origin() ); const TYPE tyD1_X0 = MATH::F_DOT( tvD0, tgBX0.Query_AxisUnit0() ); const TYPE tyD1_X1 = MATH::F_DOT( tvD0, tgBX0.Query_AxisUnit1() ); const TYPE tyD1_X2 = MATH::F_DOT( tvD0, tgBX0.Query_AxisUnit2() ); const TYPE tyDS_X0 = MATH::F_DOT( tvDS, tgBX0.Query_AxisUnit0() ); const TYPE tyDS_X1 = MATH::F_DOT( tvDS, tgBX0.Query_AxisUnit1() ); const TYPE tyDS_X2 = MATH::F_DOT( tvDS, tgBX0.Query_AxisUnit2() ); T_(VECTOR,DIM) tvDN; tvDS = MATH::F_SETV<TYPE,DIM>( P::FSEL(tyD1_X0, tyDS_X0,-tyDS_X0), P::FSEL(tyD1_X1, tyDS_X1,-tyDS_X1), P::FSEL(tyD1_X2, tyDS_X2,-tyDS_X2) ); tvDN = MATH::F_SETV<TYPE,DIM>( P::ABS(tyD1_X0), P::ABS(tyD1_X1), P::ABS(tyD1_X2) ); // Calculate the distance and place of closest contact. TYPE tyDistSq = TYPE(0.0); switch ((Near_Zero( tvD0.X() ) ? 0 : 1) + (Near_Zero( tvD0.Y() ) ? 0 : 2) + (Near_Zero( tvD0.Z() ) ? 0 : 4)) { case 7: { // (+,+,+) tyDistSq += Box_DoF3( ptyLN0, &tvDS, tvDN, tgBX0 ); *ptyB0 = P::FSEL( tyD1_X0, tvDS.X(), -tvDS.X() ); *ptyB1 = P::FSEL( tyD1_X1, tvDS.Y(), -tvDS.Y() ); *ptyB2 = P::FSEL( tyD1_X2, tvDS.Z(), -tvDS.Z() ); break; } case 6: { // (+,+,0) tyDistSq += Box_DoF2( ptyLN0, &tvDS, tvDN, 0,1,2, tgBX0 ); const TYPE tyT2 = P::ABS( tvDS.Z() ) - tgBX0.Query_Extent2(); const TYPE tyZ = P::FSEL( tyT2, P::Copy_Sign( tgBX0.Query_Extent2(), tvDS.Z() ), tvDS.Z() ); tyDistSq += P::FSEL( tyT2, tyT2*tyT2, TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tvDS.X(), -tvDS.X() ); *ptyB1 = P::FSEL( tyD1_X1, tvDS.Y(), -tvDS.Y() ); *ptyB2 = P::FSEL( tyD1_X2, tyZ, -tyZ ); break; } case 5: { // (+,0,+) tyDistSq += Box_DoF2( ptyLN0, &tvDS, tvDN, 0,2,1, tgBX0 ); const TYPE tyT1 = P::ABS( tvDS.Y() ) - tgBX0.Query_Extent1(); const TYPE tyY = P::FSEL( tyT1, P::Copy_Sign( tgBX0.Query_Extent1(), tvDS.Y() ), tvDS.Y() ); tyDistSq += P::FSEL( tyT1, tyT1*tyT1, TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tvDS.X(), -tvDS.X() ); *ptyB1 = P::FSEL( tyD1_X1, tyY, -tyY ); *ptyB2 = P::FSEL( tyD1_X2, tvDS.Z(), -tvDS.Z() ); break; } case 3: { // (0,+,+) tyDistSq += Box_DoF2( ptyLN0, &tvDS, tvDN, 1,2,0, tgBX0 ); const TYPE tyT0 = P::ABS( tvDS.X() ) - tgBX0.Query_Extent0(); const TYPE tyX = P::FSEL( tyT0, P::Copy_Sign( tgBX0.Query_Extent0(), tvDS.X() ), tvDS.X() ); tyDistSq += P::FSEL( tyT0, tyT0*tyT0,TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tyX, -tyX ); *ptyB1 = P::FSEL( tyD1_X1, tvDS.Y(), -tvDS.Y() ); *ptyB2 = P::FSEL( tyD1_X2, tvDS.Z(), -tvDS.Z() ); break; } case 4: { // (+,0,0) const TYPE tyT1 = P::ABS( tvDS.Y() ) - tgBX0.Query_Extent1(); const TYPE tyT2 = P::ABS( tvDS.Z() ) - tgBX0.Query_Extent2(); const TYPE tyY = P::FSEL( tyT1, P::Copy_Sign( tgBX0.Query_Extent1(), tvDS.Y() ), tvDS.Y() ); const TYPE tyZ = P::FSEL( tyT2, P::Copy_Sign( tgBX0.Query_Extent2(), tvDS.Z() ), tvDS.Z() ); tyDistSq += P::FSEL( tyT1, tyT1*tyT1,TYPE(0.0) ) + P::FSEL( tyT2, tyT2*tyT2,TYPE(0.0) ); *ptyB0 = TYPE(0.0); *ptyB1 = P::FSEL( tyD1_X1, tyY, -tyY ); *ptyB2 = P::FSEL( tyD1_X2, tyZ, -tyZ ); *ptyLN0 = -(tvDS.X() / tvDN.X()); break; } case 2: { // (0,+,0) const TYPE tyT0 = P::ABS( tvDS.X() ) - tgBX0.Query_Extent0(); const TYPE tyT2 = P::ABS( tvDS.Z() ) - tgBX0.Query_Extent2(); const TYPE tyX = P::FSEL( tyT0, P::Copy_Sign( tgBX0.Query_Extent0(), tvDS.X() ), tvDS.X() ); const TYPE tyZ = P::FSEL( tyT2, P::Copy_Sign( tgBX0.Query_Extent2(), tvDS.Z() ), tvDS.Z() ); tyDistSq += P::FSEL( tyT0, tyT0*tyT0,TYPE(0.0) ) + P::FSEL( tyT2, tyT2*tyT2,TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tyX, -tyX ); *ptyB1 = TYPE(0.0); *ptyB2 = P::FSEL( tyD1_X2, tyZ, -tyZ ); *ptyLN0 = -(tvDS.Y() / tvDN.Y()); break; } case 1: { // (0,0,+) const TYPE tyT0 = P::ABS( tvDS.X() ) - tgBX0.Query_Extent0(); const TYPE tyT1 = P::ABS( tvDS.Y() ) - tgBX0.Query_Extent1(); const TYPE tyX = P::FSEL( tyT0, P::Copy_Sign( tgBX0.Query_Extent0(), tvDS.X() ), tvDS.X() ); const TYPE tyY = P::FSEL( tyT1, P::Copy_Sign( tgBX0.Query_Extent1(), tvDS.Y() ), tvDS.Y() ); tyDistSq += P::FSEL( tyT0, tyT0*tyT0,TYPE(0.0) ) + P::FSEL( tyT1, tyT1*tyT1,TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tyX, -tyX ); *ptyB1 = P::FSEL( tyD1_X1, tyY, -tyY ); *ptyB2 = TYPE(0.0); *ptyLN0 = -(tvDS.Z() / tvDN.Z()); break; } case 0: { // (0,0,0) const TYPE tyT0 = P::ABS( tvDS.X() ) - tgBX0.Query_Extent0(); const TYPE tyT1 = P::ABS( tvDS.Y() ) - tgBX0.Query_Extent1(); const TYPE tyT2 = P::ABS( tvDS.Z() ) - tgBX0.Query_Extent2(); const TYPE tyX = P::FSEL( tyT0, P::Copy_Sign( tgBX0.Query_Extent0(), tvDS.X() ), tvDS.X() ); const TYPE tyY = P::FSEL( tyT1, P::Copy_Sign( tgBX0.Query_Extent1(), tvDS.Y() ), tvDS.Y() ); const TYPE tyZ = P::FSEL( tyT2, P::Copy_Sign( tgBX0.Query_Extent2(), tvDS.Z() ), tvDS.Z() ); tyDistSq += P::FSEL( tyT0, tyT0*tyT0,TYPE(0.0) ) + P::FSEL( tyT1, tyT1*tyT1,TYPE(0.0) ) + P::FSEL( tyT2, tyT2*tyT2,TYPE(0.0) ); *ptyB0 = P::FSEL( tyD1_X0, tyX, -tyX ); *ptyB1 = P::FSEL( tyD1_X1, tyY, -tyY ); *ptyB2 = P::FSEL( tyD1_X2, tyZ, -tyZ ); *ptyLN0 = TYPE(0.0); break; } }; if (bC0 && *ptyLN0 < TYPE(0.0)) { *ptyLN0 = TYPE(0.0); return (F_ClosestSq( ptyB0,ptyB1,ptyB2, tgBX0, tvS0 )); }; if (bC1 && *ptyLN0 > TYPE(1.0)) { *ptyLN0 = TYPE(1.0); return (F_ClosestSq( ptyB0,ptyB1,ptyB2, tgBX0, MATH::F_ADD( tvS0, tvD0 ) )); }; return (tyDistSq); }; // ============================================================================================================================== // // ---- F_Clip ------------------------------------------------------------------------------------------------------------------ // // -- Internal Function -- bC0, bC1 : Indicate the termination condition of the linear {bc0,bC1} // // Input: tgBX0: Box primitive // Input: tvS0,tvD0: Origin and Direction for the Linear // Output: tyLN0,tyLN1: Parametric parameter to generate the two points of the linear contained inside the clip space. // Return: Result Code. // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM, bool bC0, bool bC1> TgRESULT TTgCLP_BXLN<TYPE,DIM,bC0,bC1>::DO( TYPE *ptyLN0, TYPE *ptyLN1, CR_(BOX,DIM) tgBX0, M_(VECTOR,DIM) tvS0, M_(VECTOR,DIM) tvD0 ) { TgASSERT( tgBX0.Is_Valid() ); T_(VECTOR,DIM) tvDS = MATH::F_SUB( tvS0, tgBX0.Query_Origin() ); TYPE tyDS_N,tyD1_N; TYPE tyMin = -LIMITS<TYPE>::MAX; TYPE tyMax = LIMITS<TYPE>::MAX; // Quick out - Does the linear exist outside of the clip region. tyDS_N = MATH::F_DOT(tgBX0.Query_AxisUnit0(),tvDS); tyD1_N = MATH::F_DOT(tgBX0.Query_AxisUnit0(),tvD0); if (bC0 && tyDS_N < -tgBX0.Query_Extent0()) { if (tyD1_N < TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N < -tgBX0.Query_Extent0()))) { return (TgE_NOINTERSECT); }; } else if (bC0 && tyDS_N > tgBX0.Query_Extent0()) { if (tyD1_N > TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N > tgBX0.Query_Extent0()))) { return (TgE_NOINTERSECT); }; }; // Find the non-capped intersections of this linear with the two enclosing planes. if (tyD1_N < -LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyD1_N*tyMin - tgBX0.Query_Extent0(), (tgBX0.Query_Extent0() - tyDS_N) / tyD1_N, tyMin ); tyMax = P::FSEL( tyDS_N + tyD1_N*tyMax + tgBX0.Query_Extent0(), tyMax, -(tgBX0.Query_Extent0() + tyDS_N) / tyD1_N ); } else if (tyD1_N > LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyD1_N*tyMin + tgBX0.Query_Extent0(), tyMin, -(tgBX0.Query_Extent0() + tyDS_N) / tyD1_N ); tyMax = P::FSEL( tyDS_N + tyD1_N*tyMax - tgBX0.Query_Extent0(), (tgBX0.Query_Extent0() - tyDS_N) / tyD1_N, tyMax ); }; // Quick out - Does the linear exist outside of the clip region. tyDS_N = MATH::F_DOT(tgBX0.Query_AxisUnit1(),tvDS); tyD1_N = MATH::F_DOT(tgBX0.Query_AxisUnit1(),tvD0); if (bC0 && tyDS_N < -tgBX0.Query_Extent1()) { if (tyD1_N < TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N < -tgBX0.Query_Extent1()))) { return (TgE_NOINTERSECT); }; } else if (bC0 && tyDS_N > tgBX0.Query_Extent1()) { if (tyD1_N > TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N > tgBX0.Query_Extent1()))) { return (TgE_NOINTERSECT); }; }; // Find the non-capped intersections of this linear with the two enclosing planes. if (tyD1_N < -LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyD1_N*tyMin - tgBX0.Query_Extent1(), (tgBX0.Query_Extent1() - tyDS_N) / tyD1_N, tyMin ); tyMax = P::FSEL( tyDS_N + tyD1_N*tyMax + tgBX0.Query_Extent1(), tyMax, -(tgBX0.Query_Extent1() + tyDS_N) / tyD1_N ); } else if (tyD1_N > LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyD1_N*tyMin + tgBX0.Query_Extent1(), tyMin, -(tgBX0.Query_Extent1() + tyDS_N) / tyD1_N ); tyMax = P::FSEL( tyDS_N + tyD1_N*tyMax - tgBX0.Query_Extent1(), (tgBX0.Query_Extent1() - tyDS_N) / tyD1_N, tyMax ); }; // Quick out - Does the linear exist outside of the clip region. tyDS_N = MATH::F_DOT(tgBX0.Query_AxisUnit2(),tvDS); tyD1_N = MATH::F_DOT(tgBX0.Query_AxisUnit2(),tvD0); if (bC0 && tyDS_N < -tgBX0.Query_Extent2()) { if (tyD1_N < TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N < -tgBX0.Query_Extent2()))) { return (TgE_NOINTERSECT); }; } else if (bC0 && tyDS_N > tgBX0.Query_Extent2()) { if (tyD1_N > TYPE(0.0) || (bC1 && (tyDS_N + tyD1_N > tgBX0.Query_Extent2()))) { return (TgE_NOINTERSECT); }; }; // Find the non-capped intersections of this linear with the two enclosing planes. if (tyD1_N < -LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyMin*tyD1_N - tgBX0.Query_Extent2(), (tgBX0.Query_Extent2() - tyDS_N) / tyD1_N, tyMin ); tyMax = P::FSEL( tyDS_N + tyMax*tyD1_N + tgBX0.Query_Extent2(), tyMax, -(tgBX0.Query_Extent2() + tyDS_N) / tyD1_N ); } else if (tyD1_N > LIMITS<TYPE>::EPSILON) { tyMin = P::FSEL( tyDS_N + tyMin*tyD1_N + tgBX0.Query_Extent2(), tyMin, -(tgBX0.Query_Extent2() + tyDS_N) / tyD1_N ); tyMax = P::FSEL( tyDS_N + tyMax*tyD1_N - tgBX0.Query_Extent2(), (tgBX0.Query_Extent2() - tyDS_N) / tyD1_N, tyMax ); }; // Return the results - capped to the linear legal region. if (tyMin > tyMax || tyMin <= -LIMITS<TYPE>::MAX || tyMax >= LIMITS<TYPE>::MAX) { return (TgE_FAIL); }; if (bC0) { *ptyLN0 = P::FSEL( *ptyLN0, *ptyLN0, TYPE(0.0) ); *ptyLN1 = P::FSEL( *ptyLN1, *ptyLN1, TYPE(0.0) ); }; if (bC1) { *ptyLN0 = P::FSEL( *ptyLN0 - TYPE(1.0), *ptyLN0, TYPE(1.0) ); *ptyLN1 = P::FSEL( *ptyLN1 - TYPE(1.0), *ptyLN1, TYPE(1.0) ); }; return (TgS_OK); }; // ============================================================================================================================== // template struct TTgCSQ_BXLN<TgFLOAT32,4,0,0>; template struct TTgCSQ_BXLN<TgFLOAT32,4,1,0>; template struct TTgCSQ_BXLN<TgFLOAT32,4,1,1>; template struct TTgCLP_BXLN<TgFLOAT32,4,0,0>; template struct TTgCLP_BXLN<TgFLOAT32,4,1,0>; template struct TTgCLP_BXLN<TgFLOAT32,4,1,1>; // ============================================================================================================================== // }; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]