public static float SqrDistSegOBBInternal(Segment rkLine, CollisionOBB rkBox, SegOBBParams pf) { // compute coordinates of line in box coordinate system Vector3 kDiff = rkLine.origin - rkBox.center; Vector3 kPnt = new Vector3(kDiff.Dot(rkBox.axes[0]), kDiff.Dot(rkBox.axes[1]), kDiff.Dot(rkBox.axes[2])); Vector3 kDir = new Vector3(rkLine.direction.Dot(rkBox.axes[0]), rkLine.direction.Dot(rkBox.axes[1]), rkLine.direction.Dot(rkBox.axes[2])); // Apply reflections so that direction vector has nonnegative components. bool[] bReflect = new bool[3] { false, false, false }; int i; for (i = 0; i < 3; i++) { if (kDir[i] < 0.0f) { kPnt[i] = -kPnt[i]; kDir[i] = -kDir[i]; bReflect[i] = true; } } float fSqrDistance = 0.0f; if (kDir.x > 0.0f) { if (kDir.y > 0.0f) { if (kDir.z > 0.0f) { // (+,+,+) CaseNoZeros(ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } else { // (+,+,0) Case0(0,1,2,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } } else { if (kDir.z > 0.0f) { // (+,0,+) Case0(0,2,1,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } else { // (+,0,0) Case00(0,1,2,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } } } else { if (kDir.y > 0.0f) { if (kDir.z > 0.0f) { // (0,+,+) Case0(1,2,0,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } else { // (0,+,0) Case00(1,0,2,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } } else { if (kDir.z > 0.0f) { // (0,0,+) Case00(2,0,1,ref kPnt,kDir,rkBox,pf,ref fSqrDistance); } else { // (0,0,0) Case000(ref kPnt,rkBox,ref fSqrDistance); if (pf.useIt) pf.pfLParam = 0.0f; } } } if (pf.useIt) { // undo reflections for (i = 0; i < 3; i++) { if (bReflect[i]) kPnt[i] = -kPnt[i]; } pf.pfBVec = kPnt; } return fSqrDistance; }
public static float SqrDistSegOBB(Segment rkSeg, CollisionOBB rkBox, SegOBBParams pf) { Segment kLine = new Segment(rkSeg.origin, rkSeg.direction); float fSqrDistance = SqrDistSegOBBInternal(kLine,rkBox,pf); if (pf.pfLParam >= 0.0f) { if (pf.pfLParam <= 1.0f) { return fSqrDistance; } else { fSqrDistance = XSqDistPtOBB(rkSeg.origin + rkSeg.direction,rkBox,pf); if (pf.useIt) pf.pfLParam = 1.0f; return fSqrDistance; } } else { fSqrDistance = XSqDistPtOBB(rkSeg.origin,rkBox,pf); if (pf.useIt) pf.pfLParam = 0.0f; return fSqrDistance; } }