bool MyBoundingObjectClass::IsColliding(MyBoundingObjectClass* pOther) { // check for sphere collision // magnitude vector3 distance = pOther->GetCenterGlobal() - GetCenterGlobal(); float magnitude = distance.x * distance.x + distance.y * distance.y + distance.z * distance.z; magnitude = sqrt(magnitude); if ((fRadius + pOther->fRadius) > (magnitude)) { std::cout << "colliding"; isColliding = true; return isColliding; //don't do this because we need to check AABB } else { isColliding = false; return isColliding; // exits if no collision } //// if you reach this point, check for AABB collision ////Get all vectors in global space //vector3 v3Min = vector3(m_m4ToWorld * vector4(m_v3Min, 1.0f)); //vector3 v3Max = vector3(m_m4ToWorld * vector4(m_v3Max, 1.0f)); //vector3 v3MinO = vector3(pOther->m_m4ToWorld * vector4(pOther->m_v3Min, 1.0f)); //vector3 v3MaxO = vector3(pOther->m_m4ToWorld * vector4(pOther->m_v3Max, 1.0f)); ///* //Are they colliding? //For boxes we will assume they are colliding, unless at least one of the following conditions is not met //*/ //bool bColliding = true; ////Check for X //if (m_v3MaxG.x < pOther->m_v3MinG.x) // bColliding = false; //if (m_v3MinG.x > pOther->m_v3MaxG.x) // bColliding = false; ////Check for Y //if (m_v3MaxG.y < pOther->m_v3MinG.y) // bColliding = false; //if (m_v3MinG.y > pOther->m_v3MaxG.y) // bColliding = false; ////Check for Z //if (m_v3MaxG.z < pOther->m_v3MinG.z) // bColliding = false; //if (m_v3MinG.z > pOther->m_v3MaxG.z) // bColliding = false; //isColliding = bColliding; //return bColliding; }
///////////////////////////////////////////////////////////////////// //USAGE: Determines the collision with an incoming object using the SAT // ARGUMENTS : //- MyBOClass* const a_pOther->Other object to check collision with //OUTPUT : result of the collision ///////////////////////////////////////////////////////////////////// bool MyBOClass::SAT(MyBOClass* const a_pOther) { // Get the information of this object vector3 v3CenterGlobalA = GetCenterGlobal(); matrix4 mToWorldA = GetModelMatrix(); vector3 v3RotationA[3]; v3RotationA[0] = vector3(mToWorldA[0][0], mToWorldA[0][1], mToWorldA[0][2]); v3RotationA[1] = vector3(mToWorldA[1][0], mToWorldA[1][1], mToWorldA[1][2]); v3RotationA[2] = vector3(mToWorldA[2][0], mToWorldA[2][1], mToWorldA[2][2]); //Get the information of the other object vector3 v3CenterGlobalB = a_pOther->GetCenterGlobal(); matrix4 mToWorldB = a_pOther->GetModelMatrix(); vector3 v3RotationB[3]; v3RotationB[0] = vector3(mToWorldB[0][0], mToWorldB[0][1], mToWorldB[0][2]); v3RotationB[1] = vector3(mToWorldB[1][0], mToWorldB[1][1], mToWorldB[1][2]); v3RotationB[2] = vector3(mToWorldB[2][0], mToWorldB[2][1], mToWorldB[2][2]); float fCenterAToMiddle, fCenterBToMiddle; glm::mat3 m3Rotation, m3RotationAbs; // Compute rotation matrix expressing b in a's coordinate frame for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) m3Rotation[i][j] = glm::dot(v3RotationA[i], v3RotationB[j]); // Compute translation vector v3Distance (this is the distance between both centers) vector3 v3Distance = v3CenterGlobalB - v3CenterGlobalA; //distance in global space // Bring translation into a's coordinate frame v3Distance = vector3(glm::dot(v3Distance, v3RotationA[0]), glm::dot(v3Distance, v3RotationA[1]), glm::dot(v3Distance, v3RotationA[2])); //distance in A's local // their cross product is (near) null (see the orange book for details) for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) m3RotationAbs[i][j] = std::abs(m3Rotation[i][j]) + 0.0001f; // Test axes L = AX <- 0 fCenterAToMiddle = m_v3HalfWidth.x; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][2]; if (std::abs(v3Distance.x) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center; matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld); if (m_v3CenterG.x < a_pOther->m_v3CenterG.x) { vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA; } else { vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA; } v3Center /= 2.0f; matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center) * glm::rotate(IDENTITY_M4, 90.0f, REAXISY); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), RERED); #endif return false; } // Test axes L = AY <- 1 fCenterAToMiddle = m_v3HalfWidth.y; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][2]; if (std::abs(v3Distance.y) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center; matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld); if (m_v3CenterG.y < a_pOther->m_v3CenterG.y) { vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA; } else { vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA; } v3Center /= 2.0f; matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center) * glm::rotate(IDENTITY_M4, 90.0f, REAXISX); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REGREEN); #endif return false; } // Test axes L = AZ <- 2 fCenterAToMiddle = m_v3HalfWidth.z; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][2]; if (std::abs(v3Distance.z) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center; matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld); if (m_v3CenterG.z < a_pOther->m_v3CenterG.z) { vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA; } else { vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA; } v3Center /= 2.0f; matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REBLUE); #endif return false; } // Test axes L = BX <- 3 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][0] + m_v3HalfWidth.y * m3RotationAbs[1][0] + m_v3HalfWidth.z * m3RotationAbs[2][0]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x; if (std::abs(v3Distance.x * m3Rotation[0][0] + v3Distance.y * m3Rotation[1][0] + v3Distance.z * m3Rotation[2][0]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG) * glm::rotate(IDENTITY_M4, 90.0f, REAXISY); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), RERED * 0.33f); #endif return false; } // Test axes L = BY <- 4 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][1] + m_v3HalfWidth.y * m3RotationAbs[1][1] + m_v3HalfWidth.z * m3RotationAbs[2][1]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.y; if (std::abs(v3Distance.x * m3Rotation[0][1] + v3Distance.y * m3Rotation[1][1] + v3Distance.z * m3Rotation[2][1]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG) * glm::rotate(IDENTITY_M4, 90.0f, REAXISX); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REGREEN * 0.33f); #endif return false; } // Test axes L = BZ <- 5 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][2] + m_v3HalfWidth.y * m3RotationAbs[1][2] + m_v3HalfWidth.z * m3RotationAbs[2][2]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.z; if (std::abs(v3Distance.x * m3Rotation[0][2] + v3Distance.y * m3Rotation[1][2] + v3Distance.z * m3Rotation[2][2]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG); m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REBLUE * 0.33f); #endif return false; } // Test axis L = AX x BX <- 6 fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][0] + m_v3HalfWidth.z * m3RotationAbs[1][0]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][1]; if (std::abs(v3Distance.z * m3Rotation[1][0] - v3Distance.y * m3Rotation[2][0]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center; matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld); if (m_v3CenterG.z < a_pOther->m_v3CenterG.z) { vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA; } else { vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f)); v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA; } v3Center /= 2.0f; matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AX x BY <- 7 fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][1] + m_v3HalfWidth.z * m3RotationAbs[1][1]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][0]; if (std::abs(v3Distance.z * m3Rotation[1][1] - v3Distance.y * m3Rotation[2][1]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AX x BZ <- 8 fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][2] + m_v3HalfWidth.z * m3RotationAbs[1][2]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][0]; if (std::abs(v3Distance.z * m3Rotation[1][2] - v3Distance.y * m3Rotation[2][2]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AY x BX <- 9 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][0] + m_v3HalfWidth.z * m3RotationAbs[0][0]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][1]; if (std::abs(v3Distance.x * m3Rotation[2][0] - v3Distance.z * m3Rotation[0][0]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AY x BY <- 10 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][1] + m_v3HalfWidth.z * m3RotationAbs[0][1]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][0]; if (std::abs(v3Distance.x * m3Rotation[2][1] - v3Distance.z * m3Rotation[0][1]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AY x BZ <- 11 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][2] + m_v3HalfWidth.z * m3RotationAbs[0][2]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][0]; if (std::abs(v3Distance.x * m3Rotation[2][2] - v3Distance.z * m3Rotation[0][2]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AZ x BX <- 12 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][0] + m_v3HalfWidth.y * m3RotationAbs[0][0]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][1]; if (std::abs(v3Distance.y * m3Rotation[0][0] - v3Distance.x * m3Rotation[1][0]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AZ x BY <- 13 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][1] + m_v3HalfWidth.y * m3RotationAbs[0][1]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][0]; if (std::abs(v3Distance.y * m3Rotation[0][1] - v3Distance.x * m3Rotation[1][1]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Test axis L = AZ x BZ <- 14 fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][2] + m_v3HalfWidth.y * m3RotationAbs[0][2]; fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][0]; if (std::abs(v3Distance.y * m3Rotation[0][2] - v3Distance.x * m3Rotation[1][2]) > fCenterAToMiddle + fCenterBToMiddle) { #ifdef SHOWPLANES vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f; matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center); m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID); #endif return false; } // Since no separating axis found, the OBBs must a_pOther->m_v3HalfWidth intersecting return true; }