[an error occurred while processing this directive]
//// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // //// //// Project: Talina Gaming System (TgS) (∂) //// File: TgS Collision - Box AA-Particle.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 /////////////////////////////////////////////////////////////////////////////////////////////////////// // //// ============================================================================================================================== // // //template <typename TYPE, int DIM> //TgBOOL F_Contact_Test( TYPE *ptyT0, TYPE *ptyT1, CR_(BOXAA,DIM) tgBA0, CR_(PARTICLE,DIM) tgPC0 ) //{ // return (F_Contact_Test_BAPC( // ptyT0, ptyT1, tgBA0.Query_Max() - tgBA0.Query_Min(), // tgPC0.Query_Position() - tgBA0.Query_Origin(), tgPC0.Query_Velocity(), tgPC0.Query_Acceleration() // )); //}; // // // // //template <typename TYPE, int DIM> //TgBOOL F_Contact_Test_BAPC( TYPE *ptyT0, TYPE *ptyT1, M_(VECTOR,DIM) tvE, M_(VECTOR,DIM) tvS, M_(VECTOR,DIM) tvV, M_(VECTOR,DIM) tvA ) //{ // T_(VECTOR,DIM) tvBB,tvAP,tvAN,tvAX, tvD0,tvD1; // // // Do a parabolic solve for each of the three axes independently. Then compare the overlap of the three generated intervals // // to determine if there is one intersecting interval for all three axes that converge on the AABB. // // C_(VECTOR,DIM) tv4A = TYPE(4.0)*tvA; // C_(VECTOR,DIM) tv2A = TYPE(2.0)*tvA; // // MATH::F_MUL( tvBB, tvV, tvV ); //« B•B // MATH::F_MUL( tvAP, tv4A, tvS ); //« 4•A•P // MATH::F_MUL( tvAN, tv4A, -tvE ); //« 4•A•MIN // MATH::F_MUL( tvAX, tv4A, tvE ); //« 4•A•MAX // // F_ADD( tvD0, tvBB, MATH::F_SUB(tvAN, tvAP) ); //« B•B - 4•A_(P - MIN,DIM) // MATH::F_SQRT( tvD0 ); // F_ADD( tvD1, tvBB, MATH::F_SUB(tvAX, tvAP) ); //« B•B - 4•A_(P - MAX,DIM) // MATH::F_SQRT( tvD1 ); // // T_(VECTOR,DIM) tvTN0,tvTN1,tvTX0,tvTX1; // // // T values for when the particle is equal to minimum axes values of AABB // // tvTN0 = MATH::F_DIV( F_NEG( F_ADD( tvD0, tvV ) ), tv2A ); //« (-B - √(B•B - 4•A_(P - MIN,DIM))) / 2A // tvTN1 = MATH::F_DIV( MATH::F_SUB( tvD0, tvV ), tv2A ); //« (-B + √(B•B - 4•A_(P - MIN,DIM))) / 2A // // // T values for when the particle is equal to maximum axes values of AABB // // tvTX0 = MATH::F_DIV( F_NEG( F_ADD( tvD1, tvV ) ), tv2A ); //« (-B - √(B•B - 4•A_(P - MAX,DIM))) / 2A // tvTX1 = MATH::F_DIV( MATH::F_SUB( tvD1, tvV ), tv2A ); //« (-B + √(B•B - 4•A_(P - MAX,DIM))) / 2A // // // The solution to a quadratic equation can be one of the three possible solution sets: two independent root values, one // // common root value, and two complex solutions. That would mean that a trivial examination of the solution set shows a // // possible nine different solution configurations. However, the geometry of the problem itself lets us break down these // // cases to just a handful. // // 1. Both solutions have real roots: This means that the particle passes through the box in two indepedent passes on this // // axis. The interval tested will have to be branched to test possible overlaps for each interval independently. // // 2. Both solution have complex solutions: The particle does not intersect the box on this axis at all. The test can be // // terminated at this point since its impossible for the particle to pass through the box. // // 3. A combination of a complex solution and a real solution (either one or two roots): This means that the particle must // // pass through the interval limit at least once without passing through the opposite interval limit. The implication // // is that the particle is actually contained inside the box on this interval - thus, allowing for the possibility of it // // potentially passing through the plane defined by the interval limit twice without ever passing the other limit value. // // // Order the time values so that we have a min time vector and a max time vector // // T_(VECTOR,DIM) tvM0,tvM1, tvTA,tvTB, tvTNN,tvTNX,tvTXN,tvTXX; // // MATH::F_CMP_GT( tvM0, tvTN0, tvTN1 ); // MATH::F_CMP_GT( tvM1, tvTX0, tvTX1 ); // // MATH::F_OR( tvTNX, MATH::F_AND( tvTA, tvTN0, tvM0 ), MATH::F_NAND( tvTB, tvTN1, tvM0 ) ); //« Max-Min Roots // MATH::F_OR( tvTXX, MATH::F_AND( tvTA, tvTX0, tvM1 ), MATH::F_NAND( tvTB, tvTX1, tvM1 ) ); //« Max-Max Roots // MATH::F_OR( tvTNN, MATH::F_NAND( tvTA, tvTN0, tvM0 ), MATH::F_AND( tvTB, tvTN1, tvM0 ) ); //« Min-Min Roots // MATH::F_OR( tvTXN, MATH::F_NAND( tvTA, tvTX0, tvM1 ), MATH::F_AND( tvTB, tvTX1, tvM1 ) ); //« Min-Max Roots // // // If a complex solution is found, then both roots must be complex so its only necessary to test one of the vectors. // // MATH::F_OR( tvM0, MATH::F_CMP_GE( tvTA, tvTNX, T_(VECTOR,DIM)::ZERO ), MATH::F_CMP_LE( tvTB, tvTNX, T_(VECTOR,DIM)::ZERO ) ); //« NaN Test // MATH::F_OR( tvM1, MATH::F_CMP_GE( tvTA, tvTXX, T_(VECTOR,DIM)::ZERO ), MATH::F_CMP_LE( tvTB, tvTXX, T_(VECTOR,DIM)::ZERO ) ); //« NaN Test // // // The possible solutions sets can produce the following interval setups: // // 1. Two independent intervals: In this case the elements in the max-min and min-min solutions will form one interval and // // the other interval be from the max-min and max-max vectors. // // 2. One interval: This interval will either be from min-max to max-min or from min-min to max-max. The determination will // // be based on the ordering of the roots from the solution sets. If the max-min vector is contained inside of the max // // domain then the solution must be the min-max to max-min set. However, if the min-max root is contained inside of the // // min domain then the other solution must be true. // // 3. No possible interval // // MATH::F_CMP_GE( tvTA, tvTXN, tvTNX ); // If I have 2 or 1 solutions - do I need it? // // // // // // // // // // MATH::F_AND( tvT0, MATH::F_NAND( MATH::F_CMP_GT( tvTA, tvT0, tvT1 ), MATH::F_CMP_GE( tvTB, tvT0, T_(VECTOR,DIM)::ZERO ) ) ); // MATH::F_AND( tvT1, MATH::F_NAND( MATH::F_CMP_GE( tvTA, tvT1, tvT0 ), MATH::F_CMP_GE( tvTB, tvT1, T_(VECTOR,DIM)::ZERO ) ) ); // MATH::F_AND( tvT2, MATH::F_NAND( MATH::F_CMP_GT( tvTA, tvT2, tvT3 ), MATH::F_CMP_GE( tvTB, tvT2, T_(VECTOR,DIM)::ZERO ) ) ); // MATH::F_AND( tvT3, MATH::F_NAND( MATH::F_CMP_GE( tvTA, tvT3, tvT2 ), MATH::F_CMP_GE( tvTB, tvT3, T_(VECTOR,DIM)::ZERO ) ) ); // // // // // // // //if (!Is_Valid(tvTNX.x) // //{ // // tyT0 = tvTXX.x; // // tyT1 = tvTXN.x; // //} // //else // //{ // // if (!Is_Valid(tvTXX.x) // // { // // tyT0 = tvTNX.x; // // tyT1 = tvTNN.x; // // } // // else // // { // // tyT0 = P::FSEL( tvTXX.x - tvTNX.x, tvTNX.x, tvTXX.x ); // // tyT1 = P::FSEL( tvTXX.x - tvTNX.x, tvTXX.x, tvTNX.x ); // // tyT2 = P::FSEL( tvTXN.x - tvTNN.x, tvTNN.x, tvTXN.x ); // // tyT3 = P::FSEL( tvTXN.x - tvTNN.x, tvTXN.x, tvTNN.x ); // // } // //}; // // // //if (!Is_Valid(tvTNX.x) // //{ // // tyT0 = tvTXX.x; // // tyT1 = tvTXN.x; // //} // //else // //{ // // if (!Is_Valid(tvTXX.x) // // { // // tyT0 = tvTNX.x; // // tyT1 = tvTNN.x; // // } // // else // // { // // tyT0 = P::FSEL( tvTXX.x - tvTNX.x, tvTNX.x, tvTXX.x ); // // tyT1 = P::FSEL( tvTXX.x - tvTNX.x, tvTXX.x, tvTNX.x ); // // tyT2 = P::FSEL( tvTXN.x - tvTNN.x, tvTNN.x, tvTXN.x ); // // tyT3 = P::FSEL( tvTXN.x - tvTNN.x, tvTXN.x, tvTNN.x ); // // } // //}; // // // // //if (!Is_Valid(tvTNX.x) // //{ // // tyT0 = tvTXX.x; // // tyT1 = tvTXN.x; // //} // //else // //{ // // if (!Is_Valid(tvTXX.x) // // { // // tyT0 = tvTNX.x; // // tyT1 = tvTNN.x; // // } // // else // // { // // tyT0 = P::FSEL( tvTXX.x - tvTNX.x, tvTNX.x, tvTXX.x ); // // tyT1 = P::FSEL( tvTXX.x - tvTNX.x, tvTXX.x, tvTNX.x ); // // tyT2 = P::FSEL( tvTXN.x - tvTNN.x, tvTNN.x, tvTXN.x ); // // tyT3 = P::FSEL( tvTXN.x - tvTNN.x, tvTXN.x, tvTNN.x ); // // } // //}; // // // // // // // // // // // // // // // // // // // // // // // // // // // // return (TgFALSE); //}; // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //// ============================================================================================================================== // // //}; // END COL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //}; // END TGS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[an error occurred while processing this directive]