Skip to content

Commit

Permalink
Clear excessive branching and excess copying
Browse files Browse the repository at this point in the history
  • Loading branch information
nyoungbq committed Jul 18, 2024
1 parent 54484d4 commit 06ac6f2
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 139 deletions.
192 changes: 62 additions & 130 deletions src/simplnx/Utilities/Math/GeometryMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,121 +54,54 @@ BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfVertices(INodeGeometry0D
return {ll, ur}; // should be valid
}

BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFace(const TriangleGeom& faces, int32 faceId)
BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId)
{
std::array<Point3Df, 3> points = {};
faces.getFaceCoordinates(faceId, points);
std::array<Point3Df, 3> points = GeometryMath::detail::GetFaceCoordinates<float32>(cache, faceId);

Point3Df ll = points[0];
Point3Df ur = points[0];

if(points[1][0] < ll[0])
{
ll[0] = points[1][0];
}
if(points[1][0] > ur[0])
{
ur[0] = points[1][0];
}
if(points[1][1] < ll[1])
{
ll[1] = points[1][1];
}
if(points[1][1] > ur[1])
{
ur[1] = points[1][1];
}
if(points[1][2] < ll[2])
{
ll[2] = points[1][2];
}
if(points[1][2] > ur[2])
{
ur[2] = points[1][2];
}
if(points[2][0] < ll[0])
{
ll[0] = points[2][0];
}
if(points[2][0] > ur[0])
{
ur[0] = points[2][0];
}
if(points[2][1] < ll[1])
{
ll[1] = points[2][1];
}
if(points[2][1] > ur[1])
{
ur[1] = points[2][1];
}
if(points[2][2] < ll[2])
{
ll[2] = points[2][2];
}
if(points[2][2] > ur[2])
{
ur[2] = points[2][2];
}
// Avoid Branch Prediction misses by exclusively doing multiplication operations
// C++ (§4.5/4):
// An r-value of type bool can be converted to an r-value of type int,
// with false becoming zero and true becoming one.
//
// The standard guarantees the same for float
bool swap = points[1][0] < ll[0];
ll[0] = points[1][0] * static_cast<float32>(swap) + ll[0] * static_cast<float32>(!swap);

return {ll, ur};
}
swap = points[1][1] < ll[1];
ll[1] = points[1][1] * static_cast<float32>(swap) + ll[1] * static_cast<float32>(!swap);

BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId)
{
std::array<Point3Df, 3> points = GeometryMath::detail::GetFaceCoordinates<float32>(cache, faceId);
swap = points[1][2] < ll[2];
ll[2] = points[1][2] * static_cast<float32>(swap) + ll[2] * static_cast<float32>(!swap);

Point3Df ll = points[0];
Point3Df ur = points[0];
swap = points[2][0] < ll[0];
ll[0] = points[2][0] * static_cast<float32>(swap) + ll[0] * static_cast<float32>(!swap);

if(points[1][0] < ll[0])
{
ll[0] = points[1][0];
}
if(points[1][0] > ur[0])
{
ur[0] = points[1][0];
}
if(points[1][1] < ll[1])
{
ll[1] = points[1][1];
}
if(points[1][1] > ur[1])
{
ur[1] = points[1][1];
}
if(points[1][2] < ll[2])
{
ll[2] = points[1][2];
}
if(points[1][2] > ur[2])
{
ur[2] = points[1][2];
}
if(points[2][0] < ll[0])
{
ll[0] = points[2][0];
}
if(points[2][0] > ur[0])
{
ur[0] = points[2][0];
}
if(points[2][1] < ll[1])
{
ll[1] = points[2][1];
}
if(points[2][1] > ur[1])
{
ur[1] = points[2][1];
}
if(points[2][2] < ll[2])
{
ll[2] = points[2][2];
}
if(points[2][2] > ur[2])
{
ur[2] = points[2][2];
}
swap = points[2][1] < ll[1];
ll[1] = points[2][1] * static_cast<float32>(swap) + ll[1] * static_cast<float32>(!swap);

swap = points[2][2] < ll[2];
ll[2] = points[2][2] * static_cast<float32>(swap) + ll[2] * static_cast<float32>(!swap);

swap = points[1][0] > ur[0];
ur[0] = points[1][0] * static_cast<float32>(swap) + ur[0] * static_cast<float32>(!swap);

swap = points[1][1] > ur[1];
ur[1] = points[1][1] * static_cast<float32>(swap) + ur[1] * static_cast<float32>(!swap);

swap = points[1][2] > ur[2];
ur[2] = points[1][2] * static_cast<float32>(swap) + ur[2] * static_cast<float32>(!swap);

swap = points[2][0] > ur[0];
ur[0] = points[2][0] * static_cast<float32>(swap) + ur[0] * static_cast<float32>(!swap);

swap = points[2][1] > ur[1];
ur[1] = points[2][1] * static_cast<float32>(swap) + ur[1] * static_cast<float32>(!swap);

swap = points[2][2] > ur[2];
ur[2] = points[2][2] * static_cast<float32>(swap) + ur[2] * static_cast<float32>(!swap);

return {ll, ur};
}
Expand All @@ -191,30 +124,29 @@ BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFaces(const nx::core::Tr
Point3Df min = bounds.getMinPoint();
Point3Df max = bounds.getMaxPoint();

if(min[0] < ll[0])
{
ll[0] = min[0];
}
if(min[1] < ll[1])
{
ll[1] = min[1];
}
if(min[2] < ll[2])
{
ll[2] = min[2];
}
if(max[0] > ur[0])
{
ur[0] = max[0];
}
if(max[1] > ur[1])
{
ur[1] = max[1];
}
if(max[2] > ur[2])
{
ur[2] = max[2];
}
// Avoid Branch Prediction misses by exclusively doing multiplication operations
// C++ (§4.5/4):
// An r-value of type bool can be converted to an r-value of type int,
// with false becoming zero and true becoming one.
//
// The standard guarantees the same for float
bool swap = min[0] < ll[0];
ll[0] = min[0] * static_cast<float32>(swap) + ll[0] * static_cast<float32>(!swap);

swap = min[1] < ll[1];
ll[1] = min[1] * static_cast<float32>(swap) + ll[1] * static_cast<float32>(!swap);

swap = min[2] < ll[2];
ll[2] = min[2] * static_cast<float32>(swap) + ll[2] * static_cast<float32>(!swap);

swap = max[0] > ur[0];
ur[0] = min[0] * static_cast<float32>(swap) + ur[0] * static_cast<float32>(!swap);

swap = max[1] > ur[1];
ur[1] = min[1] * static_cast<float32>(swap) + ur[1] * static_cast<float32>(!swap);

swap = max[2] > ur[2];
ur[2] = min[2] * static_cast<float32>(swap) + ur[2] * static_cast<float32>(!swap);
}

return {ll, ur};
Expand Down
10 changes: 1 addition & 9 deletions src/simplnx/Utilities/Math/GeometryMath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ inline bool IsPointInBox(const nx::core::Point3D<T>& point, const nx::core::Boun
* @return bool
*/
template <typename T>
bool DoesRayIntersectBox(nx::core::Ray<T> ray, const nx::core::BoundingBox3D<T>& bounds)
bool DoesRayIntersectBox(const nx::core::Ray<T>& ray, const nx::core::BoundingBox3D<T>& bounds)
{
auto origin = ray.getOrigin();
auto end = ray.getEndPoint();
Expand Down Expand Up @@ -395,14 +395,6 @@ nx::core::BoundingBox3Df SIMPLNX_EXPORT FindBoundingBoxOfVertices(nx::core::INod
*/
nx::core::BoundingBox3Df SIMPLNX_EXPORT FindBoundingBoxOfRotatedFace(nx::core::TriangleGeom& faces, int32 faceId, float32 g[3][3]);

/**
* @brief Returns the BoundingBox around the specified face.
* @param faces
* @param faceId
* @return nx::core::BoundingBox<float32>
*/
nx::core::BoundingBox3Df FindBoundingBoxOfFace(const nx::core::TriangleGeom& faces, int32 faceId);

/**
* @brief Returns the BoundingBox around the specified face.
* @param faces
Expand Down

0 comments on commit 06ac6f2

Please sign in to comment.