bool CheckBoxBoxQuick(Box one, Box two) { // TODO fix this Code | // v List<Vector3> intersectedCorners1 = new List<Vector3>(); intersectedCorners1.RemoveAll((corner) => (false /* add prediction code */)); if (intersectedCorners1.Count > 2) { Vector3 a = intersectedCorners1[0] - intersectedCorners1[1]; Vector3 b = intersectedCorners1[2] - intersectedCorners1[0]; Vector3 axis = Vector3.Cross(a,b); axis.Normalize(); Vector3 cp = Vector3.Lerp(intersectedCorners1[1],intersectedCorners1[2],0.5f); ContactPoint = cp; ContactNormal = axis; return true; } return false; }
void fillPointFaceBoxBox(Box one, Box two, Vector3 toCentre, int best, float pen) { // This method is called when we know that a vertex from // box two is in contact with box one. // We know which axis the collision is on (i.e. best), // but we need to work out which of the two faces on // this axis. Vector3 normal = one.GetAxis(best); if (Vector3.Dot(one.GetAxis(best), toCentre) > 0) { normal *= -1f; } // Work out which vertex of box two we're colliding with. // Using toCentre doesn't work! Vector3 vertex = two.HalfSize; if (Vector3.Dot(two.GetAxis(0), normal) < 0) vertex.X = -vertex.X; if (Vector3.Dot(two.GetAxis(1), normal) < 0) vertex.Y = -vertex.Y; if (Vector3.Dot(two.GetAxis(2), normal) < 0) vertex.Z = -vertex.Z; // Create the contact data _ContactNormal = normal; _Penetration = pen; _ContactPoint = Vector3.Transform(vertex, two.TransformMatrix); }
private static float transformToAxis(Box box, Vector3 axis) { return box.HalfSize.X * Math.Abs(Vector3.Dot(axis, box.GetAxis(0))) + box.HalfSize.Y * Math.Abs(Vector3.Dot(axis, box.GetAxis(1))) + box.HalfSize.Z * Math.Abs(Vector3.Dot(axis, box.GetAxis(2))); }
bool CheckBoxAndCheck(Box one, Box two) { //#define TEST_OVERLAP(axis) overlapOnAxis(one, two, (axis), toCentre) Vector3 toCentre = two.Position - one.Position; bool first = true, second = true, third = true; for (int i = 0; i < 3; i++) { first = first && overlapOnAxis(one, two, one.GetAxis(i), toCentre); second = second && overlapOnAxis(one, two, two.GetAxis(i), toCentre); } for (int i = 0,j=0, k=0; i < 9; i++, j++) { if (i % 3 == 0 && i != 0) { j = 0; k++; } third = third && overlapOnAxis(one, two, Vector3.Cross(one.GetAxis(k), two.GetAxis(j)),toCentre); } return first && second && third; }
/// <summary> /// fill contact data between box and point /// </summary> /// <param name="box"></param> /// <param name="point"></param> /// <returns></returns> //public bool BoxAndPoint(Box box, Vector3 point) public void BoxAndPoint(Box box, Vector3 point) { // Transform the point into box coordinates. Vector3 pointToBoxCor = Vector3.Transform(point, Matrix.Invert(box.TransformMatrix)); Vector3 normal; // Check each axis looking for the axis on which the penetration is least deep. #region X axis float minDepth = box.HalfSize.X - Math.Abs(pointToBoxCor.X); if (minDepth < 0) //return false; return; normal = box.GetAxis(0) * ((pointToBoxCor.X < 0) ? -1 : 1); #endregion #region Y axis float depth = box.HalfSize.Y - Math.Abs(pointToBoxCor.Y); if (depth < 0) //return false; return; else if (depth < minDepth) { minDepth = depth; normal = box.GetAxis(1) * ((pointToBoxCor.Y < 0) ? -1 : 1); } #endregion #region Z axis depth = box.HalfSize.Z - Math.Abs(pointToBoxCor.Z); if (depth < 0) //return false; return; else if (depth < minDepth) { minDepth = depth; normal = box.GetAxis(2) * ((pointToBoxCor.Z < 0) ? -1 : 1); } #endregion //filling data _ContactNormal = normal; _ContactPoint = point; _Penetration = minDepth; body[0] = box; // Note that we don’t know what rigid body the point // belongs to, so we just use NULL. Where this is called // this value can be left, or filled in. body[1] = null; //TODO //restitution = TODO; //friction = TODO; //return true; }
public static float penetrationOnAxis(Box one, Box two, Vector3 axis, Vector3 toCentre) { // Project the half-size of one onto axis float oneProject = transformToAxis(one, axis); float twoProject = transformToAxis(two, axis); // Project this onto the axis float distance = Math.Abs(Vector3.Dot(toCentre, axis)); // Return the overlap (i.e. positive indicates // overlap, negative indicates separation). return oneProject + twoProject - distance; }
private bool tryAxis(Box one, Box two, Vector3 axis, Vector3 toCentre, int index, // These values may be updated ref float smallestPenetration, ref int smallestCase) { if (axis.LengthSquared() < 0.0001) return true; axis.Normalize(); float penetration = penetrationOnAxis(one, two, axis, toCentre); if (penetration < 0) // there is no Contact return false; if (penetration < smallestPenetration) // Set the Smallest { smallestPenetration = penetration; smallestCase = index; } return true; }
/// <summary> /// return true if the two boxes are overlaping in each other /// </summary> /// <param name="one"></param> /// <param name="two"></param> /// <param name="axis"></param> /// <returns></returns> bool OverlapOnAxis(Box one, Box two, Vector3 axis) { // Project the half-size of one onto axis. float oneProject = TransformToAxis(one, axis); float twoProject = TransformToAxis(two, axis); // Find the vector between the two centers. Vector3 toCenter = two.GetAxis(3) - one.GetAxis(3); // Project this onto the axis. float distance = Vector3.Dot(toCenter, axis); // Check for overlap. return (distance < oneProject + twoProject); }
bool overlapOnAxis(Box one, Box two, Vector3 axis, Vector3 toCentre) { // Project the half-size of one onto axis float oneProject = transformToAxis(one, axis); float twoProject = transformToAxis(two, axis); // Project this onto the axis float distance = Math.Abs(Vector3.Dot(toCentre, axis)); // Check for overlap return (distance < oneProject + twoProject); }