Help with separating axis algorithm implementation I'm having some difficulty with my SAT implementation. I'm basing it on Dynamic Collision Detect by David Eberly et al and I'm getting stuck on a part where I have to calculate the two radiuses. I'm listing here the equation that calculates the two radiuses as the paper has them (scroll down to the bottom of the post, the equations are linked as images) and some code that I wrote based on them. If any one could please at least point me in the right direction. My first question is what does the word "Sign" mean exactly in the equation? I've understood it to be a sign vector that is used to get all the 8 vertices, but I'm having doubts about it. My second question is does he calculate the radiuses for each vertex or is that formula used just once? I've taken it to mean for each vertex, because otherwise it doesn't make sense to me. So basically what I'm doing in my code is finding the radius0 for every one of the 8 vertices of the first box, then out of those 8 radiuses I pick the one that has the largest value. The paper doesn't say to do that, but that's the only way I see that makes any sense to me. I do the same for the second box. Here is the function I've written based on the paper that should work in theory (but it doesn't) bool CollisionBox::mCheckOverlapOnAxis(const XMVECTOR& boxCenter, const XMVECTOR& xAxis, const XMVECTOR& yAxis, const XMVECTOR& zAxis, XMFLOAT3 xyzExtents, const XMVECTOR& projectionAxis) { //define a sign vector to get all the points int sign[8][3]; sign[0][0] = 1; sign[0][1] = 1; sign[0][2] = 1; sign[1][0] = 1; sign[1][1] = 1; sign[1][2] = -1; sign[2][0] = -1; sign[2][1] = 1; sign[2][2] = -1; sign[3][0] = -1; sign[3][1] = 1; sign[3][2] = 1; sign[4][0] = 1; sign[4][1] = -1; sign[4][2] = 1; sign[5][0] = 1; sign[5][1] = -1; sign[5][2] = -1; sign[6][0] = -1; sign[6][1] = -1; sign[6][2] = -1; sign[7][0] = -1; sign[7][1] = -1; sign[7][2] = 1; //the first box is the box in this class XMVECTOR axesA[3] = { mXAxis, mYAxis, mZAxis }; XMVECTOR center = { 0.0f, 0.0f, 0.0f }; float extentsA[3] = { mXExtent, mYExtent, mZExtent }; //the second box is the box passed to the class in this way "thisClass.isCollising(secondBox)" XMVECTOR axesB[3] = { xAxis, yAxis, zAxis }; XMVECTOR centerB = { boxCenter - mCenter }; //offset the center so the first box is at zero float extentsB[3] = { xyzExtents.x, xyzExtents.y, xyzExtents.z }; //start the sum with zero vectors XMVECTOR radiusA = { 0.0f, 0.0f, 0.0f }; XMVECTOR radiusB = { 0.0f, 0.0f, 0.0f }; for (int vertexCount = 0; vertexCount < 8; vertexCount++) { XMVECTOR sumA = { 0.0f, 0.0f, 0.0f }; XMVECTOR sumB = { 0.0f, 0.0f, 0.0f }; for (int i = 0; i < 3; i++) { //this is based on the equation linked at the bottom, for each box sumA += extentsA[i] * sign[vertexCount][i] * (projectionAxis * axesA[i])*(projectionAxis * axesA[i]); sumB += extentsB[i] * sign[vertexCount][i] * (projectionAxis * axesB[i])*(projectionAxis * axesB[i]); } //this section just finds the greatest radius XMVECTOR sumALen = XMVector3Length(sumA); XMVECTOR radiusALen = XMVector3Length(radiusA); XMFLOAT3 sumALenF, radiusALenF; XMStoreFloat3(&sumALenF, sumALen); XMStoreFloat3(&radiusALenF, radiusALen); if (sumALenF.x > radiusALenF.x) radiusA = sumA; XMVECTOR sumBLen = XMVector3Length(sumB); XMVECTOR radiusBLen = XMVector3Length(radiusB); XMFLOAT3 sumBLenF, radiusBLenF; XMStoreFloat3(&sumBLenF, sumBLen); XMStoreFloat3(&radiusBLenF, radiusB); if (sumBLenF.x > radiusBLenF.x) radiusB = sumB; } //now we just do a comparison test L*D > r0+r1 XMVECTOR centerDistance = centerB - center; XMVECTOR R = projectionAxis * centerDistance; XMVECTOR radiusSum = radiusA + radiusB; XMVECTOR Rlen = XMVector3Length(R); XMVECTOR rLen = XMVector3Length(radiusSum); XMFLOAT3 RLenF, rLenF; XMStoreFloat3(&RLenF, Rlen); XMStoreFloat3(&rLenF, rLen); //if L*D > r0 + r1, there is no collision, otherwise intersection is there if (RLenF.x > rLenF.x) return false; else return true; } https://ift.tt/eA8V8J
I'm having some difficulty with my SAT implementation. I'm basing it on Dynamic Collision Detect by David Eberly et al and I'm getting stuck on a part where I have to calculate the two radiuses. I'm listing here the equation that calculates the two radiuses as the paper has them (scroll down to the bottom of the post, the equations are linked as images) and some code that I wrote based on them. If any one could please at least point me in the right direction. My first question is what does the word "Sign" mean exactly in the equation? I've understood it to be a sign vector that is used to get all the 8 vertices, but I'm having doubts about it. My second question is does he calculate the radiuses for each vertex or is that formula used just once? I've taken it to mean for each vertex, because otherwise it doesn't make sense to me. So basically what I'm doing in my code is finding the radius0 for every one of the 8 vertices of the first box, then out of those 8 radiuses I pick the one that has the largest value. The paper doesn't say to do that, but that's the only way I see that makes any sense to me. I do the same for the second box. Here is the function I've written based on the paper that should work in theory (but it doesn't) bool CollisionBox::mCheckOverlapOnAxis(const XMVECTOR& boxCenter, const XMVECTOR& xAxis, const XMVECTOR& yAxis, const XMVECTOR& zAxis, XMFLOAT3 xyzExtents, const XMVECTOR& projectionAxis) { //define a sign vector to get all the points int sign[8][3]; sign[0][0] = 1; sign[0][1] = 1; sign[0][2] = 1; sign[1][0] = 1; sign[1][1] = 1; sign[1][2] = -1; sign[2][0] = -1; sign[2][1] = 1; sign[2][2] = -1; sign[3][0] = -1; sign[3][1] = 1; sign[3][2] = 1; sign[4][0] = 1; sign[4][1] = -1; sign[4][2] = 1; sign[5][0] = 1; sign[5][1] = -1; sign[5][2] = -1; sign[6][0] = -1; sign[6][1] = -1; sign[6][2] = -1; sign[7][0] = -1; sign[7][1] = -1; sign[7][2] = 1; //the first box is the box in this class XMVECTOR axesA[3] = { mXAxis, mYAxis, mZAxis }; XMVECTOR center = { 0.0f, 0.0f, 0.0f }; float extentsA[3] = { mXExtent, mYExtent, mZExtent }; //the second box is the box passed to the class in this way "thisClass.isCollising(secondBox)" XMVECTOR axesB[3] = { xAxis, yAxis, zAxis }; XMVECTOR centerB = { boxCenter - mCenter }; //offset the center so the first box is at zero float extentsB[3] = { xyzExtents.x, xyzExtents.y, xyzExtents.z }; //start the sum with zero vectors XMVECTOR radiusA = { 0.0f, 0.0f, 0.0f }; XMVECTOR radiusB = { 0.0f, 0.0f, 0.0f }; for (int vertexCount = 0; vertexCount < 8; vertexCount++) { XMVECTOR sumA = { 0.0f, 0.0f, 0.0f }; XMVECTOR sumB = { 0.0f, 0.0f, 0.0f }; for (int i = 0; i < 3; i++) { //this is based on the equation linked at the bottom, for each box sumA += extentsA[i] * sign[vertexCount][i] * (projectionAxis * axesA[i])*(projectionAxis * axesA[i]); sumB += extentsB[i] * sign[vertexCount][i] * (projectionAxis * axesB[i])*(projectionAxis * axesB[i]); } //this section just finds the greatest radius XMVECTOR sumALen = XMVector3Length(sumA); XMVECTOR radiusALen = XMVector3Length(radiusA); XMFLOAT3 sumALenF, radiusALenF; XMStoreFloat3(&sumALenF, sumALen); XMStoreFloat3(&radiusALenF, radiusALen); if (sumALenF.x > radiusALenF.x) radiusA = sumA; XMVECTOR sumBLen = XMVector3Length(sumB); XMVECTOR radiusBLen = XMVector3Length(radiusB); XMFLOAT3 sumBLenF, radiusBLenF; XMStoreFloat3(&sumBLenF, sumBLen); XMStoreFloat3(&radiusBLenF, radiusB); if (sumBLenF.x > radiusBLenF.x) radiusB = sumB; } //now we just do a comparison test L*D > r0+r1 XMVECTOR centerDistance = centerB - center; XMVECTOR R = projectionAxis * centerDistance; XMVECTOR radiusSum = radiusA + radiusB; XMVECTOR Rlen = XMVector3Length(R); XMVECTOR rLen = XMVector3Length(radiusSum); XMFLOAT3 RLenF, rLenF; XMStoreFloat3(&RLenF, Rlen); XMStoreFloat3(&rLenF, rLen); //if L*D > r0 + r1, there is no collision, otherwise intersection is there if (RLenF.x > rLenF.x) return false; else return true; }
from GameDev.net http://bit.ly/2F3J1IE
from GameDev.net http://bit.ly/2F3J1IE
ليست هناك تعليقات