namespace TGS {
namespace COL {
template <typename TYPE, int DIM>
TgBOOL F_Axis_Seperation( PC_(AXIS_RESULT,DIM) ptgAxS, CR_(STRI,DIM) tgST0, CR_(CYLINDER,DIM) tgCY0 )
{
TgASSERT( tgCY0.Is_Valid() && tgST0.Is_Valid() )
TYPE tyMinCyl, tyMaxCyl, tyMinTri, tyMaxTri;
TYPE tyTest, tyMinDepth, tyMaxDepth;
const TYPE tyTriD = MATH::F_DOT(tgST0.Query_Origin(),tgST0.Query_Normal());
tgCY0.Project( &tyMinCyl, &tyMaxCyl, tgST0.Query_Normal() );
if (tyMaxCyl < tyTriD || tyMinCyl > tyTriD)
{
return (TgFALSE);
};
ptgAxS->m_tvNormal = MATH::F_NEG( tgST0.Query_Normal() );
ptgAxS->m_tyDepth = tyTriD - tyMinCyl;
ptgAxS->m_iAxis = 1;
const TYPE tyNormTest = MATH::F_DOT(tgST0.Query_Normal(),tgCY0.Query_AxisUnit());
if (!Near_One( tyNormTest ))
{
tyMinCyl = MATH::F_DOT(tgCY0.Query_Origin(),tgCY0.Query_AxisUnit());
tyMaxCyl = tyMinCyl + tgCY0.Query_Extent();
tyMinCyl -= tgCY0.Query_Extent();
tgST0.Project( &tyMinTri, &tyMaxTri, tgCY0.Query_AxisUnit() );
if (tyMaxCyl < tyMinTri || tyMinCyl > tyMaxTri)
{
return (TgFALSE);
};
tyMinDepth = tyMaxCyl - tyMinTri;
tyMaxDepth = tyMaxTri - tyMinCyl;
if (tyMinDepth > tyMaxDepth)
{
if (tyMaxDepth < ptgAxS->m_tyDepth)
{
ptgAxS->m_tvNormal = tgCY0.Query_AxisUnit();
ptgAxS->m_tyDepth = tyMaxDepth;
ptgAxS->m_iAxis = 2;
};
}
else
{
if (tyMinDepth < ptgAxS->m_tyDepth)
{
ptgAxS->m_tvNormal = MATH::F_NEG( tgCY0.Query_AxisUnit() );
ptgAxS->m_tyDepth = tyMinDepth;
ptgAxS->m_iAxis = 3;
};
};
};
TYPE tyET0,tyET1, tyCyl, tyDistSq;
tyDistSq = F_ClosestSq( &tyET0,&tyET1, &tyCyl, tgST0, tgCY0.Query_Segment() );
if (tyDistSq > tgCY0.Query_RadiusSq())
{
return (TgFALSE);
};
if (Is_Point_Culled( tgST0.Query_CT(), tyET0,tyET1 ))
{
return (TgTRUE);
};
C_(VECTOR,DIM) tvK0 = MATH::F_MUL( tyET0, tgST0.Query_Edge0() );
C_(VECTOR,DIM) tvK1 = MATH::F_MUL( tyET1, tgST0.Query_Edge2() );
T_(VECTOR,DIM) tvProxCyl, tvProxTri;
tvProxCyl = MATH::F_ADD( tgCY0.Query_Segment().Query_Origin(), MATH::F_MUL( tyCyl, tgCY0.Query_Segment().Query_DirN() ) );
tvProxTri = MATH::F_ADD( tgST0.Query_Origin(), MATH::F_SUB( tvK0, tvK1 ) );
if (Near_Zero( tyCyl ) || Near_One( tyCyl ) )
{
const TYPE tyDet = TYPE(1.0) - tyNormTest*tyNormTest;
if (tyDet <= LIMITS<TYPE>::ROOTEPSILON)
{
return (TgTRUE);
};
const TYPE tyInvDet = TYPE(1.0) / tyDet;
const TYPE tyCylD = MATH::F_DOT(tgCY0.Query_AxisUnit(),tvProxCyl);
const TYPE tyTA = tyInvDet*( tyCylD - tyNormTest*tyTriD );
const TYPE tyTB = tyInvDet*( tyTriD - tyNormTest*tyCylD );
TTgLINE<TYPE,DIM> tgLN;
tgLN.Set_Origin( MATH::F_ADD( MATH::F_MUL( tyTA, tgCY0.Query_AxisUnit() ), MATH::F_MUL( tyTB, tgST0.Query_Normal() ) ) );
tgLN.Set_DirN( MATH::F_CX( tgCY0.Query_AxisUnit(), tgST0.Query_Normal() ) );
TTgCLIP_LIST<TYPE,DIM> ClipList;
F_Clip( &ClipList, tgST0, tgLN );
if (ClipList.m_niPoint != 2)
{
return (TgTRUE);
};
TTgSEGMENT<TYPE,DIM> tgG0;
TYPE tyG0;
tgG0.Set_Origin( ClipList.m_ptvPoint[0] );
tgG0.Set_DirN( MATH::F_SUB( ClipList.m_ptvPoint[1], ClipList.m_ptvPoint[0] ) );
tyDistSq = F_ClosestSq( &tyG0, tgG0, tvProxCyl );
if (tyDistSq > tgCY0.Query_RadiusSq())
{
return (TgTRUE);
};
tvProxTri = MATH::F_ADD( tgG0.Query_Origin(), MATH::F_MUL( tyG0, tgG0.Query_DirN() ) );
};
T_(VECTOR,DIM) tvNormal = MATH::F_NORM( &tyTest, MATH::F_SUB( tvProxCyl, tvProxTri ) );
if (Near_Zero( tyTest ))
{
return (TgTRUE);
};
tyTest = P::FSEL( tgCY0.Query_Radius() - tyTest, tgCY0.Query_Radius() - tyTest, TYPE(0.0) );
if (1 == ptgAxS->m_iAxis && Near_One( MATH::F_DOT( tgST0.Query_Normal(), tvNormal ) ))
{
return (TgTRUE);
};
if (tyTest < ptgAxS->m_tyDepth)
{
ptgAxS->m_tvNormal = tvNormal;
ptgAxS->m_tvPoint = tvProxCyl;
ptgAxS->m_tyDepth = tyTest;
ptgAxS->m_iAxis = 4;
};
return (TgTRUE);
};
template TgBOOL F_Axis_Seperation( PC_TgF4AXIS_RESULT, CR_TgF4STRI, CR_TgF4CYLINDER );
template <typename TYPE, int DIM> TgFORCEINLINE
TgBOOL F_Internal_ClipTriToCyl( PC_(CLIP_LIST,DIM) ptgCL, CR_(STRI,DIM) tgST0, CR_(CYLINDER,DIM) tgCY0 )
{
TgBOOL bC0,bC1, bTest0,bTest1, bRet = TgFALSE;
TYPE tyT0,tyT1;
bRet |= TTgCLP_CYLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, tgCY0, tgST0.Query_Point0(),tgST0.Query_Edge0() );
bC0 = Near_Zero( tyT0 );
bC1 = Near_One( tyT0 );
bTest0 = (bC0 && !tgST0.Test_Point0()) || (bC1 && !tgST0.Test_Point1()) || (!bC0 && !bC1 && !tgST0.Test_Edge0());
bC0 = Near_Zero( tyT1 );
bC1 = Near_One( tyT1 );
bTest1 = (bC0 && !tgST0.Test_Point0()) || (bC1 && !tgST0.Test_Point1()) || (!bC0 && !bC1 && !tgST0.Test_Edge0());
if (!bTest0)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point0(), MATH::F_MUL( tyT0, tgST0.Query_Edge0() ) );
};
if (!bTest1)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point0(), MATH::F_MUL( tyT1, tgST0.Query_Edge0() ) );
};
bRet |= TTgCLP_CYLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, tgCY0, tgST0.Query_Point1(),tgST0.Query_Edge1() );
bC0 = Near_Zero( tyT0 );
bC1 = Near_One( tyT0 );
bTest0 = (bC0 && !tgST0.Test_Point1()) || (bC1 && !tgST0.Test_Point2()) || (!bC0 && !bC1 && !tgST0.Test_Edge1());
bC0 = Near_Zero( tyT1 );
bC1 = Near_One( tyT1 );
bTest1 = (bC0 && !tgST0.Test_Point1()) || (bC1 && !tgST0.Test_Point2()) || (!bC0 && !bC1 && !tgST0.Test_Edge1());
if (!bTest0)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point1(), MATH::F_MUL( tyT0, tgST0.Query_Edge1() ) );
};
if (!bTest1)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point1(), MATH::F_MUL( tyT1, tgST0.Query_Edge1() ) );
};
bRet |= TTgCLP_CYLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, tgCY0, tgST0.Query_Point2(),tgST0.Query_Edge2() );
bC0 = Near_Zero( tyT0 );
bC1 = Near_One( tyT0 );
bTest0 = (bC0 && !tgST0.Test_Point2()) || (bC1 && !tgST0.Test_Point0()) || (!bC0 && !bC1 && !tgST0.Test_Edge2());
bC0 = Near_Zero( tyT1 );
bC1 = Near_One( tyT1 );
bTest1 = (bC0 && !tgST0.Test_Point2()) || (bC1 && !tgST0.Test_Point0()) || (!bC0 && !bC1 && !tgST0.Test_Edge2());
if (!bTest0)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point2(), MATH::F_MUL( tyT0, tgST0.Query_Edge2() ) );
};
if (!bTest1)
{
ptgCL->m_ptvPoint[ptgCL->m_niPoint++] = MATH::F_ADD( tgST0.Query_Point2(), MATH::F_MUL( tyT1, tgST0.Query_Edge2() ) );
};
return (bRet);
};
template <typename TYPE, int DIM>
TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(STRI,DIM) tgST0, CR_(CYLINDER,DIM) tgCY0 )
{
TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgCAPSULE<<16)|(TgUINT)ETgTRIANGLE))
TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof(T_(CONTACT,DIM)) && tgCY0.Is_Valid() && tgST0.Is_Valid())
if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact)
{
return (TgE_FAIL);
};
TgFEBUG_COLLISION_TRIANGLE_CREATEID( iDBG_TriID, tgST0, etgDEBUG_COLLISION_ENTERFCN );
C_(VECTOR,DIM) tvK0 = MATH::F_SUB( tgCY0.Query_Origin(), tgST0.Query_Origin() );
const TYPE tyDS_N = MATH::F_DOT( tgST0.Query_Normal(), tvK0 );
const TYPE tyEX_N = MATH::F_DOT( tgST0.Query_Normal(), tgCY0.Query_HalfAxis() );
const TYPE tyS0_N = tyDS_N - tyEX_N;
const TYPE tyS1_N = tyDS_N + tyEX_N;
const TYPE tyRadius = tgCY0.Query_Radius();
if ((tyS0_N > tyRadius && tyS1_N > tyRadius) || (tyS0_N < TYPE(0.0) && tyS1_N < TYPE(0.0)))
{
return (TgE_NOINTERSECT);
};
TgFEBUG_COLLISION_TRIANGLE( iDBG_TriID, etgDEBUG_COLLISION_PASSED_REJECT );
TTgAXIS_RESULT<TYPE,DIM> tgAxS;
if (!F_Axis_Seperation( &tgAxS, tgST0,tgCY0 ))
{
return (TgE_NOINTERSECT);
};
TgASSERT( Near_One( MATH::F_LSQ(tgAxS.m_tvNormal) ) && tgAxS.m_tyDepth >= TYPE(0.0) )
P_(CONTACT,DIM) ptgContact;
if (tgAxS.m_iAxis >= 4)
{
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_SUB( tgAxS.m_tvPoint, MATH::F_MUL( tgCY0.Query_Radius(), tgAxS.m_tvNormal ) );
ptgContact->m_tvNormal = tgAxS.m_tvNormal;
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tgAxS.m_tyDepth;
++ptgPacket->m_niContact;
return (TgS_OK);
};
if (tgAxS.m_iAxis >= 2)
{
T_(CLIP_LIST,DIM) tgCL;
if (F_Internal_ClipTriToCyl( &tgCL, tgST0,tgCY0 ) && 0 == tgCL.m_niPoint)
{
return (TgE_NOINTERSECT);
};
C_TgINT niMax = MIN( tgCL.m_niPoint, ptgPacket->m_niMaxContact - ptgPacket->m_niContact );
P_(CONTACT,DIM) ptgContact;
for (TgINT iIdx = 0; iIdx < niMax; ++iIdx)
{
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
C_(VECTOR,DIM) tvK1 = MATH::F_SUB( tgCL.m_ptvPoint[iIdx], tgCY0.Query_Origin() );
const TYPE tyP_AX = MATH::F_DOT( tvK1, tgCY0.Query_AxisUnit() );
TYPE tyDepth = tgCY0.Query_Extent() - P::ABS( tyP_AX );
tyDepth = P::FSEL( tyDepth, tyDepth, TYPE(0.0) );
ptgContact->m_tvPos = MATH::F_SUB( tgCL.m_ptvPoint[iIdx], MATH::F_MUL( tyDepth, tgAxS.m_tvNormal ) );
ptgContact->m_tvNormal = tgAxS.m_tvNormal;
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyDepth;
++ptgPacket->m_niContact;
};
if (0 != tgCL.m_niPoint)
{
return (niMax == tgCL.m_niPoint ? TgS_OK : TgS_MAXCONTACTS);
};
};
const TYPE tyAX_N = MATH::F_DOT(tgCY0.Query_AxisUnit(),tgST0.Query_Normal());
M_(VECTOR,DIM) tvBX0 = tgCY0.Query_BasisUnit0();
M_(VECTOR,DIM) tvBX1 = tgCY0.Query_BasisUnit1();
T_(VECTOR,DIM) tvT0, tvX0;
TYPE tyX,tyY,tyZ;
const TYPE tyUseBX = P::ABS( tyAX_N ) - (TYPE(1.0) - LIMITS<TYPE>::EPSILON);
tvT0 = MATH::F_SUB( MATH::F_MUL( tyAX_N, tgCY0.Query_AxisUnit() ), tgST0.Query_Normal() );
tyX = P::FSEL( tyUseBX, tvBX0.X(), tvT0.X() );
tyY = P::FSEL( tyUseBX, tvBX0.Y(), tvT0.Y() );
tyZ = P::FSEL( tyUseBX, tvBX0.Z(), tvT0.Z() );
tvX0 = MATH::F_NORM( MATH::F_SETV<TYPE,DIM>( tyX,tyY,tyZ ) );
const TYPE tyDN = P::FSEL( tyAX_N, TYPE(-1.0), TYPE(1.0) );
C_(VECTOR,DIM) tvC0 = MATH::F_ADD( tgCY0.Query_Origin(), MATH::F_MUL( tyDN, tgCY0.Query_HalfAxis() ) );
if (tyAX_N > TYPE(0.5))
{
T_(VECTOR,DIM) tvX1;
tvT0 = MATH::F_CX( tvX0, tgCY0.Query_AxisUnit() );
tyX = P::FSEL( tyUseBX, tvBX1.X(), tvT0.X() );
tyY = P::FSEL( tyUseBX, tvBX1.Y(), tvT0.Y() );
tyZ = P::FSEL( tyUseBX, tvBX1.Z(), tvT0.Z() );
tvX1 = MATH::F_SETV<TYPE,DIM>( tyX,tyY,tyZ );
MATH::F_NORM( tvX1 );
tvX1 = MATH::F_MUL( tvX1, KF32_SQRT3 );
TYPE tyT0,tyT1, tyTest;
TgINT iCode;
C_TgINT niContact = ptgPacket->m_niContact;
tvT0 = MATH::F_MUL( tgCY0.Query_Radius(), tvX0 );
if (TTgCLF_STLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, &iCode, tgST0, tvC0,tvT0 ) >= 0 && 0 != (iCode & 12))
{
const TYPE tyL0 = 0 != (iCode & 4) ? tyT0 : -tyT1;
const TYPE tyL1 = 0 != (iCode & 8) ? tyT1 : -tyT0;
const TYPE tyLN = P::FSEL( tyL1 - tyL0, tyL1, tyL0 );
C_(VECTOR,DIM) tvK1 = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK1 ), tgST0.Query_Normal() );
if (tyTest >= TYPE(0.0))
{
if (ptgPacket->m_niContact >= ptgPacket->m_niMaxContact)
{
return (TgS_MAXCONTACTS);
};
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
};
tvT0 = MATH::F_MUL( TYPE(-0.5)*tgCY0.Query_Radius(), MATH::F_ADD( tvX0, tvX1 ) );
if (TTgCLF_STLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, &iCode, tgST0, tvC0,tvT0 ) >= 0 && 0 != (iCode & 12))
{
const TYPE tyL0 = 0 != (iCode & 4) ? tyT0 : -tyT1;
const TYPE tyL1 = 0 != (iCode & 8) ? tyT1 : -tyT0;
const TYPE tyLN = P::FSEL( tyL1 - tyL0, tyL1, tyL0 );
C_(VECTOR,DIM) tvK1 = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK1 ), tgST0.Query_Normal() );
if (tyTest >= TYPE(0.0))
{
if (ptgPacket->m_niContact >= ptgPacket->m_niMaxContact)
{
return (TgS_MAXCONTACTS);
};
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
};
tvT0 = MATH::F_MUL( TYPE(-0.5)*tgCY0.Query_Radius(), MATH::F_SUB( tvX0, tvX1 ) );
if (TTgCLF_STLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, &iCode, tgST0, tvC0,tvT0 ) >= 0 && 0 != (iCode & 12))
{
const TYPE tyL0 = 0 != (iCode & 4) ? tyT0 : -tyT1;
const TYPE tyL1 = 0 != (iCode & 8) ? tyT1 : -tyT0;
const TYPE tyLN = P::FSEL( tyL1 - tyL0, tyL1, tyL0 );
C_(VECTOR,DIM) tvK1 = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK1 ), tgST0.Query_Normal() );
if (tyTest >= TYPE(0.0))
{
if (ptgPacket->m_niContact >= ptgPacket->m_niMaxContact)
{
return (TgS_MAXCONTACTS);
};
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tvC0, MATH::F_MUL( tyLN, tvT0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
};
if (niContact != ptgPacket->m_niContact)
{
return (TgS_OK);
};
T_(CLIP_LIST,DIM) tgCL;
F_Internal_ClipTriToCyl( &tgCL, tgST0,tgCY0 );
if (0 == tgCL.m_niPoint)
{
return (TgE_NOINTERSECT);
};
C_TgINT niMax = MIN( tgCL.m_niPoint, ptgPacket->m_niMaxContact - ptgPacket->m_niContact );
tvT0 = MATH::F_MUL( TYPE(-2.0)*tgCY0.Query_Extent(), tgST0.Query_Normal() );
for (TgINT iIdx = 0; iIdx < niMax; ++iIdx)
{
if (TTgCLP_CYLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, tgCY0, tgCL.m_ptvPoint[iIdx],tvT0 ) < 0)
{
continue;
};
if (ptgPacket->m_niContact >= ptgPacket->m_niMaxContact)
{
return (TgS_MAXCONTACTS);
};
const TYPE tyLN = P::FSEL( tyT1 - tyT0, tyT1, tyT0 );
C_(VECTOR,DIM) tvK2 = MATH::F_ADD( tgCL.m_ptvPoint[iIdx], MATH::F_MUL( tyLN, tvT0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK2 ), tgST0.Query_Normal() );
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tgCL.m_ptvPoint[iIdx], MATH::F_MUL( tyLN, tvT0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
return (niContact != ptgPacket->m_niContact ? TgS_OK : TgE_NOINTERSECT);
}
else
{
C_(VECTOR,DIM) tvD0 = MATH::F_MUL( TYPE(-2.0)*tyDN, tgCY0.Query_HalfAxis() );
C_(VECTOR,DIM) tvS0 = MATH::F_ADD( tvC0, tvX0 );
TYPE tyTest, tyT0,tyT1;
C_TgINT niContact = ptgPacket->m_niContact;
TgINT iCode;
if (TTgCLF_STLN<TYPE,DIM,1,1>::DO( &tyT0,&tyT1, &iCode,tgST0, tvS0,tvD0 ) < 0 || 0 == (iCode & 12))
{
return (TgE_NOINTERSECT);
};
C_(VECTOR,DIM) tvK1 = MATH::F_ADD( tvS0, MATH::F_MUL( tyT0, tvD0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK1 ), tgST0.Query_Normal() );
if (0 == (iCode & 4) && tyTest >= TYPE(0.0))
{
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tvS0, MATH::F_MUL( tyT0, tvD0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
C_(VECTOR,DIM) tvK2 = MATH::F_ADD( tvS0, MATH::F_MUL( tyT1, tvD0 ) );
tyTest = MATH::F_DOT( MATH::F_SUB( tgST0.Query_Origin(), tvK2 ), tgST0.Query_Normal() );
if (0 == (iCode & 8) && tyTest >= TYPE(0.0))
{
if (ptgPacket->m_niContact >= ptgPacket->m_niMaxContact)
{
return (TgS_MAXCONTACTS);
};
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tvS0, MATH::F_MUL( tyT1, tvD0 ) );
ptgContact->m_tvNormal = tgST0.Query_Normal();
ptgContact->m_tyT0 = TYPE(0.0);
ptgContact->m_tyDepth = tyTest;
++ptgPacket->m_niContact;
};
return (niContact != ptgPacket->m_niContact ? TgS_OK : TgE_NOINTERSECT);
};
};
template TgRESULT F_Contact_Penetrate( PC_TgF4CONTACT_PACKET, CR_TgF4STRI, CR_TgF4CYLINDER );
};
};