/** * Calculates a tight box-sphere bounds for the aggregate geometry; this is more expensive than CalcAABB * (tight meaning the sphere may be smaller than would be required to encompass the AABB, but all individual components lie within both the box and the sphere) * * @param Output The output box-sphere bounds calculated for this set of aggregate geometry * @param LocalToWorld Transform */ void FKAggregateGeom::CalcBoxSphereBounds(FBoxSphereBounds& Output, const FTransform& LocalToWorld) const { // Calculate the AABB const FBox AABB = CalcAABB(LocalToWorld); if ((SphereElems.Num() == 0) && (SphylElems.Num() == 0) && (BoxElems.Num() == 0)) { // For bounds that only consist of convex shapes (such as anything generated from a BSP model), // we can get nice tight bounds by considering just the points of the convex shape const FVector Origin = AABB.GetCenter(); float RadiusSquared = 0.0f; for (int32 i = 0; i < ConvexElems.Num(); i++) { const FKConvexElem& Elem = ConvexElems[i]; for (int32 j = 0; j < Elem.VertexData.Num(); ++j) { const FVector Point = LocalToWorld.TransformPosition(Elem.VertexData[j]); RadiusSquared = FMath::Max(RadiusSquared, (Point - Origin).SizeSquared()); } } // Push the resulting AABB and sphere into the output AABB.GetCenterAndExtents(Output.Origin, Output.BoxExtent); Output.SphereRadius = FMath::Sqrt(RadiusSquared); } else if ((SphereElems.Num() == 1) && (SphylElems.Num() == 0) && (BoxElems.Num() == 0) && (ConvexElems.Num() == 0)) { // For bounds that only consist of a single sphere, // we can be certain the box extents are the same as its radius AABB.GetCenterAndExtents(Output.Origin, Output.BoxExtent); Output.SphereRadius = Output.BoxExtent.X; } else { // Just use the loose sphere bounds that totally fit the AABB Output = FBoxSphereBounds(AABB); } }
void dgCollisionScene::CalcAABBSimd(const dgMatrix &matrix, dgVector &p0, dgVector &p1) const { CalcAABB(matrix, p0, p1); }