/// <summary> /// Gets a bounding volume transformed by a matrix. /// </summary> /// <param name="m">The matrix to transform by.</param> /// <returns>The transformed box.</returns> /// <see cref="TransformProjectBy"/> public FBox TransformBy(FMatrix m) { // if we are not valid, return another invalid box. if (!IsValid) { return(default(FBox)); } FVector vecMin = Min; FVector vecMax = Max; FVector m0 = m.GetRow(0); FVector m1 = m.GetRow(1); FVector m2 = m.GetRow(2); FVector m3 = m.GetRow(3); FVector half = new FVector(0.5f, 0.5f, 0.5f); FVector origin = (vecMax + vecMin) * half; FVector extent = (vecMax - vecMin) * half; FVector newOrigin = FVector.Replicate(origin, 0) * m0; newOrigin += (FVector.Replicate(origin, 1) * m1); newOrigin += (FVector.Replicate(origin, 2) * m2); newOrigin += m3; FVector newExtent = (FVector.Replicate(extent, 0) * m0).GetAbs(); newExtent += (FVector.Replicate(extent, 1) * m1).GetAbs(); newExtent += (FVector.Replicate(extent, 2) * m2).GetAbs(); FVector newVecMin = newOrigin - newExtent; FVector newVecMax = newOrigin + newExtent; FBox newBox; newBox.Min = newVecMin; newBox.Max = newVecMax; newBox.isValid = 1; return(newBox); }
/// <summary> /// Gets a bounding volume transformed by a matrix. /// </summary> /// <param name="m">The matrix.</param> /// <returns>The transformed volume.</returns> public FBoxSphereBounds TransformBy(FMatrix m) { FBoxSphereBounds result; FVector vecOrigin = Origin; FVector vecExtent = BoxExtent; FVector m0 = m.GetRow(0); FVector m1 = m.GetRow(1); FVector m2 = m.GetRow(2); FVector m3 = m.GetRow(3); FVector newOrigin = FVector.Replicate(vecOrigin, 0) * m0; newOrigin += (FVector.Replicate(vecOrigin, 1) * m1); newOrigin += (FVector.Replicate(vecOrigin, 2) * m2); newOrigin = newOrigin + m3; FVector newExtent = (FVector.Replicate(vecExtent, 0) * m0).GetAbs(); newExtent += (FVector.Replicate(vecExtent, 1) * m1).GetAbs(); newExtent += (FVector.Replicate(vecExtent, 2) * m2).GetAbs(); result.BoxExtent = newExtent; result.Origin = newOrigin; FVector maxRadius = m0 * m0; maxRadius += m1 * m1; maxRadius += m2 * m2; maxRadius = FVector.ComponentMax(FVector.ComponentMax(maxRadius, FVector.Replicate(maxRadius, 1)), FVector.Replicate(maxRadius, 2)); result.SphereRadius = FMath.Sqrt(maxRadius[0]) * SphereRadius; // For non-uniform scaling, computing sphere radius from a box results in a smaller sphere. float boxExtentMagnitude = FMath.Sqrt(FVector.DotProduct(newExtent, newExtent)); result.SphereRadius = FMath.Min(result.SphereRadius, boxExtentMagnitude); result.DiagnosticCheckNaN(); return(result); }