Skip to content

Commit

Permalink
Issue: #26 Tolerance bug with rays
Browse files Browse the repository at this point in the history
  • Loading branch information
attcs committed Apr 18, 2024
1 parent 9ba4422 commit 4c3d89b
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 24 deletions.
17 changes: 9 additions & 8 deletions adaptor.eigen.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,14 @@ namespace OrthoTree
continue;
}

minDistances[dimensionID] = ((hComp > 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) - tolerance -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
maxDistances[dimensionID] = ((hComp < 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) + tolerance -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
minDistances[dimensionID] =
((hComp > 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
maxDistances[dimensionID] =
((hComp < 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
}

auto const rMin = *std::ranges::max_element(minDistances);
Expand Down Expand Up @@ -210,8 +212,7 @@ namespace OrthoTree
}

// Get box-Hyperplane relation (Plane equation: dotProduct(planeNormal, point) = distanceOfOrigo)
static constexpr PlaneRelation GetBoxPlaneRelation(
AlignedBox_ const& box, Scalar_ distanceOfOrigo, VectorType_ const& planeNormal, Scalar_ tolerance) noexcept
static constexpr PlaneRelation GetBoxPlaneRelation(AlignedBox_ const& box, Scalar_ distanceOfOrigo, VectorType_ const& planeNormal, Scalar_ tolerance) noexcept
{
assert(IsNormalizedVector(planeNormal));

Expand Down
38 changes: 24 additions & 14 deletions adaptor.unreal.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace UnrealDummyTypes
};

template<typename geometry_type>
struct FVectorTemplate2 : FVectorTemplate < FVectorTemplate2<geometry_type>>
struct FVectorTemplate2 : FVectorTemplate<FVectorTemplate2<geometry_type>>
{
geometry_type X;
geometry_type Y;
Expand All @@ -126,7 +126,8 @@ namespace UnrealDummyTypes
FVectorTemplate2(geometry_type X, geometry_type Y)
: X(X)
, Y(Y)
{}
{
}
};

template<typename geometry_type>
Expand All @@ -141,7 +142,8 @@ namespace UnrealDummyTypes
: X(X)
, Y(Y)
, Z(Z)
{}
{
}
};

template<typename FVector_>
Expand All @@ -152,15 +154,17 @@ namespace UnrealDummyTypes
bool IsValid;

FBoxTemplate() = default;
FBoxTemplate(FVector_ && Min, FVector_ && Max)
FBoxTemplate(FVector_&& Min, FVector_&& Max)
: Min(Min)
, Max(Max)
{}
{
}

FBoxTemplate(FVector_ const& Min, FVector_ const& Max)
: Min(Min)
, Max(Max)
{}
{
}

FVector_ GetCenter() const
{
Expand Down Expand Up @@ -316,7 +320,10 @@ namespace OrthoTree
static constexpr FVector2D_ const& GetRayOrigin(FRay2D_ const& ray) noexcept { return ray.Origin; }

static constexpr FVector2D_ const& GetPlaneNormal(FPlane2D_ const& plane) noexcept { return plane.Direction; }
static constexpr FGeometry_ GetPlaneOrigoDistance(FPlane2D_ const& plane) noexcept { return FVector2D_::DotProduct(plane.Origin, plane.Direction); }
static constexpr FGeometry_ GetPlaneOrigoDistance(FPlane2D_ const& plane) noexcept
{
return FVector2D_::DotProduct(plane.Origin, plane.Direction);
}
};


Expand Down Expand Up @@ -516,12 +523,14 @@ namespace OrthoTree
continue;
}

minDistances[dimensionID] = ((hComp > 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) - tolerance -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
maxDistances[dimensionID] = ((hComp < 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) + tolerance -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
minDistances[dimensionID] =
((hComp > 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
maxDistances[dimensionID] =
((hComp < 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
}

auto const rMin = *std::ranges::max_element(minDistances);
Expand Down Expand Up @@ -614,7 +623,8 @@ namespace OrthoTree
UnrealAdaptorGeneral2D<FGeometry_, FVector_, FBox_>>;

template<typename FGeometry_, typename FVector_, typename FBox_, typename FRay_, typename FPlane_>
using OctreePointTemplate = OrthoTreePoint<3, FVector_, FBox_, FRay_, FPlane_, FGeometry_, UnrealAdaptorGeneral3D<FGeometry_, FVector_, FBox_, FRay_, FPlane_>>;
using OctreePointTemplate =
OrthoTreePoint<3, FVector_, FBox_, FRay_, FPlane_, FGeometry_, UnrealAdaptorGeneral3D<FGeometry_, FVector_, FBox_, FRay_, FPlane_>>;


// Templates for box types
Expand Down
4 changes: 2 additions & 2 deletions octree.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,10 @@ namespace OrthoTree
continue;
}

minDistances[dimensionID] = ((hComp > 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) - tolerance -
minDistances[dimensionID] = ((hComp > 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
maxDistances[dimensionID] = ((hComp < 0.0 ? Base::GetBoxMinC(box, dimensionID) : Base::GetBoxMaxC(box, dimensionID)) + tolerance -
maxDistances[dimensionID] = ((hComp < 0.0 ? (Base::GetBoxMinC(box, dimensionID) - tolerance) : (Base::GetBoxMaxC(box, dimensionID) + tolerance)) -
Base::GetPointC(rayBasePoint, dimensionID)) /
hComp;
}
Expand Down
97 changes: 97 additions & 0 deletions unittests/general.tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2787,6 +2787,7 @@ namespace LongIntAdaptor
}
}


TEST_METHOD(PickSearch_Issue8)
{
autoce nDim = 3;
Expand Down Expand Up @@ -3020,6 +3021,102 @@ namespace LongIntAdaptor
Assert::IsTrue(std::ranges::is_permutation(vidActual, vidExpected));
}

template<int nDim, typename TGeometry>
vector<BoundingBoxND<nDim, TGeometry>> readBoxCloud(std::filesystem::path const& path)
{
auto boxes = vector<BoundingBoxND<nDim, TGeometry>>{};
auto file = std::ifstream(path, std::ios::in);
if (file.fail())
return boxes;

auto line = std::string{};
while (std::getline(file, line))
{
if (file.fail())
return boxes;

// LOG__DEBUG min: { -446.75, 60.0322, -182.431 }, max: { -442.374, 60.0322, -180.318 }
auto& box = boxes.emplace_back();
auto sw = std::string_view(line).substr(22);
for (int iDim = 0; iDim < nDim; ++iDim)
{
autoc[ptr, ec] = std::from_chars(sw.data(), sw.data() + sw.length(), box.Min[iDim]);
if (ec != std::errc{})
return boxes;

sw.remove_prefix(ptr - sw.data());
if (!sw.empty())
sw.remove_prefix(2); // space
}

sw.remove_prefix(9);
for (int iDim = 0; iDim < nDim; ++iDim)
{
autoc[ptr, ec] = std::from_chars(sw.data(), sw.data() + sw.length(), box.Max[iDim]);
if (ec != std::errc{})
return boxes;

sw.remove_prefix(ptr - sw.data());
if (!sw.empty())
sw.remove_prefix(2); // space
}
}

return boxes;
}


TEST_METHOD(Issue26)
{
const auto boxes = readBoxCloud<3, float>("../../../bbox_output.txt");
if (boxes.empty())
return;

using Tree = TreeBoxContainerND<3, 2, float>;

autoc tree = Tree(boxes, 4, std::nullopt, 21, false);

srand(0);
const auto boxOfTree = tree.GetCore().GetBox();
const float rayIntersectTolerance = 0.1f;
for (int iTry = 0; iTry < 100; ++iTry)
{
constexpr int mod = 1000;
constexpr auto modr = 0.0011f; // it ensures a little bit bigger space, to make possible out of tree test

const float searchSizeY = float(rand() % mod) * modr * (boxOfTree.Max[1] - boxOfTree.Min[1]);
const auto x = float(rand() % mod) * modr * (boxOfTree.Max[0] - boxOfTree.Min[0]);
const auto y = float(rand() % mod) * modr * (boxOfTree.Max[1] - boxOfTree.Min[1]);
const auto z = float(rand() % mod) * modr * (boxOfTree.Max[2] - boxOfTree.Min[2]);
const auto pos = Tree::TVector{ x, y, z };
const auto searchBox = Tree::TBox{
{pos[0] - rayIntersectTolerance, pos[1] - searchSizeY, pos[2] - rayIntersectTolerance},
{pos[0] + rayIntersectTolerance, pos[1], pos[2] + rayIntersectTolerance}
};


auto resultOfBruteForce = vector<std::size_t>{};
autoc boxNo = boxes.size();
for (std::size_t id = 0; id < boxNo; ++id)
{
if (Tree::AD::AreBoxesOverlapped(searchBox, boxes[id], false, false))
resultOfBruteForce.emplace_back(id);
}

auto resultOfSearchBox = tree.RangeSearch<false>(searchBox);
std::ranges::sort(resultOfSearchBox);

std::vector<OctreeBox::MortonNodeID> nodeIDs;
for (auto entityID : resultOfBruteForce)
nodeIDs.emplace_back(tree.GetCore().GetNodeIDByEntity(entityID));

auto resultOfRay = tree.RayIntersectedAll(pos, { 0.0, -1.0, 0.0 }, rayIntersectTolerance, searchSizeY);
std::ranges::sort(resultOfRay);

Assert::IsTrue(resultOfBruteForce == resultOfSearchBox);
Assert::IsTrue(resultOfBruteForce == resultOfRay);
}
}

};
}
Expand Down

0 comments on commit 4c3d89b

Please sign in to comment.