[an error occurred while processing this directive]
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // // Project: Talina Gaming System (TgS) (∂) // File: TgS Collision - Box-Box.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_Axis_Seperation ------------------------------------------------------------------------------------------------------- // // Input: tgBX0, tgBX1: Box primitives // Output: tgAxS: Structure holds the resulting axis separation information necessary to create a contact set. // Return: False if a separating axis exists, true otherwise // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TgBOOL F_Axis_Seperation( PC_(AXIS_RESULT,DIM) ptgAxS, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 ) { TYPE tyMinBox0, tyMaxBox0, tyMinBox1, tyMaxBox1; TgBOOL bUseAxis[3] = { TgTRUE, TgTRUE, TgTRUE }; // -- Axis: Box Face/Plane Normals ------------------------- for (TgUINT iIndex = 0; iIndex < 3; ++iIndex) { // Determine the extents of the primitives along the chosen axis. C_(VECTOR,DIM) &tvAxisUnit0 = tgBX0.Query_AxisUnit( iIndex ); const TYPE tyB0_AU = MATH::F_DOT( tgBX0.Query_Origin(), tvAxisUnit0 ); tyMinBox0 = tyB0_AU - tgBX0.Query_Extent( iIndex ); tyMaxBox0 = tyB0_AU + tgBX0.Query_Extent( iIndex ); tgBX1.Project( &tyMinBox1, &tyMaxBox1, tvAxisUnit0 ); if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test. { return (TgFALSE); }; { // Selection of the best (minimal depth) axis. const TYPE tyMinDepth = tyMaxBox1 - tyMinBox0; const TYPE tyMaxDepth = tyMaxBox0 - tyMinBox1; C_TgBOOL bNegAxis = tyMinDepth > tyMaxDepth; if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth) { ptgAxS->m_tvNormal = bNegAxis ? tvAxisUnit0 : MATH::F_NEG( tvAxisUnit0 ); ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth; ptgAxS->m_iAxis = bNegAxis ? iIndex + 3 : iIndex; }; }; // Check this unit axis of box 0 against the three axis of box 1. If there is a match then we mark this axis to // be ignored during the cross product phase. if ( Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit0(), tvAxisUnit0 ) ) || Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit1(), tvAxisUnit0 ) ) || Near_One( MATH::F_DOT( tgBX1.Query_AxisUnit2(), tvAxisUnit0 ) ) ) { bUseAxis[iIndex] = TgFALSE; }; // Determine the extents of the primitives along the chosen axis. C_(VECTOR,DIM) &tvAxisUnit1 = tgBX1.Query_AxisUnit( iIndex ); const TYPE tyB1_AU = MATH::F_DOT( tgBX1.Query_Origin(), tvAxisUnit1 ); tgBX0.Project( &tyMinBox0, &tyMaxBox0, tvAxisUnit1 ); tyMinBox1 = tyB1_AU - tgBX1.Query_Extent( iIndex ); tyMaxBox1 = tyB1_AU + tgBX1.Query_Extent( iIndex ); if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test. { return (TgFALSE); }; { // Selection of the best (minimal depth) axis. const TYPE tyMinDepth = tyMaxBox1 - tyMinBox0; const TYPE tyMaxDepth = tyMaxBox0 - tyMinBox1; C_TgBOOL bNegAxis = tyMinDepth > tyMaxDepth; if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth) { ptgAxS->m_tvNormal = bNegAxis ? tvAxisUnit1 : MATH::F_NEG( tvAxisUnit1 ); ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth; ptgAxS->m_iAxis = bNegAxis ? iIndex + 9 : iIndex + 6; }; }; }; // -- Axis: Axis-Box Cross Product ------------------------- for (TgUINT iBox0 = 0; iBox0 < 3; ++iBox0) { if (!bUseAxis[iBox0]) { continue; }; for (TgUINT iBox1 = 0; iBox1 < 3; ++iBox1) { // Axis is created by taking the cross product of the triangle edge and a box axis. T_(VECTOR,DIM) tvAxis; const TYPE tyAxis = MATH::F_UCX( &tvAxis, tgBX1.Query_AxisUnit( iBox1 ), tgBX0.Query_AxisUnit( iBox0 ) ); if (Near_Zero( tyAxis )) //« Sanity/Parallel check for the resulting vector. { continue; }; tgBX0.Project( &tyMinBox0, &tyMaxBox0, tvAxis ); tgBX1.Project( &tyMinBox1, &tyMaxBox1, tvAxis ); if (tyMaxBox1 < tyMinBox0 || tyMinBox1 > tyMaxBox0) //« Seperation Test. { return (TgFALSE); }; // Selection of the best (minimal depth) axis. const TYPE tyMinDepth = tyMaxBox1 - tyMinBox0; const TYPE tyMaxDepth = tyMaxBox0 - tyMinBox1; C_TgBOOL bNegAxis = tyMinDepth > tyMaxDepth; if ((bNegAxis ? tyMaxDepth : tyMinDepth) < ptgAxS->m_tyDepth) { ptgAxS->m_tvNormal = bNegAxis ? tvAxis : MATH::F_NEG( tvAxis ); ptgAxS->m_tyDepth = bNegAxis ? tyMaxDepth : tyMinDepth; ptgAxS->m_iAxis = iBox0*3 + iBox1 + (bNegAxis ? 21 : 12); }; }; }; return (TgTRUE); }; template TgBOOL F_Axis_Seperation( PC_TgF4AXIS_RESULT, CR_TgF4BOX, CR_TgF4BOX ); // ============================================================================================================================== // // ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------------------------------------------------ // template <typename TYPE, int DIM> TgRESULT F_Contact_Penetrate_BoxAxis1( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(AXIS_RESULT,DIM) tgAxS, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 ) { TTgAXIS_PROJECT<TYPE,DIM> tgConfig; F_Axis_ProjInfo( &tgConfig, tgAxS.m_tvNormal, tgBX0 ); switch (tgConfig.m_niMinDepth) { case 1: { //« Vertex-Face Contact //C_(VECTOR,DIM) &tvP0 = tgConfig.m_atvMinVert[0]; return (TgS_OK); }; case 2: { //« Edge-Face Contact return (TgS_OK); }; case 4: { //« Face-Face Contact return (TgS_OK); }; default: TgASSERT(TgFALSE); return (TgE_FAIL); }; return (TgE_FAIL); }; template TgRESULT F_Contact_Penetrate_BoxAxis1( PC_TgF4CONTACT_PACKET, CR_TgF4AXIS_RESULT, CR_TgF4BOX, CR_TgF4BOX ); // ============================================================================================================================== // // ---- F_Contact_Penetrate ----------------------------------------------------------------------------------------------------- // // Input: tgPacket: The current series of contact points for this query-series, and contact generation parameters. // Input: tgBX0: Box primitive // Input: tgBX1: Box - 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> //C_TgRESULT F_Contact_Penetrate( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(BOX,DIM) tgBX0, CR_(BOX,DIM) tgBX1 ) //{ // TgBLOCK_FCN_NOOBJ(ETgFAC_COLLISION, 0, ETgTEST_PENETRATE, (((TgUINT)ETgBOX<<16)|(TgUINT)ETgBOX)) // // TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) )) // TgASSERT(tgBX0.Is_Valid() && tgBX1.Is_Valid()) // // if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact) // { // return (TgE_FAIL); // }; // // // Find the minimal axis of separation, or return if the primitives are not in contact. // // TTgAXIS_RESULT<TYPE,DIM> tgAxS; // // if (!F_Axis_Seperation( tgAxS, tgBX0,tgBX1 )) // { // return (TgE_NOINTERSECT); // }; // // TgASSERT( Near_One( MATH::F_LSQ(tgAxS.tvNormal) ) && tgAxS.tyDepth >= TYPE(0.0) ) // // // == Contact Generation ==================================================================================================== // // // C_TgINT niContact = ptgPacket->m_niContact; // P_(CONTACT,DIM) ptgContact; // // if (tgAxS.iAxis >= 12) // { // } // else // { // if (tgAxS.iAxis >= 6) // { // return (F_Contact_Penetrate_BoxAxis( )); // } // else // { // return (F_Contact_Penetrate_BoxAxis( )); // }; // }; // // // // // return (TgE_FAIL); //}; // //template TgRESULT F_Contact_Penetrate( R_TgF4CONTACT_PACKET, CR_TgF4BOX, CR_TgF4BOX ); // ============================================================================================================================== // }; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]