[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // // Project: Talina Gaming System (TgS) (∂) // File: TgS Collision - Sphere-Plane.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 /////////////////////////////////////////////////////////////////////////////////////////////////////// // ============================================================================================================================== // // ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- // // Input: tgPacket: The current series of contact points for this query-series, and contact generation parameters. // Input: tgSP0: Sphere primitive // Input: tgPN0: Plane primitive - contact points are generated on this primitive // Output: tgPacket: Points of penetration between the two primitives are added to it // Return: Result Code // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(SPHERE,DIM) tgSP0, CR_(PLANE,DIM) tgPN0 ) { TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgSPHERE<<16)|(TgUINT)ETgPLANE)) TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) )) TgASSERT(tgSP0.Is_Valid() && tgPN0.Is_Valid()) if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact) { return (TgE_FAIL); }; const TYPE tyDist = F_Sign_Dist( tgPN0, tgSP0.Query_Origin() ); if (tyDist > tgSP0.Query_Radius()) { return (TgE_NOINTERSECT); }; P_(CONTACT,DIM) ptgContact; ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride); ptgContact->m_tvPos = MATH::F_SUB( tgSP0.Query_Origin(), MATH::F_MUL( tyDist, tgPN0.Query_Normal() ) ); ptgContact->m_tvNormal = tgPN0.Query_Normal(); ptgContact->m_tyT0 = TYPE(0.0); ptgContact->m_tyDepth = tgSP0.Query_Radius() - tyDist; ++ptgPacket->m_niContact; return (TgS_OK); }; template TgRESULT F_Contact_Penetrate( PC_TgF4CONTACT_PACKET, CR_TgF4SPHERE, CR_TgF4PLANE ); // ============================================================================================================================== // // ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- // // Input: tgPacket: The current series of contact points for this query-series, and contact generation parameters. // Input: tgPN0: Plane primitive // Input: tgSP0: Sphere primitive - contact points are generated on this primitive // Output: tgPacket: Points of penetration between the two primitives are added to it // Return: Result Code // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(PLANE,DIM) tgPN0, CR_(SPHERE,DIM) tgSP0 ) { TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgPLANE<<16)|(TgUINT)ETgSPHERE)) TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) )) TgASSERT(tgSP0.Is_Valid() && tgPN0.Is_Valid()) if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact) { return (TgE_FAIL); }; const TYPE tyDist = F_Sign_Dist( tgPN0, tgSP0.Query_Origin() ); if (tyDist > tgSP0.Query_Radius()) { return (TgE_NOINTERSECT); }; P_(CONTACT,DIM) ptgContact; ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride); ptgContact->m_tvPos = MATH::F_SUB( tgSP0.Query_Origin(), MATH::F_MUL( tgSP0.Query_Radius(), tgPN0.Query_Normal() ) ); ptgContact->m_tvNormal = tgPN0.Query_Normal(); ptgContact->m_tyT0 = TYPE(0.0); ptgContact->m_tyDepth = tgSP0.Query_Radius() - tyDist; ++ptgPacket->m_niContact; return (TgS_OK); }; template TgRESULT F_Contact_Penetrate( PC_TgF4CONTACT_PACKET, CR_TgF4PLANE, CR_TgF4SPHERE ); // ============================================================================================================================== // // ---- F_Contact_Sweep --------------------------------------------------------------------------------------------------------- // // Input: tgPacket: The current series of contact points for this query-series, and contact generation parameters. // Input: tyPM: Current normalized time of first contact. // Input: bPenetrate: If the swept primitives are in penetration, if true the function will return points of penetration. // Input: tgSP0: Sphere primitive // Input: tgPN0: Plane primitive // Input: tgDT: A structure holding the swept primitive displacement for the entire duration of the test period // Output: tgPacket: Contact points are added or replace the current set depending on the time comparison and given parameters // Output: tyPM: New normalized time of first contact // Return: Result Code // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TgRESULT F_Contact_Sweep( PC_(CONTACT_PACKET,DIM) ptgPacket, TYPE *ptyPM, CR_(PLANE,DIM) tgPN0, CR_(SPHERE,DIM) tgSP0, CR_(DELTA,DIM) tgDT ) { TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_SWEEP, (((TgUINT)ETgSPHERE<<16)|(TgUINT)ETgPLANE)) TgASSERT(tgSP0.Is_Valid() && tgPN0.Is_Valid()) if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact) { return (TgE_FAIL); }; const TYPE tyDist = F_Sign_Dist( tgPN0, tgSP0.Query_Origin() ); if (tyDist <= tgSP0.Query_Radius()) { if (*ptyPM > ptgPacket->m_tySweepTol) { ptgPacket->m_niContact = 0; }; *ptyPM = TYPE(0.0); C_TgBOOL bPenetrate = TgTRUE == ptgPacket->m_bReport_Penetration; if (bPenetrate && TgS_MAXCONTACTS == F_Contact_Penetrate( ptgPacket, tgPN0, tgSP0 )) { return (TgE_PREPENETRATION_MAXCONTACTS); }; return (TgE_PREPENETRATION); }; const TYPE tyDT_N = -MATH::F_DOT(tgDT.m_tvDT,tgPN0.Query_Normal()); if (tyDT_N <= TYPE(0.0)) { return (TgE_NOINTERSECT); }; const TYPE tyT0 = (tyDist - tgSP0.Query_Radius()) / tyDT_N; if (tyT0 > *ptyPM + ptgPacket->m_tySweepTol) { return (TgE_NOINTERSECT); }; if (tyT0 < *ptyPM - ptgPacket->m_tySweepTol) { ptgPacket->m_niContact = 0; *ptyPM = tyT0; }; P_(CONTACT,DIM) ptgContact; ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride); C_(VECTOR,DIM) tvK0 = MATH::F_ADD( tgSP0.Query_Origin(), MATH::F_MUL( tyT0, tgDT.m_tvDT ) ); ptgContact->m_tvPos = MATH::F_SUB( tvK0, MATH::F_MUL( tgSP0.Query_Radius(), tgPN0.Query_Normal() ) ); ptgContact->m_tvNormal = tgPN0.Query_Normal(); ptgContact->m_tyT0 = tyT0; ptgContact->m_tyDepth = TYPE(0.0); ++ptgPacket->m_niContact; return (TgS_OK); }; template TgRESULT F_Contact_Sweep( PC_TgF4CONTACT_PACKET, P_TgFLOAT32, CR_TgF4PLANE, CR_TgF4SPHERE, CR_TgF4DELTA ); // ============================================================================================================================== // }; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]