[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // // Project: Talina Gaming System (TgS) (∂) // File: TgS Collision - Sphere-Point.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_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 primitives // Input: tvS0: Point // 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, M_(VECTOR,DIM) tvS0, CR_(SPHERE,DIM) tgSP0, CR_(DELTA,DIM) tgDT ) { TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_SWEEP, (((TgUINT)ETgPOINT<<16)|(TgUINT)ETgSPHERE)) TgASSERT( Is_Valid( tgDT ) && tgSP0.Is_Valid() && MATH::F_Is_Point_Valid( tvS0 ) ) TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) )) T_(VECTOR,DIM) tvDS = MATH::F_SUB( tvS0, tgSP0.Query_Origin() ); TYPE tyDS_DS = MATH::F_LSQ( tvDS ); if (tyDS_DS <= tgSP0.Query_RadiusSq()) { 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, tvS0,tgSP0 )) { return (TgE_PREPENETRATION_MAXCONTACTS); }; return (TgE_PREPENETRATION); }; TYPE tyTMPC = tgDT.m_tyDT - LIMITS<TYPE>::EPSILON; const TYPE tyDS_UDT = MATH::F_DOT(tvDS,tgDT.m_tvUDT); tyTMPC = P::FSEL( tyTMPC, tyDS_UDT - LIMITS<TYPE>::EPSILON, TYPE(-1.0) ); // Negligible distance towards each other. tyTMPC = P::FSEL( tyTMPC, tgSP0.Query_Radius() + *ptyPM*tgDT.m_tyDT - tyDS_UDT, TYPE(-1.0) ); // Separation along displacement tyTMPC = P::FSEL( tyTMPC, tgSP0.Query_RadiusSq() - tyDS_DS + tyDS_UDT*tyDS_UDT, TYPE(-1.0) ); // Orthogonal separation tyTMPC = P::FSEL( tyTMPC, tyDS_UDT - P::SQRT( tyTMPC ), TYPE(-1.0) ); // Time occurs after first time of contact. if (tyTMPC > (*ptyPM + ptgPacket->m_tySweepTol)*tgDT.m_tyDT) { return (TgE_NOINTERSECT); // Outside of sweep space. }; const TYPE tyT0 = tyTMPC / tgDT.m_tyDT; if (tyT0 < *ptyPM - ptgPacket->m_tySweepTol) { ptgPacket->m_niContact = 0; *ptyPM = tyT0; }; C_(VECTOR,DIM) tvS1 = MATH::F_ADD( tgSP0.Query_Origin(), MATH::F_MUL( tyTMPC, tgDT.m_tvUDT ) ); C_(VECTOR,DIM) tvNormal = MATH::F_NORM( MATH::F_SUB( tvS1, tvS0 ) ); 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( tvS1, MATH::F_MUL( tvNormal, tgSP0.Query_Radius() ) ); ptgContact->m_tvNormal = tvNormal; 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, M_TgF4VECTOR, CR_TgF4SPHERE, CR_TgF4DELTA ); // ============================================================================================================================== // }; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]