/// <summary> /// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation, /// so all the passed points will fit in the current view. /// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn). /// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut). /// </summary> /// <param name="boundingBox">The bounding box.</param> /// <returns>The zoom to fit distance</returns> public float GetZoomToExtentsShiftDistance(ref BoundingBox boundingBox) { return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners())); }
/// <summary> /// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit) operation, /// so all the passed points will fit in the current view. /// </summary> /// <param name="boundingBox">The bounding box.</param> /// <returns>The zoom to fit vector</returns> public Vector3 GetZoomToExtentsShiftVector(ref BoundingBox boundingBox) { return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners()) * pNear.Normal); }
/// <summary> /// Check the intersection between an <see cref="OrientedBoundingBox"/> and <see cref="BoundingBox"/> /// </summary> /// <param name="box">The BoundingBox to test.</param> /// <returns>The type of containment the two objects have.</returns> /// <remarks> /// For accuracy, The transformation matrix for the <see cref="OrientedBoundingBox"/> must not have any scaling applied to it. /// Anyway, scaling using Scale method will keep this method accurate. /// </remarks> public ContainmentType Contains(ref BoundingBox box) { var cornersCheck = Contains(box.GetCorners()); if (cornersCheck != ContainmentType.Disjoint) { return(cornersCheck); } var boxCenter = box.Minimum + (box.Maximum - box.Minimum) / 2f; var boxExtents = box.Maximum - boxCenter; var SizeA = Extents; var SizeB = boxExtents; var RotA = GetRows(ref Transformation); float ExtentA, ExtentB, Separation; int i, k; Matrix R; // Rotation from B to A Matrix.Invert(ref Transformation, out R); var AR = new Matrix(); // absolute values of R matrix, to use with box extents for (i = 0; i < 3; i++) { for (k = 0; k < 3; k++) { AR[i, k] = Math.Abs(R[i, k]); } } // Vector separating the centers of Box B and of Box A var vSepWS = boxCenter - Center; // Rotated into Box A's coordinates var vSepA = new Vector3(Vector3.Dot(vSepWS, RotA[0]), Vector3.Dot(vSepWS, RotA[1]), Vector3.Dot(vSepWS, RotA[2])); // Test if any of A's basis vectors separate the box for (i = 0; i < 3; i++) { ExtentA = SizeA[i]; ExtentB = Vector3.Dot(SizeB, new Vector3(AR[i, 0], AR[i, 1], AR[i, 2])); Separation = Math.Abs(vSepA[i]); if (Separation > ExtentA + ExtentB) { return(ContainmentType.Disjoint); } } // Test if any of B's basis vectors separate the box for (k = 0; k < 3; k++) { ExtentA = Vector3.Dot(SizeA, new Vector3(AR[0, k], AR[1, k], AR[2, k])); ExtentB = SizeB[k]; Separation = Math.Abs(Vector3.Dot(vSepA, new Vector3(R[0, k], R[1, k], R[2, k]))); if (Separation > ExtentA + ExtentB) { return(ContainmentType.Disjoint); } } // Now test Cross Products of each basis vector combination ( A[i], B[k] ) for (i = 0; i < 3; i++) { for (k = 0; k < 3; k++) { int i1 = (i + 1) % 3, i2 = (i + 2) % 3; int k1 = (k + 1) % 3, k2 = (k + 2) % 3; ExtentA = SizeA[i1] * AR[i2, k] + SizeA[i2] * AR[i1, k]; ExtentB = SizeB[k1] * AR[i, k2] + SizeB[k2] * AR[i, k1]; Separation = Math.Abs(vSepA[i2] * R[i1, k] - vSepA[i1] * R[i2, k]); if (Separation > ExtentA + ExtentB) { return(ContainmentType.Disjoint); } } } // No separating axis found, the boxes overlap return(ContainmentType.Intersects); }