[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // // Project: Talina Gaming System (TgS) (∂) // File: TgS Collision - Cylinder-Sphere.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: tgCY0: Cylinder 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_(CYLINDER,DIM) tgCY1 ) { TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgSPHERE<<16)|(TgUINT)ETgCYLINDER)) TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) )) TgASSERT(tgCY1.Is_Valid() && tgSP0.Is_Valid()) if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact) { return (TgE_FAIL); }; T_(VECTOR,DIM) tvDS = MATH::F_SUB( tgCY1.Query_Origin(), tgSP0.Query_Origin() ); // Separating Axis - Cylindrical Principal Axis. const TYPE tyDS_AX = MATH::F_DOT(tvDS,tgCY1.Query_AxisUnit()); TYPE tyDepth; tyDepth = tgCY1.Query_Extent() + tgSP0.Query_Radius() - P::ABS(tyDS_AX); if (tyDepth < TYPE(0.0)) { return (TgE_NOINTERSECT); }; T_(VECTOR,DIM) tvNormal; tvNormal = tyDS_AX < TYPE(0.0) ? MATH::F_NEG( tgCY1.Query_AxisUnit() ) : tgCY1.Query_AxisUnit(); // Separating Axis - Cylindrical Radial Axis. TYPE tyRT, tyTest; C_(VECTOR,DIM) tvK0 = MATH::F_MUL( tyDS_AX, tgCY1.Query_AxisUnit() ); T_(VECTOR,DIM) tvRT = MATH::F_NORM( &tyRT, MATH::F_SUB( tvDS, tvK0 ) ); tyTest = tgCY1.Query_Radius() + tgSP0.Query_Radius() - tyRT; if (tyTest < TYPE(0.0)) { return (TgE_NOINTERSECT); } if (tyTest < tyDepth) { tyDepth = tyTest; tvNormal = tvRT; }; // Separating Axis - Minimal Axis Connecting Cylindrical Ring and Sphere Centre. // Dev Note: The origin of the sphere is restricted to being outside of the cylinder. This biases the contact away from rim // collisions, and prevents having to do directional analysis to determine the contact depth. if (P::ABS(tyDS_AX) > tgCY1.Query_Extent() && tyRT > tgCY1.Query_Radius()) { T_(VECTOR,DIM) tvRIM; tvDS = MATH::F_NORM( tvDS ); tvRIM = MATH::F_NORM( &tyTest, MATH::F_SUB( tgCY1.Calc_Support_Point( MATH::F_NEG( tvDS ) ), tgSP0.Query_Origin() ) ); tyTest = tgSP0.Query_Radius() - tyTest; if (tyTest < TYPE(0.0)) { return (TgE_NOINTERSECT); }; if (tyTest < tyDepth) { tyDepth = tyTest; tvNormal = tvRIM; }; }; P_(CONTACT,DIM) ptgContact; ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride); ptgContact->m_tvPos = MATH::F_ADD( tgSP0.Query_Origin(), MATH::F_MUL( tvNormal, tgSP0.Query_Radius() - tyDepth ) ); ptgContact->m_tvNormal = tvNormal; ptgContact->m_tyT0 = TYPE(0.0); ptgContact->m_tyDepth = tyDepth; ++ptgPacket->m_niContact; return (TgS_OK); }; template TgRESULT F_Contact_Penetrate( PC_TgF4CONTACT_PACKET, CR_TgF4SPHERE, CR_TgF4CYLINDER ); // ============================================================================================================================== // }; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]